aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/README77
-rw-r--r--Documentation/ABI/obsolete/devfs13
-rw-r--r--Documentation/ABI/stable/syscalls10
-rw-r--r--Documentation/ABI/stable/sysfs-module30
-rw-r--r--Documentation/ABI/testing/sysfs-class16
-rw-r--r--Documentation/ABI/testing/sysfs-devices25
-rw-r--r--Documentation/isdn/README.gigaset7
-rw-r--r--Documentation/keys.txt39
-rw-r--r--Documentation/power/devices.txt90
-rw-r--r--Documentation/power/swsusp.txt37
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt19
-rw-r--r--Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl50
-rw-r--r--Documentation/usb/usbmon.txt32
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/powerpc/boot/Makefile4
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c66
-rw-r--r--arch/ppc/boot/lib/Makefile2
-rw-r--r--arch/ppc/syslib/mpc83xx_devices.c6
-rw-r--r--arch/sparc/kernel/setup.c2
-rw-r--r--arch/um/kernel/time_kern.c2
-rw-r--r--arch/x86_64/Kconfig5
-rw-r--r--arch/xtensa/boot/lib/Makefile2
-rw-r--r--block/genhd.c7
-rw-r--r--drivers/base/Kconfig4
-rw-r--r--drivers/base/Makefile2
-rw-r--r--drivers/base/attribute_container.c8
-rw-r--r--drivers/base/base.h9
-rw-r--r--drivers/base/bus.c28
-rw-r--r--drivers/base/class.c112
-rw-r--r--drivers/base/core.c197
-rw-r--r--drivers/base/firmware_class.c22
-rw-r--r--drivers/base/hypervisor.c19
-rw-r--r--drivers/base/init.c1
-rw-r--r--drivers/base/isa.c180
-rw-r--r--drivers/base/platform.c35
-rw-r--r--drivers/base/power/Makefile3
-rw-r--r--drivers/base/power/suspend.c17
-rw-r--r--drivers/base/sys.c51
-rw-r--r--drivers/block/cciss.c1
-rw-r--r--drivers/block/ub.c78
-rw-r--r--drivers/char/agp/Kconfig3
-rw-r--r--drivers/char/tty_io.c11
-rw-r--r--drivers/isdn/gigaset/common.c13
-rw-r--r--drivers/isdn/gigaset/gigaset.h1
-rw-r--r--drivers/isdn/gigaset/interface.c10
-rw-r--r--drivers/isdn/gigaset/proc.c21
-rw-r--r--drivers/media/video/usbvideo/konicawc.c3
-rw-r--r--drivers/net/myri10ge/myri10ge.c2
-rw-r--r--drivers/usb/Makefile2
-rw-r--r--drivers/usb/atm/usbatm.c2
-rw-r--r--drivers/usb/atm/xusbatm.c1
-rw-r--r--drivers/usb/class/cdc-acm.c84
-rw-r--r--drivers/usb/class/cdc-acm.h16
-rw-r--r--drivers/usb/core/Makefile3
-rw-r--r--drivers/usb/core/devio.c38
-rw-r--r--drivers/usb/core/endpoint.c275
-rw-r--r--drivers/usb/core/file.c79
-rw-r--r--drivers/usb/core/hub.c153
-rw-r--r--drivers/usb/core/message.c182
-rw-r--r--drivers/usb/core/sysfs.c201
-rw-r--r--drivers/usb/core/usb.c1
-rw-r--r--drivers/usb/core/usb.h3
-rw-r--r--drivers/usb/gadget/ether.c90
-rw-r--r--drivers/usb/gadget/inode.c62
-rw-r--r--drivers/usb/gadget/net2280.c17
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c13
-rw-r--r--drivers/usb/gadget/rndis.c389
-rw-r--r--drivers/usb/gadget/rndis.h26
-rw-r--r--drivers/usb/gadget/serial.c105
-rw-r--r--drivers/usb/host/Kconfig20
-rw-r--r--drivers/usb/host/ehci-au1xxx.c21
-rw-r--r--drivers/usb/host/ehci-fsl.c37
-rw-r--r--drivers/usb/host/ehci-hcd.c50
-rw-r--r--drivers/usb/host/ehci-pci.c59
-rw-r--r--drivers/usb/host/ehci-sched.c216
-rw-r--r--drivers/usb/host/isp116x-hcd.c4
-rw-r--r--drivers/usb/host/sl811-hcd.c2
-rw-r--r--drivers/usb/host/sl811_cs.c2
-rw-r--r--drivers/usb/host/uhci-debug.c45
-rw-r--r--drivers/usb/host/uhci-hcd.c139
-rw-r--r--drivers/usb/host/uhci-hcd.h81
-rw-r--r--drivers/usb/host/uhci-hub.c5
-rw-r--r--drivers/usb/host/uhci-q.c947
-rw-r--r--drivers/usb/input/acecad.c4
-rw-r--r--drivers/usb/input/aiptek.c4
-rw-r--r--drivers/usb/input/appletouch.c117
-rw-r--r--drivers/usb/input/ati_remote.c4
-rw-r--r--drivers/usb/input/ati_remote2.c2
-rw-r--r--drivers/usb/input/hid-core.c83
-rw-r--r--drivers/usb/input/hid-input.c36
-rw-r--r--drivers/usb/input/hid.h11
-rw-r--r--drivers/usb/input/itmtouch.c4
-rw-r--r--drivers/usb/input/kbtab.c5
-rw-r--r--drivers/usb/input/keyspan_remote.c4
-rw-r--r--drivers/usb/input/mtouchusb.c4
-rw-r--r--drivers/usb/input/powermate.c4
-rw-r--r--drivers/usb/input/touchkitusb.c4
-rw-r--r--drivers/usb/input/usbkbd.c4
-rw-r--r--drivers/usb/input/usbmouse.c4
-rw-r--r--drivers/usb/input/usbtouchscreen.c2
-rw-r--r--drivers/usb/input/wacom.c5
-rw-r--r--drivers/usb/input/xpad.c4
-rw-r--r--drivers/usb/input/yealink.c4
-rw-r--r--drivers/usb/misc/Kconfig23
-rw-r--r--drivers/usb/misc/Makefile2
-rw-r--r--drivers/usb/misc/appledisplay.c383
-rw-r--r--drivers/usb/misc/cy7c63.c244
-rw-r--r--drivers/usb/misc/phidgetkit.c303
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c127
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.h6
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c151
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_init.c4
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_init.h20
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_struct.h2
-rw-r--r--drivers/usb/misc/usbtest.c38
-rw-r--r--drivers/usb/mon/mon_dma.c5
-rw-r--r--drivers/usb/mon/mon_main.c23
-rw-r--r--drivers/usb/mon/mon_stat.c4
-rw-r--r--drivers/usb/mon/mon_text.c36
-rw-r--r--drivers/usb/mon/usb_mon.h2
-rw-r--r--drivers/usb/net/asix.c4
-rw-r--r--drivers/usb/net/cdc_ether.c14
-rw-r--r--drivers/usb/net/pegasus.c29
-rw-r--r--drivers/usb/net/rndis_host.c2
-rw-r--r--drivers/usb/net/zaurus.c19
-rw-r--r--drivers/usb/serial/Kconfig18
-rw-r--r--drivers/usb/serial/airprime.c2
-rw-r--r--drivers/usb/serial/console.c56
-rw-r--r--drivers/usb/serial/cp2101.c1
-rw-r--r--drivers/usb/serial/cyberjack.c2
-rw-r--r--drivers/usb/serial/cypress_m8.c2
-rw-r--r--drivers/usb/serial/empeg.c2
-rw-r--r--drivers/usb/serial/ftdi_sio.c13
-rw-r--r--drivers/usb/serial/ftdi_sio.h6
-rw-r--r--drivers/usb/serial/garmin_gps.c2
-rw-r--r--drivers/usb/serial/generic.c4
-rw-r--r--drivers/usb/serial/io_edgeport.c48
-rw-r--r--drivers/usb/serial/ipaq.c2
-rw-r--r--drivers/usb/serial/ipw.c2
-rw-r--r--drivers/usb/serial/ir-usb.c2
-rw-r--r--drivers/usb/serial/keyspan.c2
-rw-r--r--drivers/usb/serial/kl5kusb105.c3
-rw-r--r--drivers/usb/serial/omninet.c2
-rw-r--r--drivers/usb/serial/option.c139
-rw-r--r--drivers/usb/serial/pl2303.c4
-rw-r--r--drivers/usb/serial/usb-serial.c58
-rw-r--r--drivers/usb/serial/usb-serial.h5
-rw-r--r--drivers/usb/serial/visor.c2
-rw-r--r--drivers/usb/serial/whiteheat.c8
-rw-r--r--drivers/usb/storage/onetouch.c3
-rw-r--r--drivers/usb/storage/scsiglue.c4
-rw-r--r--drivers/usb/storage/shuttle_usbat.c105
-rw-r--r--drivers/usb/storage/shuttle_usbat.h4
-rw-r--r--drivers/usb/storage/transport.c88
-rw-r--r--drivers/usb/storage/unusual_devs.h35
-rw-r--r--drivers/usb/storage/usb.c51
-rw-r--r--drivers/video/console/mdacon.c2
-rw-r--r--drivers/video/console/vgacon.c19
-rw-r--r--drivers/video/vga16fb.c2
-rw-r--r--fs/binfmt_elf.c1
-rw-r--r--fs/binfmt_misc.c1
-rw-r--r--fs/block_dev.c32
-rw-r--r--fs/dcache.c75
-rw-r--r--fs/exec.c1
-rw-r--r--fs/locks.c57
-rw-r--r--fs/ntfs/file.c13
-rw-r--r--fs/partitions/check.c4
-rw-r--r--fs/super.c2
-rw-r--r--fs/xfs/Kconfig27
-rw-r--r--fs/xfs/Makefile-linux-2.64
-rw-r--r--fs/xfs/linux-2.6/kmem.h38
-rw-r--r--fs/xfs/linux-2.6/mrlock.h4
-rw-r--r--fs/xfs/linux-2.6/sema.h19
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c65
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h8
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c13
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c170
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.c59
-rw-r--r--fs/xfs/linux-2.6/xfs_globals.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c65
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c117
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h35
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c123
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h6
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c189
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_sysctl.c5
-rw-r--r--fs/xfs/linux-2.6/xfs_sysctl.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.c41
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.h167
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c52
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h376
-rw-r--r--fs/xfs/quota/xfs_dquot.c8
-rw-r--r--fs/xfs/quota/xfs_dquot.h4
-rw-r--r--fs/xfs/quota/xfs_dquot_item.c6
-rw-r--r--fs/xfs/quota/xfs_qm.c8
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c81
-rw-r--r--fs/xfs/quota/xfs_qm_stats.c2
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c6
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c2
-rw-r--r--fs/xfs/support/debug.c4
-rw-r--r--fs/xfs/support/debug.h3
-rw-r--r--fs/xfs/xfs_acl.c71
-rw-r--r--fs/xfs/xfs_acl.h16
-rw-r--r--fs/xfs/xfs_alloc.c31
-rw-r--r--fs/xfs/xfs_alloc.h2
-rw-r--r--fs/xfs/xfs_alloc_btree.c2
-rw-r--r--fs/xfs/xfs_attr.c66
-rw-r--r--fs/xfs/xfs_attr.h14
-rw-r--r--fs/xfs/xfs_attr_leaf.c4
-rw-r--r--fs/xfs/xfs_bmap.c386
-rw-r--r--fs/xfs/xfs_bmap.h22
-rw-r--r--fs/xfs/xfs_bmap_btree.c12
-rw-r--r--fs/xfs/xfs_btree.c2
-rw-r--r--fs/xfs/xfs_buf_item.c9
-rw-r--r--fs/xfs/xfs_cap.h10
-rw-r--r--fs/xfs/xfs_da_btree.c194
-rw-r--r--fs/xfs/xfs_da_btree.h4
-rw-r--r--fs/xfs/xfs_dfrag.c84
-rw-r--r--fs/xfs/xfs_dfrag.h3
-rw-r--r--fs/xfs/xfs_dinode.h5
-rw-r--r--fs/xfs/xfs_dir.c1217
-rw-r--r--fs/xfs/xfs_dir.h142
-rw-r--r--fs/xfs/xfs_dir2.c396
-rw-r--r--fs/xfs/xfs_dir2.h32
-rw-r--r--fs/xfs/xfs_dir2_block.c31
-rw-r--r--fs/xfs/xfs_dir2_data.c5
-rw-r--r--fs/xfs/xfs_dir2_data.h8
-rw-r--r--fs/xfs/xfs_dir2_leaf.c14
-rw-r--r--fs/xfs/xfs_dir2_node.c16
-rw-r--r--fs/xfs/xfs_dir2_sf.c13
-rw-r--r--fs/xfs/xfs_dir2_trace.c2
-rw-r--r--fs/xfs/xfs_dir_leaf.c2213
-rw-r--r--fs/xfs/xfs_dir_leaf.h231
-rw-r--r--fs/xfs/xfs_dir_sf.h155
-rw-r--r--fs/xfs/xfs_dmapi.h2
-rw-r--r--fs/xfs/xfs_dmops.c1
-rw-r--r--fs/xfs/xfs_error.c2
-rw-r--r--fs/xfs/xfs_extfree_item.c57
-rw-r--r--fs/xfs/xfs_extfree_item.h53
-rw-r--r--fs/xfs/xfs_fs.h7
-rw-r--r--fs/xfs/xfs_fsops.c20
-rw-r--r--fs/xfs/xfs_ialloc.c5
-rw-r--r--fs/xfs/xfs_ialloc_btree.c2
-rw-r--r--fs/xfs/xfs_iget.c22
-rw-r--r--fs/xfs/xfs_inode.c94
-rw-r--r--fs/xfs/xfs_inode.h7
-rw-r--r--fs/xfs/xfs_inode_item.c57
-rw-r--r--fs/xfs/xfs_inode_item.h61
-rw-r--r--fs/xfs/xfs_iocore.c7
-rw-r--r--fs/xfs/xfs_iomap.c26
-rw-r--r--fs/xfs/xfs_itable.c20
-rw-r--r--fs/xfs/xfs_itable.h1
-rw-r--r--fs/xfs/xfs_log.c21
-rw-r--r--fs/xfs/xfs_log_recover.c113
-rw-r--r--fs/xfs/xfs_mount.c54
-rw-r--r--fs/xfs/xfs_mount.h70
-rw-r--r--fs/xfs/xfs_qmops.c1
-rw-r--r--fs/xfs/xfs_quota.h2
-rw-r--r--fs/xfs/xfs_rename.c68
-rw-r--r--fs/xfs/xfs_rtalloc.c16
-rw-r--r--fs/xfs/xfs_rw.c124
-rw-r--r--fs/xfs/xfs_rw.h10
-rw-r--r--fs/xfs/xfs_trans.c48
-rw-r--r--fs/xfs/xfs_trans.h7
-rw-r--r--fs/xfs/xfs_trans_ail.c6
-rw-r--r--fs/xfs/xfs_trans_buf.c12
-rw-r--r--fs/xfs/xfs_trans_extfree.c1
-rw-r--r--fs/xfs/xfs_trans_inode.c2
-rw-r--r--fs/xfs/xfs_trans_item.c2
-rw-r--r--fs/xfs/xfs_trans_space.h11
-rw-r--r--fs/xfs/xfs_utils.c13
-rw-r--r--fs/xfs/xfs_utils.h7
-rw-r--r--fs/xfs/xfs_vfsops.c122
-rw-r--r--fs/xfs/xfs_vnodeops.c295
-rw-r--r--include/asm-alpha/vga.h2
-rw-r--r--include/asm-arm/vga.h2
-rw-r--r--include/asm-i386/vga.h2
-rw-r--r--include/asm-ia64/vga.h2
-rw-r--r--include/asm-m32r/vga.h2
-rw-r--r--include/asm-mips/vga.h2
-rw-r--r--include/asm-powerpc/vga.h4
-rw-r--r--include/asm-sparc64/vga.h2
-rw-r--r--include/asm-x86_64/vga.h2
-rw-r--r--include/asm-xtensa/vga.h2
-rw-r--r--include/linux/dcache.h2
-rw-r--r--include/linux/device.h25
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/isa.h28
-rw-r--r--include/linux/key.h23
-rw-r--r--include/linux/kobject.h2
-rw-r--r--include/linux/security.h10
-rw-r--r--include/linux/sysdev.h18
-rw-r--r--include/linux/tty.h4
-rw-r--r--include/linux/usb.h22
-rw-r--r--include/linux/usb/cdc.h (renamed from include/linux/usb_cdc.h)0
-rw-r--r--include/linux/usb/input.h (renamed from include/linux/usb_input.h)0
-rw-r--r--include/linux/usb/isp116x.h (renamed from include/linux/usb_isp116x.h)0
-rw-r--r--include/linux/usb/sl811.h (renamed from include/linux/usb_sl811.h)8
-rw-r--r--include/linux/zconf.h12
-rw-r--r--include/linux/zlib.h209
-rw-r--r--include/linux/zutil.h12
-rw-r--r--include/sound/ac97_codec.h1
-rw-r--r--include/sound/asequencer.h4
-rw-r--r--include/sound/asound.h2
-rw-r--r--include/sound/core.h3
-rw-r--r--include/sound/emu10k1.h2
-rw-r--r--include/sound/info.h11
-rw-r--r--include/sound/mpu401.h14
-rw-r--r--include/sound/pcm.h19
-rw-r--r--include/sound/pcm_params.h125
-rw-r--r--include/sound/rawmidi.h3
-rw-r--r--include/sound/version.h4
-rw-r--r--kernel/power/main.c2
-rw-r--r--kernel/sys.c56
-rw-r--r--kernel/user.c2
-rw-r--r--lib/kobject.c6
-rw-r--r--lib/zlib_deflate/deflate.c25
-rw-r--r--lib/zlib_deflate/deflate_syms.c3
-rw-r--r--lib/zlib_inflate/Makefile4
-rw-r--r--lib/zlib_inflate/infblock.c365
-rw-r--r--lib/zlib_inflate/infblock.h48
-rw-r--r--lib/zlib_inflate/infcodes.c202
-rw-r--r--lib/zlib_inflate/infcodes.h33
-rw-r--r--lib/zlib_inflate/inffast.c462
-rw-r--r--lib/zlib_inflate/inffast.h12
-rw-r--r--lib/zlib_inflate/inffixed.h94
-rw-r--r--lib/zlib_inflate/inflate.c1086
-rw-r--r--lib/zlib_inflate/inflate.h107
-rw-r--r--lib/zlib_inflate/inflate_syms.c3
-rw-r--r--lib/zlib_inflate/inflate_sync.c152
-rw-r--r--lib/zlib_inflate/inftrees.c683
-rw-r--r--lib/zlib_inflate/inftrees.h99
-rw-r--r--lib/zlib_inflate/infutil.c88
-rw-r--r--lib/zlib_inflate/infutil.h176
-rw-r--r--security/dummy.c2
-rw-r--r--security/keys/key.c12
-rw-r--r--security/keys/keyring.c5
-rw-r--r--security/keys/process_keys.c57
-rw-r--r--security/keys/request_key.c6
-rw-r--r--security/keys/request_key_auth.c47
-rw-r--r--security/selinux/hooks.c64
-rw-r--r--security/selinux/include/av_perm_to_string.h6
-rw-r--r--security/selinux/include/av_permissions.h8
-rw-r--r--security/selinux/include/class_to_string.h1
-rw-r--r--security/selinux/include/flask.h1
-rw-r--r--security/selinux/include/objsec.h5
-rw-r--r--sound/Kconfig2
-rw-r--r--sound/Makefile2
-rw-r--r--sound/aoa/Kconfig17
-rw-r--r--sound/aoa/Makefile4
-rw-r--r--sound/aoa/aoa-gpio.h81
-rw-r--r--sound/aoa/aoa.h131
-rw-r--r--sound/aoa/codecs/Kconfig32
-rw-r--r--sound/aoa/codecs/Makefile3
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-onyx.c1113
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-onyx.h76
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h209
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-tas.c654
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-tas.h47
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-toonie.c141
-rw-r--r--sound/aoa/core/Makefile5
-rw-r--r--sound/aoa/core/snd-aoa-alsa.c98
-rw-r--r--sound/aoa/core/snd-aoa-alsa.h16
-rw-r--r--sound/aoa/core/snd-aoa-core.c162
-rw-r--r--sound/aoa/core/snd-aoa-gpio-feature.c399
-rw-r--r--sound/aoa/core/snd-aoa-gpio-pmf.c246
-rw-r--r--sound/aoa/fabrics/Kconfig12
-rw-r--r--sound/aoa/fabrics/Makefile1
-rw-r--r--sound/aoa/fabrics/snd-aoa-fabric-layout.c1109
-rw-r--r--sound/aoa/soundbus/Kconfig14
-rw-r--r--sound/aoa/soundbus/Makefile3
-rw-r--r--sound/aoa/soundbus/core.c250
-rw-r--r--sound/aoa/soundbus/i2sbus/Makefile2
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus-control.c192
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus-control.h37
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus-core.c387
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus-interface.h187
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus-pcm.c1021
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus.h112
-rw-r--r--sound/aoa/soundbus/soundbus.h202
-rw-r--r--sound/aoa/soundbus/sysfs.c43
-rw-r--r--sound/arm/sa11xx-uda1341.c16
-rw-r--r--sound/core/control.c31
-rw-r--r--sound/core/device.c6
-rw-r--r--sound/core/hwdep.c1
-rw-r--r--sound/core/info.c178
-rw-r--r--sound/core/info_oss.c3
-rw-r--r--sound/core/init.c78
-rw-r--r--sound/core/isadma.c6
-rw-r--r--sound/core/memory.c5
-rw-r--r--sound/core/misc.c6
-rw-r--r--sound/core/oss/mixer_oss.c2
-rw-r--r--sound/core/oss/pcm_oss.c529
-rw-r--r--sound/core/pcm.c90
-rw-r--r--sound/core/pcm_compat.c4
-rw-r--r--sound/core/pcm_lib.c725
-rw-r--r--sound/core/pcm_memory.c14
-rw-r--r--sound/core/pcm_misc.c24
-rw-r--r--sound/core/pcm_native.c113
-rw-r--r--sound/core/rawmidi.c3
-rw-r--r--sound/core/seq/oss/seq_oss.c1
-rw-r--r--sound/core/seq/seq.c22
-rw-r--r--sound/core/seq/seq_clientmgr.c12
-rw-r--r--sound/core/seq/seq_device.c3
-rw-r--r--sound/core/seq/seq_dummy.c6
-rw-r--r--sound/core/seq/seq_info.c11
-rw-r--r--sound/core/seq/seq_lock.c2
-rw-r--r--sound/core/seq/seq_memory.c3
-rw-r--r--sound/core/seq/seq_midi.c11
-rw-r--r--sound/core/seq/seq_ports.c5
-rw-r--r--sound/core/seq/seq_virmidi.c4
-rw-r--r--sound/core/sound.c109
-rw-r--r--sound/core/sound_oss.c9
-rw-r--r--sound/core/timer.c6
-rw-r--r--sound/drivers/dummy.c4
-rw-r--r--sound/drivers/mpu401/mpu401.c4
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c186
-rw-r--r--sound/drivers/mtpav.c14
-rw-r--r--sound/drivers/opl3/opl3_lib.c19
-rw-r--r--sound/drivers/opl3/opl3_oss.c3
-rw-r--r--sound/drivers/opl3/opl3_seq.c4
-rw-r--r--sound/drivers/opl3/opl3_synth.c4
-rw-r--r--sound/drivers/opl4/opl4_lib.c12
-rw-r--r--sound/drivers/opl4/opl4_seq.c4
-rw-r--r--sound/drivers/serial-u16550.c4
-rw-r--r--sound/drivers/virmidi.c4
-rw-r--r--sound/drivers/vx/vx_core.c32
-rw-r--r--sound/drivers/vx/vx_hwdep.c3
-rw-r--r--sound/i2c/i2c.c17
-rw-r--r--sound/i2c/l3/uda1341.c4
-rw-r--r--sound/isa/gus/gus_irq.c2
-rw-r--r--sound/isa/gus/gus_mem.c6
-rw-r--r--sound/isa/gus/gus_synth.c4
-rw-r--r--sound/isa/gus/interwave.c4
-rw-r--r--sound/isa/opl3sa2.c12
-rw-r--r--sound/isa/opti9xx/miro.c2
-rw-r--r--sound/isa/sb/emu8000.c22
-rw-r--r--sound/isa/sb/emu8000_patch.c2
-rw-r--r--sound/isa/sb/sb16.c2
-rw-r--r--sound/isa/sb/sb16_csp.c2
-rw-r--r--sound/isa/sb/sb8_midi.c20
-rw-r--r--sound/isa/sscape.c3
-rw-r--r--sound/isa/wavefront/wavefront.c2
-rw-r--r--sound/pci/Kconfig9
-rw-r--r--sound/pci/ac97/ac97_codec.c61
-rw-r--r--sound/pci/ac97/ac97_patch.c19
-rw-r--r--sound/pci/ac97/ac97_pcm.c10
-rw-r--r--sound/pci/ac97/ac97_proc.c5
-rw-r--r--sound/pci/ac97/ak4531_codec.c2
-rw-r--r--sound/pci/ad1889.c2
-rw-r--r--sound/pci/ali5451/ali5451.c4
-rw-r--r--sound/pci/als4000.c4
-rw-r--r--sound/pci/atiixp.c2
-rw-r--r--sound/pci/atiixp_modem.c2
-rw-r--r--sound/pci/au88x0/au88x0.c12
-rw-r--r--sound/pci/au88x0/au88x0_mpu401.c11
-rw-r--r--sound/pci/au88x0/au88x0_xtalk.c29
-rw-r--r--sound/pci/azt3328.c234
-rw-r--r--sound/pci/azt3328.h36
-rw-r--r--sound/pci/bt87x.c8
-rw-r--r--sound/pci/ca0106/ca0106.h4
-rw-r--r--sound/pci/ca0106/ca0106_main.c57
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c181
-rw-r--r--sound/pci/ca0106/ca0106_proc.c17
-rw-r--r--sound/pci/cmipci.c10
-rw-r--r--sound/pci/cs4281.c16
-rw-r--r--sound/pci/cs46xx/cs46xx.c4
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c5
-rw-r--r--sound/pci/cs46xx/dsp_spos.c7
-rw-r--r--sound/pci/cs46xx/dsp_spos_scb_lib.c1
-rw-r--r--sound/pci/cs5535audio/Makefile4
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c41
-rw-r--r--sound/pci/cs5535audio/cs5535audio.h8
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c24
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pm.c123
-rw-r--r--sound/pci/emu10k1/emu10k1.c8
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c69
-rw-r--r--sound/pci/emu10k1/emu10k1x.c3
-rw-r--r--sound/pci/emu10k1/emumixer.c54
-rw-r--r--sound/pci/emu10k1/emuproc.c27
-rw-r--r--sound/pci/emu10k1/io.c4
-rw-r--r--sound/pci/emu10k1/memory.c8
-rw-r--r--sound/pci/emu10k1/p17v.h111
-rw-r--r--sound/pci/emu10k1/tina2.h8
-rw-r--r--sound/pci/emu10k1/voice.c4
-rw-r--r--sound/pci/ens1370.c2
-rw-r--r--sound/pci/es1938.c3
-rw-r--r--sound/pci/es1968.c5
-rw-r--r--sound/pci/fm801.c5
-rw-r--r--sound/pci/hda/Makefile2
-rw-r--r--sound/pci/hda/hda_codec.c41
-rw-r--r--sound/pci/hda/hda_intel.c20
-rw-r--r--sound/pci/hda/hda_patch.h3
-rw-r--r--sound/pci/hda/hda_proc.c6
-rw-r--r--sound/pci/hda/patch_analog.c61
-rw-r--r--sound/pci/hda/patch_atihdmi.c165
-rw-r--r--sound/pci/hda/patch_realtek.c30
-rw-r--r--sound/pci/hda/patch_sigmatel.c82
-rw-r--r--sound/pci/ice1712/aureon.c26
-rw-r--r--sound/pci/ice1712/aureon.h1
-rw-r--r--sound/pci/ice1712/ews.c3
-rw-r--r--sound/pci/ice1712/ice1712.c43
-rw-r--r--sound/pci/ice1712/ice1712.h5
-rw-r--r--sound/pci/ice1712/ice1724.c5
-rw-r--r--sound/pci/ice1712/pontis.c8
-rw-r--r--sound/pci/intel8x0.c10
-rw-r--r--sound/pci/intel8x0m.c4
-rw-r--r--sound/pci/korg1212/korg1212.c2
-rw-r--r--sound/pci/maestro3.c3
-rw-r--r--sound/pci/mixart/mixart.c1
-rw-r--r--sound/pci/pcxhr/pcxhr.c4
-rw-r--r--sound/pci/riptide/riptide.c6
-rw-r--r--sound/pci/rme32.c14
-rw-r--r--sound/pci/rme96.c44
-rw-r--r--sound/pci/rme9652/hdsp.c7
-rw-r--r--sound/pci/rme9652/hdspm.c2
-rw-r--r--sound/pci/rme9652/rme9652.c4
-rw-r--r--sound/pci/sonicvibes.c8
-rw-r--r--sound/pci/trident/trident.c3
-rw-r--r--sound/pci/trident/trident_main.c22
-rw-r--r--sound/pci/trident/trident_memory.c3
-rw-r--r--sound/pci/trident/trident_synth.c4
-rw-r--r--sound/pci/via82xx.c12
-rw-r--r--sound/pci/via82xx_modem.c2
-rw-r--r--sound/pci/ymfpci/ymfpci.c3
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_core.c2
-rw-r--r--sound/pcmcia/vx/vxp_ops.c2
-rw-r--r--sound/pcmcia/vx/vxpocket.c2
-rw-r--r--sound/ppc/Makefile2
-rw-r--r--sound/ppc/pmac.c44
-rw-r--r--sound/ppc/pmac.h3
-rw-r--r--sound/ppc/powermac.c21
-rw-r--r--sound/ppc/toonie.c378
-rw-r--r--sound/sparc/dbri.c8
-rw-r--r--sound/synth/emux/emux.c12
-rw-r--r--sound/synth/emux/emux_proc.c1
-rw-r--r--sound/synth/emux/emux_seq.c3
-rw-r--r--sound/synth/emux/emux_synth.c5
-rw-r--r--sound/synth/emux/soundfont.c6
-rw-r--r--sound/usb/usbaudio.c15
-rw-r--r--sound/usb/usbaudio.h7
-rw-r--r--sound/usb/usbmidi.c202
-rw-r--r--sound/usb/usbmixer.c70
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c2
547 files changed, 19522 insertions, 13099 deletions
diff --git a/Documentation/ABI/README b/Documentation/ABI/README
new file mode 100644
index 000000000000..9feaf16f1617
--- /dev/null
+++ b/Documentation/ABI/README
@@ -0,0 +1,77 @@
1This directory attempts to document the ABI between the Linux kernel and
2userspace, and the relative stability of these interfaces. Due to the
3everchanging nature of Linux, and the differing maturity levels, these
4interfaces should be used by userspace programs in different ways.
5
6We have four different levels of ABI stability, as shown by the four
7different subdirectories in this location. Interfaces may change levels
8of stability according to the rules described below.
9
10The different levels of stability are:
11
12 stable/
13 This directory documents the interfaces that the developer has
14 defined to be stable. Userspace programs are free to use these
15 interfaces with no restrictions, and backward compatibility for
16 them will be guaranteed for at least 2 years. Most interfaces
17 (like syscalls) are expected to never change and always be
18 available.
19
20 testing/
21 This directory documents interfaces that are felt to be stable,
22 as the main development of this interface has been completed.
23 The interface can be changed to add new features, but the
24 current interface will not break by doing this, unless grave
25 errors or security problems are found in them. Userspace
26 programs can start to rely on these interfaces, but they must be
27 aware of changes that can occur before these interfaces move to
28 be marked stable. Programs that use these interfaces are
29 strongly encouraged to add their name to the description of
30 these interfaces, so that the kernel developers can easily
31 notify them if any changes occur (see the description of the
32 layout of the files below for details on how to do this.)
33
34 obsolete/
35 This directory documents interfaces that are still remaining in
36 the kernel, but are marked to be removed at some later point in
37 time. The description of the interface will document the reason
38 why it is obsolete and when it can be expected to be removed.
39 The file Documentation/feature-removal-schedule.txt may describe
40 some of these interfaces, giving a schedule for when they will
41 be removed.
42
43 removed/
44 This directory contains a list of the old interfaces that have
45 been removed from the kernel.
46
47Every file in these directories will contain the following information:
48
49What: Short description of the interface
50Date: Date created
51KernelVersion: Kernel version this feature first showed up in.
52Contact: Primary contact for this interface (may be a mailing list)
53Description: Long description of the interface and how to use it.
54Users: All users of this interface who wish to be notified when
55 it changes. This is very important for interfaces in
56 the "testing" stage, so that kernel developers can work
57 with userspace developers to ensure that things do not
58 break in ways that are unacceptable. It is also
59 important to get feedback for these interfaces to make
60 sure they are working in a proper way and do not need to
61 be changed further.
62
63
64How things move between levels:
65
66Interfaces in stable may move to obsolete, as long as the proper
67notification is given.
68
69Interfaces may be removed from obsolete and the kernel as long as the
70documented amount of time has gone by.
71
72Interfaces in the testing state can move to the stable state when the
73developers feel they are finished. They cannot be removed from the
74kernel tree without going through the obsolete state first.
75
76It's up to the developer to place their interfaces in the category they
77wish for it to start out in.
diff --git a/Documentation/ABI/obsolete/devfs b/Documentation/ABI/obsolete/devfs
new file mode 100644
index 000000000000..b8b87399bc8f
--- /dev/null
+++ b/Documentation/ABI/obsolete/devfs
@@ -0,0 +1,13 @@
1What: devfs
2Date: July 2005
3Contact: Greg Kroah-Hartman <gregkh@suse.de>
4Description:
5 devfs has been unmaintained for a number of years, has unfixable
6 races, contains a naming policy within the kernel that is
7 against the LSB, and can be replaced by using udev.
8 The files fs/devfs/*, include/linux/devfs_fs*.h will be removed,
9 along with the the assorted devfs function calls throughout the
10 kernel tree.
11
12Users:
13
diff --git a/Documentation/ABI/stable/syscalls b/Documentation/ABI/stable/syscalls
new file mode 100644
index 000000000000..c3ae3e7d6a0c
--- /dev/null
+++ b/Documentation/ABI/stable/syscalls
@@ -0,0 +1,10 @@
1What: The kernel syscall interface
2Description:
3 This interface matches much of the POSIX interface and is based
4 on it and other Unix based interfaces. It will only be added to
5 over time, and not have things removed from it.
6
7 Note that this interface is different for every architecture
8 that Linux supports. Please see the architecture-specific
9 documentation for details on the syscall numbers that are to be
10 mapped to each syscall.
diff --git a/Documentation/ABI/stable/sysfs-module b/Documentation/ABI/stable/sysfs-module
new file mode 100644
index 000000000000..75be43118335
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-module
@@ -0,0 +1,30 @@
1What: /sys/module
2Description:
3 The /sys/module tree consists of the following structure:
4
5 /sys/module/MODULENAME
6 The name of the module that is in the kernel. This
7 module name will show up either if the module is built
8 directly into the kernel, or if it is loaded as a
9 dyanmic module.
10
11 /sys/module/MODULENAME/parameters
12 This directory contains individual files that are each
13 individual parameters of the module that are able to be
14 changed at runtime. See the individual module
15 documentation as to the contents of these parameters and
16 what they accomplish.
17
18 Note: The individual parameter names and values are not
19 considered stable, only the fact that they will be
20 placed in this location within sysfs. See the
21 individual driver documentation for details as to the
22 stability of the different parameters.
23
24 /sys/module/MODULENAME/refcnt
25 If the module is able to be unloaded from the kernel, this file
26 will contain the current reference count of the module.
27
28 Note: If the module is built into the kernel, or if the
29 CONFIG_MODULE_UNLOAD kernel configuration value is not enabled,
30 this file will not be present.
diff --git a/Documentation/ABI/testing/sysfs-class b/Documentation/ABI/testing/sysfs-class
new file mode 100644
index 000000000000..4b0cb891e46e
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class
@@ -0,0 +1,16 @@
1What: /sys/class/
2Date: Febuary 2006
3Contact: Greg Kroah-Hartman <gregkh@suse.de>
4Description:
5 The /sys/class directory will consist of a group of
6 subdirectories describing individual classes of devices
7 in the kernel. The individual directories will consist
8 of either subdirectories, or symlinks to other
9 directories.
10
11 All programs that use this directory tree must be able
12 to handle both subdirectories or symlinks in order to
13 work properly.
14
15Users:
16 udev <linux-hotplug-devel@lists.sourceforge.net>
diff --git a/Documentation/ABI/testing/sysfs-devices b/Documentation/ABI/testing/sysfs-devices
new file mode 100644
index 000000000000..6a25671ee5f6
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices
@@ -0,0 +1,25 @@
1What: /sys/devices
2Date: February 2006
3Contact: Greg Kroah-Hartman <gregkh@suse.de>
4Description:
5 The /sys/devices tree contains a snapshot of the
6 internal state of the kernel device tree. Devices will
7 be added and removed dynamically as the machine runs,
8 and between different kernel versions, the layout of the
9 devices within this tree will change.
10
11 Please do not rely on the format of this tree because of
12 this. If a program wishes to find different things in
13 the tree, please use the /sys/class structure and rely
14 on the symlinks there to point to the proper location
15 within the /sys/devices tree of the individual devices.
16 Or rely on the uevent messages to notify programs of
17 devices being added and removed from this tree to find
18 the location of those devices.
19
20 Note that sometimes not all devices along the directory
21 chain will have emitted uevent messages, so userspace
22 programs must be able to handle such occurrences.
23
24Users:
25 udev <linux-hotplug-devel@lists.sourceforge.net>
diff --git a/Documentation/isdn/README.gigaset b/Documentation/isdn/README.gigaset
index 85a64defd385..fa0d4cca964a 100644
--- a/Documentation/isdn/README.gigaset
+++ b/Documentation/isdn/README.gigaset
@@ -124,7 +124,8 @@ GigaSet 307x Device Driver
124 124
125 You can use some configuration tool of your distribution to configure this 125 You can use some configuration tool of your distribution to configure this
126 "modem" or configure pppd/wvdial manually. There are some example ppp 126 "modem" or configure pppd/wvdial manually. There are some example ppp
127 configuration files and chat scripts in the gigaset-VERSION/ppp directory. 127 configuration files and chat scripts in the gigaset-VERSION/ppp directory
128 in the driver packages from http://sourceforge.net/projects/gigaset307x/.
128 Please note that the USB drivers are not able to change the state of the 129 Please note that the USB drivers are not able to change the state of the
129 control lines (the M105 driver can be configured to use some undocumented 130 control lines (the M105 driver can be configured to use some undocumented
130 control requests, if you really need the control lines, though). This means 131 control requests, if you really need the control lines, though). This means
@@ -164,8 +165,8 @@ GigaSet 307x Device Driver
164 165
165 If you want both of these at once, you are out of luck. 166 If you want both of these at once, you are out of luck.
166 167
167 You can also use /sys/module/<name>/parameters/cidmode for changing 168 You can also use /sys/class/tty/ttyGxy/cidmode for changing the CID mode
168 the CID mode setting (<name> is usb_gigaset or bas_gigaset). 169 setting (ttyGxy is ttyGU0 or ttyGB0).
169 170
170 171
1713. Troubleshooting 1723. Troubleshooting
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index aaa01b0e3ee9..3bbe157b45e4 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -19,6 +19,7 @@ This document has the following sections:
19 - Key overview 19 - Key overview
20 - Key service overview 20 - Key service overview
21 - Key access permissions 21 - Key access permissions
22 - SELinux support
22 - New procfs files 23 - New procfs files
23 - Userspace system call interface 24 - Userspace system call interface
24 - Kernel services 25 - Kernel services
@@ -232,6 +233,34 @@ For changing the ownership, group ID or permissions mask, being the owner of
232the key or having the sysadmin capability is sufficient. 233the key or having the sysadmin capability is sufficient.
233 234
234 235
236===============
237SELINUX SUPPORT
238===============
239
240The security class "key" has been added to SELinux so that mandatory access
241controls can be applied to keys created within various contexts. This support
242is preliminary, and is likely to change quite significantly in the near future.
243Currently, all of the basic permissions explained above are provided in SELinux
244as well; SE Linux is simply invoked after all basic permission checks have been
245performed.
246
247Each key is labeled with the same context as the task to which it belongs.
248Typically, this is the same task that was running when the key was created.
249The default keyrings are handled differently, but in a way that is very
250intuitive:
251
252 (*) The user and user session keyrings that are created when the user logs in
253 are currently labeled with the context of the login manager.
254
255 (*) The keyrings associated with new threads are each labeled with the context
256 of their associated thread, and both session and process keyrings are
257 handled similarly.
258
259Note, however, that the default keyrings associated with the root user are
260labeled with the default kernel context, since they are created early in the
261boot process, before root has a chance to log in.
262
263
235================ 264================
236NEW PROCFS FILES 265NEW PROCFS FILES
237================ 266================
@@ -935,6 +964,16 @@ The structure has a number of fields, some of which are mandatory:
935 It is not safe to sleep in this method; the caller may hold spinlocks. 964 It is not safe to sleep in this method; the caller may hold spinlocks.
936 965
937 966
967 (*) void (*revoke)(struct key *key);
968
969 This method is optional. It is called to discard part of the payload
970 data upon a key being revoked. The caller will have the key semaphore
971 write-locked.
972
973 It is safe to sleep in this method, though care should be taken to avoid
974 a deadlock against the key semaphore.
975
976
938 (*) void (*destroy)(struct key *key); 977 (*) void (*destroy)(struct key *key);
939 978
940 This method is optional. It is called to discard the payload data on a key 979 This method is optional. It is called to discard the payload data on a key
diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
index f987afe43e28..fba1e05c47c7 100644
--- a/Documentation/power/devices.txt
+++ b/Documentation/power/devices.txt
@@ -135,96 +135,6 @@ HW.
135 135
136FREEZE -- stop DMA and interrupts, and be prepared to reinit HW from 136FREEZE -- stop DMA and interrupts, and be prepared to reinit HW from
137scratch. That probably means stop accepting upstream requests, the 137scratch. That probably means stop accepting upstream requests, the
138actual policy of what to do with them beeing specific to a given
139driver. It's acceptable for a network driver to just drop packets
140while a block driver is expected to block the queue so no request is
141lost. (Use IDE as an example on how to do that). FREEZE requires no
142power state change, and it's expected for drivers to be able to
143quickly transition back to operating state.
144
145SUSPEND -- like FREEZE, but also put hardware into low-power state. If
146there's need to distinguish several levels of sleep, additional flag
147is probably best way to do that.
148
149Transitions are only from a resumed state to a suspended state, never
150between 2 suspended states. (ON -> FREEZE or ON -> SUSPEND can happen,
151FREEZE -> SUSPEND or SUSPEND -> FREEZE can not).
152
153All events are:
154
155[NOTE NOTE NOTE: If you are driver author, you should not care; you
156should only look at event, and ignore flags.]
157
158#Prepare for suspend -- userland is still running but we are going to
159#enter suspend state. This gives drivers chance to load firmware from
160#disk and store it in memory, or do other activities taht require
161#operating userland, ability to kmalloc GFP_KERNEL, etc... All of these
162#are forbiden once the suspend dance is started.. event = ON, flags =
163#PREPARE_TO_SUSPEND
164
165Apm standby -- prepare for APM event. Quiesce devices to make life
166easier for APM BIOS. event = FREEZE, flags = APM_STANDBY
167
168Apm suspend -- same as APM_STANDBY, but it we should probably avoid
169spinning down disks. event = FREEZE, flags = APM_SUSPEND
170
171System halt, reboot -- quiesce devices to make life easier for BIOS. event
172= FREEZE, flags = SYSTEM_HALT or SYSTEM_REBOOT
173
174System shutdown -- at least disks need to be spun down, or data may be
175lost. Quiesce devices, just to make life easier for BIOS. event =
176FREEZE, flags = SYSTEM_SHUTDOWN
177
178Kexec -- turn off DMAs and put hardware into some state where new
179kernel can take over. event = FREEZE, flags = KEXEC
180
181Powerdown at end of swsusp -- very similar to SYSTEM_SHUTDOWN, except wake
182may need to be enabled on some devices. This actually has at least 3
183subtypes, system can reboot, enter S4 and enter S5 at the end of
184swsusp. event = FREEZE, flags = SWSUSP and one of SYSTEM_REBOOT,
185SYSTEM_SHUTDOWN, SYSTEM_S4
186
187Suspend to ram -- put devices into low power state. event = SUSPEND,
188flags = SUSPEND_TO_RAM
189
190Freeze for swsusp snapshot -- stop DMA and interrupts. No need to put
191devices into low power mode, but you must be able to reinitialize
192device from scratch in resume method. This has two flavors, its done
193once on suspending kernel, once on resuming kernel. event = FREEZE,
194flags = DURING_SUSPEND or DURING_RESUME
195
196Device detach requested from /sys -- deinitialize device; proably same as
197SYSTEM_SHUTDOWN, I do not understand this one too much. probably event
198= FREEZE, flags = DEV_DETACH.
199
200#These are not really events sent:
201#
202#System fully on -- device is working normally; this is probably never
203#passed to suspend() method... event = ON, flags = 0
204#
205#Ready after resume -- userland is now running, again. Time to free any
206#memory you ate during prepare to suspend... event = ON, flags =
207#READY_AFTER_RESUME
208#
209
210
211pm_message_t meaning
212
213pm_message_t has two fields. event ("major"), and flags. If driver
214does not know event code, it aborts the request, returning error. Some
215drivers may need to deal with special cases based on the actual type
216of suspend operation being done at the system level. This is why
217there are flags.
218
219Event codes are:
220
221ON -- no need to do anything except special cases like broken
222HW.
223
224# NOTIFICATION -- pretty much same as ON?
225
226FREEZE -- stop DMA and interrupts, and be prepared to reinit HW from
227scratch. That probably means stop accepting upstream requests, the
228actual policy of what to do with them being specific to a given 138actual policy of what to do with them being specific to a given
229driver. It's acceptable for a network driver to just drop packets 139driver. It's acceptable for a network driver to just drop packets
230while a block driver is expected to block the queue so no request is 140while a block driver is expected to block the queue so no request is
diff --git a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt
index d7814a113ee1..516c5019013b 100644
--- a/Documentation/power/swsusp.txt
+++ b/Documentation/power/swsusp.txt
@@ -18,10 +18,11 @@ Some warnings, first.
18 * 18 *
19 * (*) suspend/resume support is needed to make it safe. 19 * (*) suspend/resume support is needed to make it safe.
20 * 20 *
21 * If you have any filesystems on USB devices mounted before suspend, 21 * If you have any filesystems on USB devices mounted before software suspend,
22 * they won't be accessible after resume and you may lose data, as though 22 * they won't be accessible after resume and you may lose data, as though
23 * you have unplugged the USB devices with mounted filesystems on them 23 * you have unplugged the USB devices with mounted filesystems on them;
24 * (see the FAQ below for details). 24 * see the FAQ below for details. (This is not true for more traditional
25 * power states like "standby", which normally don't turn USB off.)
25 26
26You need to append resume=/dev/your_swap_partition to kernel command 27You need to append resume=/dev/your_swap_partition to kernel command
27line. Then you suspend by 28line. Then you suspend by
@@ -204,7 +205,7 @@ Q: There don't seem to be any generally useful behavioral
204distinctions between SUSPEND and FREEZE. 205distinctions between SUSPEND and FREEZE.
205 206
206A: Doing SUSPEND when you are asked to do FREEZE is always correct, 207A: Doing SUSPEND when you are asked to do FREEZE is always correct,
207but it may be unneccessarily slow. If you want USB to stay simple, 208but it may be unneccessarily slow. If you want your driver to stay simple,
208slowness may not matter to you. It can always be fixed later. 209slowness may not matter to you. It can always be fixed later.
209 210
210For devices like disk it does matter, you do not want to spindown for 211For devices like disk it does matter, you do not want to spindown for
@@ -357,17 +358,25 @@ Q: Is this true that if I have a mounted filesystem on a USB device and
357I suspend to disk, I can lose data unless the filesystem has been mounted 358I suspend to disk, I can lose data unless the filesystem has been mounted
358with "sync"? 359with "sync"?
359 360
360A: That's right. It depends on your hardware, and it could be true even for 361A: That's right ... if you disconnect that device, you may lose data.
361suspend-to-RAM. In fact, even with "-o sync" you can lose data if your 362In fact, even with "-o sync" you can lose data if your programs have
362programs have information in buffers they haven't written out to disk. 363information in buffers they haven't written out to a disk you disconnect,
364or if you disconnect before the device finished saving data you wrote.
363 365
364If you're lucky, your hardware will support low-power modes for USB 366Software suspend normally powers down USB controllers, which is equivalent
365controllers while the system is asleep. Lots of hardware doesn't, 367to disconnecting all USB devices attached to your system.
366however. Shutting off the power to a USB controller is equivalent to 368
367unplugging all the attached devices. 369Your system might well support low-power modes for its USB controllers
370while the system is asleep, maintaining the connection, using true sleep
371modes like "suspend-to-RAM" or "standby". (Don't write "disk" to the
372/sys/power/state file; write "standby" or "mem".) We've not seen any
373hardware that can use these modes through software suspend, although in
374theory some systems might support "platform" or "firmware" modes that
375won't break the USB connections.
368 376
369Remember that it's always a bad idea to unplug a disk drive containing a 377Remember that it's always a bad idea to unplug a disk drive containing a
370mounted filesystem. With USB that's true even when your system is asleep! 378mounted filesystem. That's true even when your system is asleep! The
371The safest thing is to unmount all USB-based filesystems before suspending 379safest thing is to unmount all filesystems on removable media (such USB,
372and remount them after resuming. 380Firewire, CompactFlash, MMC, external SATA, or even IDE hotplug bays)
381before suspending; then remount them after resuming.
373 382
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 0ee2c7dfc482..87d76a5c73d0 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -366,7 +366,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
366 366
367 Module for C-Media CMI8338 and 8738 PCI sound cards. 367 Module for C-Media CMI8338 and 8738 PCI sound cards.
368 368
369 mpu_port - 0x300,0x310,0x320,0x330, 0 = disable (default) 369 mpu_port - 0x300,0x310,0x320,0x330 = legacy port,
370 1 = integrated PCI port,
371 0 = disable (default)
370 fm_port - 0x388 (default), 0 = disable (default) 372 fm_port - 0x388 (default), 0 = disable (default)
371 soft_ac3 - Software-conversion of raw SPDIF packets (model 033 only) 373 soft_ac3 - Software-conversion of raw SPDIF packets (model 033 only)
372 (default = 1) 374 (default = 1)
@@ -468,7 +470,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
468 470
469 Module for multifunction CS5535 companion PCI device 471 Module for multifunction CS5535 companion PCI device
470 472
471 This module supports multiple cards. 473 The power-management is supported.
472 474
473 Module snd-dt019x 475 Module snd-dt019x
474 ----------------- 476 -----------------
@@ -707,8 +709,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
707 Module snd-hda-intel 709 Module snd-hda-intel
708 -------------------- 710 --------------------
709 711
710 Module for Intel HD Audio (ICH6, ICH6M, ICH7), ATI SB450, 712 Module for Intel HD Audio (ICH6, ICH6M, ESB2, ICH7, ICH8),
711 VIA VT8251/VT8237A 713 ATI SB450, SB600, RS600,
714 VIA VT8251/VT8237A,
715 SIS966, ULI M5461
712 716
713 model - force the model name 717 model - force the model name
714 position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) 718 position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
@@ -778,6 +782,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
778 AD1981 782 AD1981
779 basic 3-jack (default) 783 basic 3-jack (default)
780 hp HP nx6320 784 hp HP nx6320
785 thinkpad Lenovo Thinkpad T60/X60/Z60
781 786
782 AD1986A 787 AD1986A
783 6stack 6-jack, separate surrounds (default) 788 6stack 6-jack, separate surrounds (default)
@@ -1633,9 +1638,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1633 1638
1634 About capture IBL, see the description of snd-vx222 module. 1639 About capture IBL, see the description of snd-vx222 module.
1635 1640
1636 Note: the driver is build only when CONFIG_ISA is set. 1641 Note: snd-vxp440 driver is merged to snd-vxpocket driver since
1637
1638 Note2: snd-vxp440 driver is merged to snd-vxpocket driver since
1639 ALSA 1.0.10. 1642 ALSA 1.0.10.
1640 1643
1641 The power-management is supported. 1644 The power-management is supported.
@@ -1662,8 +1665,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1662 1665
1663 Module for Sound Core PDAudioCF sound card. 1666 Module for Sound Core PDAudioCF sound card.
1664 1667
1665 Note: the driver is build only when CONFIG_ISA is set.
1666
1667 The power-management is supported. 1668 The power-management is supported.
1668 1669
1669 1670
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 1faf76383bab..635cbb94357c 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -4215,7 +4215,7 @@ struct _snd_pcm_runtime {
4215 <programlisting> 4215 <programlisting>
4216<![CDATA[ 4216<![CDATA[
4217 struct snd_rawmidi *rmidi; 4217 struct snd_rawmidi *rmidi;
4218 snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, integrated, 4218 snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,
4219 irq, irq_flags, &rmidi); 4219 irq, irq_flags, &rmidi);
4220]]> 4220]]>
4221 </programlisting> 4221 </programlisting>
@@ -4242,15 +4242,36 @@ struct _snd_pcm_runtime {
4242 </para> 4242 </para>
4243 4243
4244 <para> 4244 <para>
4245 The 5th argument is bitflags for additional information.
4245 When the i/o port address above is a part of the PCI i/o 4246 When the i/o port address above is a part of the PCI i/o
4246 region, the MPU401 i/o port might have been already allocated 4247 region, the MPU401 i/o port might have been already allocated
4247 (reserved) by the driver itself. In such a case, pass non-zero 4248 (reserved) by the driver itself. In such a case, pass a bit flag
4248 to the 5th argument 4249 <constant>MPU401_INFO_INTEGRATED</constant>,
4249 (<parameter>integrated</parameter>). Otherwise, pass 0 to it,
4250 and 4250 and
4251 the mpu401-uart layer will allocate the i/o ports by itself. 4251 the mpu401-uart layer will allocate the i/o ports by itself.
4252 </para> 4252 </para>
4253 4253
4254 <para>
4255 When the controller supports only the input or output MIDI stream,
4256 pass <constant>MPU401_INFO_INPUT</constant> or
4257 <constant>MPU401_INFO_OUTPUT</constant> bitflag, respectively.
4258 Then the rawmidi instance is created as a single stream.
4259 </para>
4260
4261 <para>
4262 <constant>MPU401_INFO_MMIO</constant> bitflag is used to change
4263 the access method to MMIO (via readb and writeb) instead of
4264 iob and outb. In this case, you have to pass the iomapped address
4265 to <function>snd_mpu401_uart_new()</function>.
4266 </para>
4267
4268 <para>
4269 When <constant>MPU401_INFO_TX_IRQ</constant> is set, the output
4270 stream isn't checked in the default interrupt handler. The driver
4271 needs to call <function>snd_mpu401_uart_interrupt_tx()</function>
4272 by itself to start processing the output stream in irq handler.
4273 </para>
4274
4254 <para> 4275 <para>
4255 Usually, the port address corresponds to the command port and 4276 Usually, the port address corresponds to the command port and
4256 port + 1 corresponds to the data port. If not, you may change 4277 port + 1 corresponds to the data port. If not, you may change
@@ -5333,7 +5354,7 @@ struct _snd_pcm_runtime {
5333 <informalexample> 5354 <informalexample>
5334 <programlisting> 5355 <programlisting>
5335<![CDATA[ 5356<![CDATA[
5336 snd_info_set_text_ops(entry, chip, read_size, my_proc_read); 5357 snd_info_set_text_ops(entry, chip, my_proc_read);
5337]]> 5358]]>
5338 </programlisting> 5359 </programlisting>
5339 </informalexample> 5360 </informalexample>
@@ -5394,7 +5415,6 @@ struct _snd_pcm_runtime {
5394 <informalexample> 5415 <informalexample>
5395 <programlisting> 5416 <programlisting>
5396<![CDATA[ 5417<![CDATA[
5397 entry->c.text.write_size = 256;
5398 entry->c.text.write = my_proc_write; 5418 entry->c.text.write = my_proc_write;
5399]]> 5419]]>
5400 </programlisting> 5420 </programlisting>
@@ -5402,22 +5422,6 @@ struct _snd_pcm_runtime {
5402 </para> 5422 </para>
5403 5423
5404 <para> 5424 <para>
5405 The buffer size for read is set to 1024 implicitly by
5406 <function>snd_info_set_text_ops()</function>. It should suffice
5407 in most cases (the size will be aligned to
5408 <constant>PAGE_SIZE</constant> anyway), but if you need to handle
5409 very large text files, you can set it explicitly, too.
5410
5411 <informalexample>
5412 <programlisting>
5413<![CDATA[
5414 entry->c.text.read_size = 65536;
5415]]>
5416 </programlisting>
5417 </informalexample>
5418 </para>
5419
5420 <para>
5421 For the write callback, you can use 5425 For the write callback, you can use
5422 <function>snd_info_get_line()</function> to get a text line, and 5426 <function>snd_info_get_line()</function> to get a text line, and
5423 <function>snd_info_get_str()</function> to retrieve a string from 5427 <function>snd_info_get_str()</function> to retrieve a string from
@@ -5562,7 +5566,7 @@ struct _snd_pcm_runtime {
5562 power status.</para></listitem> 5566 power status.</para></listitem>
5563 <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem> 5567 <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem>
5564 <listitem><para>If AC97 codecs are used, call 5568 <listitem><para>If AC97 codecs are used, call
5565 <function>snd_ac97_resume()</function> for each codec.</para></listitem> 5569 <function>snd_ac97_suspend()</function> for each codec.</para></listitem>
5566 <listitem><para>Save the register values if necessary.</para></listitem> 5570 <listitem><para>Save the register values if necessary.</para></listitem>
5567 <listitem><para>Stop the hardware if necessary.</para></listitem> 5571 <listitem><para>Stop the hardware if necessary.</para></listitem>
5568 <listitem><para>Disable the PCI device by calling 5572 <listitem><para>Disable the PCI device by calling
diff --git a/Documentation/usb/usbmon.txt b/Documentation/usb/usbmon.txt
index 63cb7edd177e..e65ec828d7aa 100644
--- a/Documentation/usb/usbmon.txt
+++ b/Documentation/usb/usbmon.txt
@@ -29,14 +29,13 @@ if usbmon is built into the kernel.
29 29
30# mount -t debugfs none_debugs /sys/kernel/debug 30# mount -t debugfs none_debugs /sys/kernel/debug
31# modprobe usbmon 31# modprobe usbmon
32#
32 33
33Verify that bus sockets are present. 34Verify that bus sockets are present.
34 35
35[root@lembas zaitcev]# ls /sys/kernel/debug/usbmon 36# ls /sys/kernel/debug/usbmon
361s 1t 2s 2t 3s 3t 4s 4t 371s 1t 2s 2t 3s 3t 4s 4t
37[root@lembas zaitcev]# 38#
38
39# ls /sys/kernel
40 39
412. Find which bus connects to the desired device 402. Find which bus connects to the desired device
42 41
@@ -76,7 +75,7 @@ that the file size is not excessive for your favourite editor.
76 75
77* Raw text data format 76* Raw text data format
78 77
79The '0t' type data consists of a stream of events, such as URB submission, 78The '1t' type data consists of a stream of events, such as URB submission,
80URB callback, submission error. Every event is a text line, which consists 79URB callback, submission error. Every event is a text line, which consists
81of whitespace separated words. The number of position of words may depend 80of whitespace separated words. The number of position of words may depend
82on the event type, but there is a set of words, common for all types. 81on the event type, but there is a set of words, common for all types.
@@ -97,20 +96,25 @@ Here is the list of words, from left to right:
97 Zi Zo Isochronous input and output 96 Zi Zo Isochronous input and output
98 Ii Io Interrupt input and output 97 Ii Io Interrupt input and output
99 Bi Bo Bulk input and output 98 Bi Bo Bulk input and output
100 Device address and Endpoint number are decimal numbers with leading zeroes 99 Device address and Endpoint number are 3-digit and 2-digit (respectively)
101 or 3 and 2 positions, correspondingly. 100 decimal numbers, with leading zeroes.
102- URB Status. This field makes no sense for submissions, but is present 101- URB Status. In most cases, this field contains a number, sometimes negative,
103 to help scripts with parsing. In error case, it contains the error code. 102 which represents a "status" field of the URB. This field makes no sense for
104 In case of a setup packet, it contains a Setup Tag. If scripts read a number 103 submissions, but is present anyway to help scripts with parsing. When an
105 in this field, they proceed to read Data Length. Otherwise, they read 104 error occurs, the field contains the error code. In case of a submission of
106 the setup packet before reading the Data Length. 105 a Control packet, this field contains a Setup Tag instead of an error code.
106 It is easy to tell whether the Setup Tag is present because it is never a
107 number. Thus if scripts find a number in this field, they proceed to read
108 Data Length. If they find something else, like a letter, they read the setup
109 packet before reading the Data Length.
107- Setup packet, if present, consists of 5 words: one of each for bmRequestType, 110- Setup packet, if present, consists of 5 words: one of each for bmRequestType,
108 bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0. 111 bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0.
109 These words are safe to decode if Setup Tag was 's'. Otherwise, the setup 112 These words are safe to decode if Setup Tag was 's'. Otherwise, the setup
110 packet was present, but not captured, and the fields contain filler. 113 packet was present, but not captured, and the fields contain filler.
111- Data Length. This is the actual length in the URB. 114- Data Length. For submissions, this is the requested length. For callbacks,
115 this is the actual length.
112- Data tag. The usbmon may not always capture data, even if length is nonzero. 116- Data tag. The usbmon may not always capture data, even if length is nonzero.
113 Only if tag is '=', the data words are present. 117 The data words are present only if this tag is '='.
114- Data words follow, in big endian hexadecimal format. Notice that they are 118- Data words follow, in big endian hexadecimal format. Notice that they are
115 not machine words, but really just a byte stream split into words to make 119 not machine words, but really just a byte stream split into words to make
116 it easier to read. Thus, the last word may contain from one to four bytes. 120 it easier to read. Thus, the last word may contain from one to four bytes.
diff --git a/MAINTAINERS b/MAINTAINERS
index 0692c33d13cd..d10e629db563 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3191,7 +3191,7 @@ XFS FILESYSTEM
3191P: Silicon Graphics Inc 3191P: Silicon Graphics Inc
3192M: xfs-masters@oss.sgi.com 3192M: xfs-masters@oss.sgi.com
3193M: nathans@sgi.com 3193M: nathans@sgi.com
3194L: linux-xfs@oss.sgi.com 3194L: xfs@oss.sgi.com
3195W: http://oss.sgi.com/projects/xfs 3195W: http://oss.sgi.com/projects/xfs
3196S: Supported 3196S: Supported
3197 3197
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 840ae595a617..d961bfeed05f 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -29,8 +29,8 @@ OBJCOPYFLAGS := contents,alloc,load,readonly,data
29OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000 29OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000
30OBJCOPY_MIB_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment 30OBJCOPY_MIB_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
31 31
32zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c 32zlib := inffast.c inflate.c inftrees.c
33zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h 33zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
34zliblinuxheader := zlib.h zconf.h zutil.h 34zliblinuxheader := zlib.h zconf.h zutil.h
35 35
36$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) 36$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index ceb584682fa3..71a3275935ec 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -372,7 +372,7 @@ static int __init fsl_usb_of_init(void)
372{ 372{
373 struct device_node *np; 373 struct device_node *np;
374 unsigned int i; 374 unsigned int i;
375 struct platform_device *usb_dev; 375 struct platform_device *usb_dev_mph = NULL, *usb_dev_dr = NULL;
376 int ret; 376 int ret;
377 377
378 for (np = NULL, i = 0; 378 for (np = NULL, i = 0;
@@ -393,15 +393,15 @@ static int __init fsl_usb_of_init(void)
393 r[1].end = np->intrs[0].line; 393 r[1].end = np->intrs[0].line;
394 r[1].flags = IORESOURCE_IRQ; 394 r[1].flags = IORESOURCE_IRQ;
395 395
396 usb_dev = 396 usb_dev_mph =
397 platform_device_register_simple("fsl-usb2-mph", i, r, 2); 397 platform_device_register_simple("fsl-ehci", i, r, 2);
398 if (IS_ERR(usb_dev)) { 398 if (IS_ERR(usb_dev_mph)) {
399 ret = PTR_ERR(usb_dev); 399 ret = PTR_ERR(usb_dev_mph);
400 goto err; 400 goto err;
401 } 401 }
402 402
403 usb_dev->dev.coherent_dma_mask = 0xffffffffUL; 403 usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL;
404 usb_dev->dev.dma_mask = &usb_dev->dev.coherent_dma_mask; 404 usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask;
405 405
406 usb_data.operating_mode = FSL_USB2_MPH_HOST; 406 usb_data.operating_mode = FSL_USB2_MPH_HOST;
407 407
@@ -417,31 +417,14 @@ static int __init fsl_usb_of_init(void)
417 usb_data.phy_mode = determine_usb_phy(prop); 417 usb_data.phy_mode = determine_usb_phy(prop);
418 418
419 ret = 419 ret =
420 platform_device_add_data(usb_dev, &usb_data, 420 platform_device_add_data(usb_dev_mph, &usb_data,
421 sizeof(struct 421 sizeof(struct
422 fsl_usb2_platform_data)); 422 fsl_usb2_platform_data));
423 if (ret) 423 if (ret)
424 goto unreg; 424 goto unreg_mph;
425 } 425 }
426 426
427 return 0; 427 for (np = NULL;
428
429unreg:
430 platform_device_unregister(usb_dev);
431err:
432 return ret;
433}
434
435arch_initcall(fsl_usb_of_init);
436
437static int __init fsl_usb_dr_of_init(void)
438{
439 struct device_node *np;
440 unsigned int i;
441 struct platform_device *usb_dev;
442 int ret;
443
444 for (np = NULL, i = 0;
445 (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL; 428 (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL;
446 i++) { 429 i++) {
447 struct resource r[2]; 430 struct resource r[2];
@@ -453,21 +436,21 @@ static int __init fsl_usb_dr_of_init(void)
453 436
454 ret = of_address_to_resource(np, 0, &r[0]); 437 ret = of_address_to_resource(np, 0, &r[0]);
455 if (ret) 438 if (ret)
456 goto err; 439 goto unreg_mph;
457 440
458 r[1].start = np->intrs[0].line; 441 r[1].start = np->intrs[0].line;
459 r[1].end = np->intrs[0].line; 442 r[1].end = np->intrs[0].line;
460 r[1].flags = IORESOURCE_IRQ; 443 r[1].flags = IORESOURCE_IRQ;
461 444
462 usb_dev = 445 usb_dev_dr =
463 platform_device_register_simple("fsl-usb2-dr", i, r, 2); 446 platform_device_register_simple("fsl-ehci", i, r, 2);
464 if (IS_ERR(usb_dev)) { 447 if (IS_ERR(usb_dev_dr)) {
465 ret = PTR_ERR(usb_dev); 448 ret = PTR_ERR(usb_dev_dr);
466 goto err; 449 goto err;
467 } 450 }
468 451
469 usb_dev->dev.coherent_dma_mask = 0xffffffffUL; 452 usb_dev_dr->dev.coherent_dma_mask = 0xffffffffUL;
470 usb_dev->dev.dma_mask = &usb_dev->dev.coherent_dma_mask; 453 usb_dev_dr->dev.dma_mask = &usb_dev_dr->dev.coherent_dma_mask;
471 454
472 usb_data.operating_mode = FSL_USB2_DR_HOST; 455 usb_data.operating_mode = FSL_USB2_DR_HOST;
473 456
@@ -475,19 +458,22 @@ static int __init fsl_usb_dr_of_init(void)
475 usb_data.phy_mode = determine_usb_phy(prop); 458 usb_data.phy_mode = determine_usb_phy(prop);
476 459
477 ret = 460 ret =
478 platform_device_add_data(usb_dev, &usb_data, 461 platform_device_add_data(usb_dev_dr, &usb_data,
479 sizeof(struct 462 sizeof(struct
480 fsl_usb2_platform_data)); 463 fsl_usb2_platform_data));
481 if (ret) 464 if (ret)
482 goto unreg; 465 goto unreg_dr;
483 } 466 }
484
485 return 0; 467 return 0;
486 468
487unreg: 469unreg_dr:
488 platform_device_unregister(usb_dev); 470 if (usb_dev_dr)
471 platform_device_unregister(usb_dev_dr);
472unreg_mph:
473 if (usb_dev_mph)
474 platform_device_unregister(usb_dev_mph);
489err: 475err:
490 return ret; 476 return ret;
491} 477}
492 478
493arch_initcall(fsl_usb_dr_of_init); 479arch_initcall(fsl_usb_of_init);
diff --git a/arch/ppc/boot/lib/Makefile b/arch/ppc/boot/lib/Makefile
index 80c84d562fa4..2f995f712ec5 100644
--- a/arch/ppc/boot/lib/Makefile
+++ b/arch/ppc/boot/lib/Makefile
@@ -5,7 +5,7 @@
5CFLAGS_kbd.o := -Idrivers/char 5CFLAGS_kbd.o := -Idrivers/char
6CFLAGS_vreset.o := -Iarch/ppc/boot/include 6CFLAGS_vreset.o := -Iarch/ppc/boot/include
7 7
8zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c 8zlib := inffast.c inflate.c inftrees.c
9 9
10lib-y += $(zlib:.c=.o) div64.o 10lib-y += $(zlib:.c=.o) div64.o
11lib-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o 11lib-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
index 1af2c000fcfa..5c4932ca8e9b 100644
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -186,7 +186,7 @@ struct platform_device ppc_sys_platform_devices[] = {
186 }, 186 },
187 }, 187 },
188 [MPC83xx_USB2_DR] = { 188 [MPC83xx_USB2_DR] = {
189 .name = "fsl-usb2-dr", 189 .name = "fsl-ehci",
190 .id = 1, 190 .id = 1,
191 .num_resources = 2, 191 .num_resources = 2,
192 .resource = (struct resource[]) { 192 .resource = (struct resource[]) {
@@ -203,8 +203,8 @@ struct platform_device ppc_sys_platform_devices[] = {
203 }, 203 },
204 }, 204 },
205 [MPC83xx_USB2_MPH] = { 205 [MPC83xx_USB2_MPH] = {
206 .name = "fsl-usb2-mph", 206 .name = "fsl-ehci",
207 .id = 1, 207 .id = 2,
208 .num_resources = 2, 208 .num_resources = 2,
209 .resource = (struct resource[]) { 209 .resource = (struct resource[]) {
210 { 210 {
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 2cbf282f0d00..a893a9cc9534 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -332,7 +332,7 @@ void __init setup_arch(char **cmdline_p)
332 if (!root_flags) 332 if (!root_flags)
333 root_mountflags &= ~MS_RDONLY; 333 root_mountflags &= ~MS_RDONLY;
334 ROOT_DEV = old_decode_dev(root_dev); 334 ROOT_DEV = old_decode_dev(root_dev);
335#ifdef CONFIG_BLK_DEV_INITRD 335#ifdef CONFIG_BLK_DEV_RAM
336 rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK; 336 rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
337 rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0); 337 rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0);
338 rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0); 338 rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0);
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index 86f51d04c98d..87cdbc560d36 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -87,7 +87,7 @@ void timer_irq(union uml_pt_regs *regs)
87 87
88void time_init_kern(void) 88void time_init_kern(void)
89{ 89{
90 unsigned long long nsecs; 90 long long nsecs;
91 91
92 nsecs = os_nsecs(); 92 nsecs = os_nsecs();
93 set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, 93 set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 408d44a59756..7d3bc5ac5db0 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -389,6 +389,7 @@ config GART_IOMMU
389 bool "K8 GART IOMMU support" 389 bool "K8 GART IOMMU support"
390 default y 390 default y
391 select SWIOTLB 391 select SWIOTLB
392 select AGP
392 depends on PCI 393 depends on PCI
393 help 394 help
394 Support for hardware IOMMU in AMD's Opteron/Athlon64 Processors 395 Support for hardware IOMMU in AMD's Opteron/Athlon64 Processors
@@ -401,11 +402,9 @@ config GART_IOMMU
401 northbridge and a software emulation used on other systems without 402 northbridge and a software emulation used on other systems without
402 hardware IOMMU. If unsure, say Y. 403 hardware IOMMU. If unsure, say Y.
403 404
404# need this always enabled with GART_IOMMU for the VIA workaround 405# need this always selected by GART_IOMMU for the VIA workaround
405config SWIOTLB 406config SWIOTLB
406 bool 407 bool
407 default y
408 depends on GART_IOMMU
409 408
410config X86_MCE 409config X86_MCE
411 bool "Machine check support" if EMBEDDED 410 bool "Machine check support" if EMBEDDED
diff --git a/arch/xtensa/boot/lib/Makefile b/arch/xtensa/boot/lib/Makefile
index 9e73bb8aeb7a..d3d2aa2d883a 100644
--- a/arch/xtensa/boot/lib/Makefile
+++ b/arch/xtensa/boot/lib/Makefile
@@ -2,7 +2,7 @@
2# Makefile for some libs needed by zImage. 2# Makefile for some libs needed by zImage.
3# 3#
4 4
5zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c 5zlib := inffast.c inflate.c inftrees.c
6 6
7lib-y += $(zlib:.c=.o) zmem.o 7lib-y += $(zlib:.c=.o) zmem.o
8 8
diff --git a/block/genhd.c b/block/genhd.c
index 5a8d3bf02f17..8d7339511e5e 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -17,8 +17,7 @@
17#include <linux/buffer_head.h> 17#include <linux/buffer_head.h>
18#include <linux/mutex.h> 18#include <linux/mutex.h>
19 19
20static struct subsystem block_subsys; 20struct subsystem block_subsys;
21
22static DEFINE_MUTEX(block_subsys_lock); 21static DEFINE_MUTEX(block_subsys_lock);
23 22
24/* 23/*
@@ -511,9 +510,7 @@ static struct kset_uevent_ops block_uevent_ops = {
511 .uevent = block_uevent, 510 .uevent = block_uevent,
512}; 511};
513 512
514/* declare block_subsys. */ 513decl_subsys(block, &ktype_block, &block_uevent_ops);
515static decl_subsys(block, &ktype_block, &block_uevent_ops);
516
517 514
518/* 515/*
519 * aggregate disk stat collector. Uses the same stats that the sysfs 516 * aggregate disk stat collector. Uses the same stats that the sysfs
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index f0eff3dac58d..80502dc6ed66 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -38,3 +38,7 @@ config DEBUG_DRIVER
38 If you are unsure about this, say N here. 38 If you are unsure about this, say N here.
39 39
40endmenu 40endmenu
41
42config SYS_HYPERVISOR
43 bool
44 default n
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index e99471d3232b..b539e5e75b56 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -5,10 +5,12 @@ obj-y := core.o sys.o bus.o dd.o \
5 cpu.o firmware.o init.o map.o dmapool.o \ 5 cpu.o firmware.o init.o map.o dmapool.o \
6 attribute_container.o transport_class.o 6 attribute_container.o transport_class.o
7obj-y += power/ 7obj-y += power/
8obj-$(CONFIG_ISA) += isa.o
8obj-$(CONFIG_FW_LOADER) += firmware_class.o 9obj-$(CONFIG_FW_LOADER) += firmware_class.o
9obj-$(CONFIG_NUMA) += node.o 10obj-$(CONFIG_NUMA) += node.o
10obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o 11obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o
11obj-$(CONFIG_SMP) += topology.o 12obj-$(CONFIG_SMP) += topology.o
13obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
12 14
13ifeq ($(CONFIG_DEBUG_DRIVER),y) 15ifeq ($(CONFIG_DEBUG_DRIVER),y)
14EXTRA_CFLAGS += -DDEBUG 16EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index 2a7d7ae83e1e..22220733f76f 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -236,7 +236,6 @@ attribute_container_remove_device(struct device *dev,
236 } 236 }
237 up(&attribute_container_mutex); 237 up(&attribute_container_mutex);
238} 238}
239EXPORT_SYMBOL_GPL(attribute_container_remove_device);
240 239
241/** 240/**
242 * attribute_container_device_trigger - execute a trigger for each matching classdev 241 * attribute_container_device_trigger - execute a trigger for each matching classdev
@@ -276,7 +275,6 @@ attribute_container_device_trigger(struct device *dev,
276 } 275 }
277 up(&attribute_container_mutex); 276 up(&attribute_container_mutex);
278} 277}
279EXPORT_SYMBOL_GPL(attribute_container_device_trigger);
280 278
281/** 279/**
282 * attribute_container_trigger - trigger a function for each matching container 280 * attribute_container_trigger - trigger a function for each matching container
@@ -304,7 +302,6 @@ attribute_container_trigger(struct device *dev,
304 } 302 }
305 up(&attribute_container_mutex); 303 up(&attribute_container_mutex);
306} 304}
307EXPORT_SYMBOL_GPL(attribute_container_trigger);
308 305
309/** 306/**
310 * attribute_container_add_attrs - add attributes 307 * attribute_container_add_attrs - add attributes
@@ -333,7 +330,6 @@ attribute_container_add_attrs(struct class_device *classdev)
333 330
334 return 0; 331 return 0;
335} 332}
336EXPORT_SYMBOL_GPL(attribute_container_add_attrs);
337 333
338/** 334/**
339 * attribute_container_add_class_device - same function as class_device_add 335 * attribute_container_add_class_device - same function as class_device_add
@@ -352,7 +348,6 @@ attribute_container_add_class_device(struct class_device *classdev)
352 return error; 348 return error;
353 return attribute_container_add_attrs(classdev); 349 return attribute_container_add_attrs(classdev);
354} 350}
355EXPORT_SYMBOL_GPL(attribute_container_add_class_device);
356 351
357/** 352/**
358 * attribute_container_add_class_device_adapter - simple adapter for triggers 353 * attribute_container_add_class_device_adapter - simple adapter for triggers
@@ -367,7 +362,6 @@ attribute_container_add_class_device_adapter(struct attribute_container *cont,
367{ 362{
368 return attribute_container_add_class_device(classdev); 363 return attribute_container_add_class_device(classdev);
369} 364}
370EXPORT_SYMBOL_GPL(attribute_container_add_class_device_adapter);
371 365
372/** 366/**
373 * attribute_container_remove_attrs - remove any attribute files 367 * attribute_container_remove_attrs - remove any attribute files
@@ -389,7 +383,6 @@ attribute_container_remove_attrs(struct class_device *classdev)
389 for (i = 0; attrs[i]; i++) 383 for (i = 0; attrs[i]; i++)
390 class_device_remove_file(classdev, attrs[i]); 384 class_device_remove_file(classdev, attrs[i]);
391} 385}
392EXPORT_SYMBOL_GPL(attribute_container_remove_attrs);
393 386
394/** 387/**
395 * attribute_container_class_device_del - equivalent of class_device_del 388 * attribute_container_class_device_del - equivalent of class_device_del
@@ -405,7 +398,6 @@ attribute_container_class_device_del(struct class_device *classdev)
405 attribute_container_remove_attrs(classdev); 398 attribute_container_remove_attrs(classdev);
406 class_device_del(classdev); 399 class_device_del(classdev);
407} 400}
408EXPORT_SYMBOL_GPL(attribute_container_class_device_del);
409 401
410/** 402/**
411 * attribute_container_find_class_device - find the corresponding class_device 403 * attribute_container_find_class_device - find the corresponding class_device
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 5735b38582d0..c3b8dc98b8a7 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -5,13 +5,21 @@ extern int devices_init(void);
5extern int buses_init(void); 5extern int buses_init(void);
6extern int classes_init(void); 6extern int classes_init(void);
7extern int firmware_init(void); 7extern int firmware_init(void);
8#ifdef CONFIG_SYS_HYPERVISOR
9extern int hypervisor_init(void);
10#else
11static inline int hypervisor_init(void) { return 0; }
12#endif
8extern int platform_bus_init(void); 13extern int platform_bus_init(void);
9extern int system_bus_init(void); 14extern int system_bus_init(void);
10extern int cpu_dev_init(void); 15extern int cpu_dev_init(void);
11extern int attribute_container_init(void); 16extern int attribute_container_init(void);
12 17
13extern int bus_add_device(struct device * dev); 18extern int bus_add_device(struct device * dev);
19extern void bus_attach_device(struct device * dev);
14extern void bus_remove_device(struct device * dev); 20extern void bus_remove_device(struct device * dev);
21extern struct bus_type *get_bus(struct bus_type * bus);
22extern void put_bus(struct bus_type * bus);
15 23
16extern int bus_add_driver(struct device_driver *); 24extern int bus_add_driver(struct device_driver *);
17extern void bus_remove_driver(struct device_driver *); 25extern void bus_remove_driver(struct device_driver *);
@@ -34,4 +42,5 @@ struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
34 return container_of(_attr, struct class_device_attribute, attr); 42 return container_of(_attr, struct class_device_attribute, attr);
35} 43}
36 44
45extern char *make_class_name(const char *name, struct kobject *kobj);
37 46
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 76656acd00d4..050d86d0b872 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -362,8 +362,7 @@ static void device_remove_attrs(struct bus_type * bus, struct device * dev)
362 * @dev: device being added 362 * @dev: device being added
363 * 363 *
364 * - Add the device to its bus's list of devices. 364 * - Add the device to its bus's list of devices.
365 * - Try to attach to driver. 365 * - Create link to device's bus.
366 * - Create link to device's physical location.
367 */ 366 */
368int bus_add_device(struct device * dev) 367int bus_add_device(struct device * dev)
369{ 368{
@@ -372,11 +371,10 @@ int bus_add_device(struct device * dev)
372 371
373 if (bus) { 372 if (bus) {
374 pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); 373 pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
375 device_attach(dev);
376 klist_add_tail(&dev->knode_bus, &bus->klist_devices);
377 error = device_add_attrs(bus, dev); 374 error = device_add_attrs(bus, dev);
378 if (!error) { 375 if (!error) {
379 sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); 376 sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
377 sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "subsystem");
380 sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus"); 378 sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus");
381 } 379 }
382 } 380 }
@@ -384,6 +382,22 @@ int bus_add_device(struct device * dev)
384} 382}
385 383
386/** 384/**
385 * bus_attach_device - add device to bus
386 * @dev: device tried to attach to a driver
387 *
388 * - Try to attach to driver.
389 */
390void bus_attach_device(struct device * dev)
391{
392 struct bus_type * bus = dev->bus;
393
394 if (bus) {
395 device_attach(dev);
396 klist_add_tail(&dev->knode_bus, &bus->klist_devices);
397 }
398}
399
400/**
387 * bus_remove_device - remove device from bus 401 * bus_remove_device - remove device from bus
388 * @dev: device to be removed 402 * @dev: device to be removed
389 * 403 *
@@ -395,6 +409,7 @@ int bus_add_device(struct device * dev)
395void bus_remove_device(struct device * dev) 409void bus_remove_device(struct device * dev)
396{ 410{
397 if (dev->bus) { 411 if (dev->bus) {
412 sysfs_remove_link(&dev->kobj, "subsystem");
398 sysfs_remove_link(&dev->kobj, "bus"); 413 sysfs_remove_link(&dev->kobj, "bus");
399 sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); 414 sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
400 device_remove_attrs(dev->bus, dev); 415 device_remove_attrs(dev->bus, dev);
@@ -732,14 +747,9 @@ EXPORT_SYMBOL_GPL(bus_for_each_dev);
732EXPORT_SYMBOL_GPL(bus_find_device); 747EXPORT_SYMBOL_GPL(bus_find_device);
733EXPORT_SYMBOL_GPL(bus_for_each_drv); 748EXPORT_SYMBOL_GPL(bus_for_each_drv);
734 749
735EXPORT_SYMBOL_GPL(bus_add_device);
736EXPORT_SYMBOL_GPL(bus_remove_device);
737EXPORT_SYMBOL_GPL(bus_register); 750EXPORT_SYMBOL_GPL(bus_register);
738EXPORT_SYMBOL_GPL(bus_unregister); 751EXPORT_SYMBOL_GPL(bus_unregister);
739EXPORT_SYMBOL_GPL(bus_rescan_devices); 752EXPORT_SYMBOL_GPL(bus_rescan_devices);
740EXPORT_SYMBOL_GPL(get_bus);
741EXPORT_SYMBOL_GPL(put_bus);
742EXPORT_SYMBOL_GPL(find_bus);
743 753
744EXPORT_SYMBOL_GPL(bus_create_file); 754EXPORT_SYMBOL_GPL(bus_create_file);
745EXPORT_SYMBOL_GPL(bus_remove_file); 755EXPORT_SYMBOL_GPL(bus_remove_file);
diff --git a/drivers/base/class.c b/drivers/base/class.c
index b1ea4df85c7d..9aa127460262 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -91,14 +91,14 @@ void class_remove_file(struct class * cls, const struct class_attribute * attr)
91 sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr); 91 sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr);
92} 92}
93 93
94struct class * class_get(struct class * cls) 94static struct class *class_get(struct class *cls)
95{ 95{
96 if (cls) 96 if (cls)
97 return container_of(subsys_get(&cls->subsys), struct class, subsys); 97 return container_of(subsys_get(&cls->subsys), struct class, subsys);
98 return NULL; 98 return NULL;
99} 99}
100 100
101void class_put(struct class * cls) 101static void class_put(struct class * cls)
102{ 102{
103 if (cls) 103 if (cls)
104 subsys_put(&cls->subsys); 104 subsys_put(&cls->subsys);
@@ -142,6 +142,7 @@ int class_register(struct class * cls)
142 pr_debug("device class '%s': registering\n", cls->name); 142 pr_debug("device class '%s': registering\n", cls->name);
143 143
144 INIT_LIST_HEAD(&cls->children); 144 INIT_LIST_HEAD(&cls->children);
145 INIT_LIST_HEAD(&cls->devices);
145 INIT_LIST_HEAD(&cls->interfaces); 146 INIT_LIST_HEAD(&cls->interfaces);
146 init_MUTEX(&cls->sem); 147 init_MUTEX(&cls->sem);
147 error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name); 148 error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name);
@@ -504,22 +505,21 @@ void class_device_initialize(struct class_device *class_dev)
504 INIT_LIST_HEAD(&class_dev->node); 505 INIT_LIST_HEAD(&class_dev->node);
505} 506}
506 507
507static char *make_class_name(struct class_device *class_dev) 508char *make_class_name(const char *name, struct kobject *kobj)
508{ 509{
509 char *name; 510 char *class_name;
510 int size; 511 int size;
511 512
512 size = strlen(class_dev->class->name) + 513 size = strlen(name) + strlen(kobject_name(kobj)) + 2;
513 strlen(kobject_name(&class_dev->kobj)) + 2;
514 514
515 name = kmalloc(size, GFP_KERNEL); 515 class_name = kmalloc(size, GFP_KERNEL);
516 if (!name) 516 if (!class_name)
517 return ERR_PTR(-ENOMEM); 517 return ERR_PTR(-ENOMEM);
518 518
519 strcpy(name, class_dev->class->name); 519 strcpy(class_name, name);
520 strcat(name, ":"); 520 strcat(class_name, ":");
521 strcat(name, kobject_name(&class_dev->kobj)); 521 strcat(class_name, kobject_name(kobj));
522 return name; 522 return class_name;
523} 523}
524 524
525int class_device_add(struct class_device *class_dev) 525int class_device_add(struct class_device *class_dev)
@@ -535,18 +535,22 @@ int class_device_add(struct class_device *class_dev)
535 return -EINVAL; 535 return -EINVAL;
536 536
537 if (!strlen(class_dev->class_id)) 537 if (!strlen(class_dev->class_id))
538 goto register_done; 538 goto out1;
539 539
540 parent_class = class_get(class_dev->class); 540 parent_class = class_get(class_dev->class);
541 if (!parent_class) 541 if (!parent_class)
542 goto register_done; 542 goto out1;
543
543 parent_class_dev = class_device_get(class_dev->parent); 544 parent_class_dev = class_device_get(class_dev->parent);
544 545
545 pr_debug("CLASS: registering class device: ID = '%s'\n", 546 pr_debug("CLASS: registering class device: ID = '%s'\n",
546 class_dev->class_id); 547 class_dev->class_id);
547 548
548 /* first, register with generic layer. */ 549 /* first, register with generic layer. */
549 kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id); 550 error = kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
551 if (error)
552 goto out2;
553
550 if (parent_class_dev) 554 if (parent_class_dev)
551 class_dev->kobj.parent = &parent_class_dev->kobj; 555 class_dev->kobj.parent = &parent_class_dev->kobj;
552 else 556 else
@@ -554,41 +558,58 @@ int class_device_add(struct class_device *class_dev)
554 558
555 error = kobject_add(&class_dev->kobj); 559 error = kobject_add(&class_dev->kobj);
556 if (error) 560 if (error)
557 goto register_done; 561 goto out2;
558 562
559 /* add the needed attributes to this device */ 563 /* add the needed attributes to this device */
564 sysfs_create_link(&class_dev->kobj, &parent_class->subsys.kset.kobj, "subsystem");
560 class_dev->uevent_attr.attr.name = "uevent"; 565 class_dev->uevent_attr.attr.name = "uevent";
561 class_dev->uevent_attr.attr.mode = S_IWUSR; 566 class_dev->uevent_attr.attr.mode = S_IWUSR;
562 class_dev->uevent_attr.attr.owner = parent_class->owner; 567 class_dev->uevent_attr.attr.owner = parent_class->owner;
563 class_dev->uevent_attr.store = store_uevent; 568 class_dev->uevent_attr.store = store_uevent;
564 class_device_create_file(class_dev, &class_dev->uevent_attr); 569 error = class_device_create_file(class_dev, &class_dev->uevent_attr);
570 if (error)
571 goto out3;
565 572
566 if (MAJOR(class_dev->devt)) { 573 if (MAJOR(class_dev->devt)) {
567 struct class_device_attribute *attr; 574 struct class_device_attribute *attr;
568 attr = kzalloc(sizeof(*attr), GFP_KERNEL); 575 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
569 if (!attr) { 576 if (!attr) {
570 error = -ENOMEM; 577 error = -ENOMEM;
571 kobject_del(&class_dev->kobj); 578 goto out4;
572 goto register_done;
573 } 579 }
574 attr->attr.name = "dev"; 580 attr->attr.name = "dev";
575 attr->attr.mode = S_IRUGO; 581 attr->attr.mode = S_IRUGO;
576 attr->attr.owner = parent_class->owner; 582 attr->attr.owner = parent_class->owner;
577 attr->show = show_dev; 583 attr->show = show_dev;
578 class_device_create_file(class_dev, attr); 584 error = class_device_create_file(class_dev, attr);
585 if (error) {
586 kfree(attr);
587 goto out4;
588 }
589
579 class_dev->devt_attr = attr; 590 class_dev->devt_attr = attr;
580 } 591 }
581 592
582 class_device_add_attrs(class_dev); 593 error = class_device_add_attrs(class_dev);
594 if (error)
595 goto out5;
596
583 if (class_dev->dev) { 597 if (class_dev->dev) {
584 class_name = make_class_name(class_dev); 598 class_name = make_class_name(class_dev->class->name,
585 sysfs_create_link(&class_dev->kobj, 599 &class_dev->kobj);
586 &class_dev->dev->kobj, "device"); 600 error = sysfs_create_link(&class_dev->kobj,
587 sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, 601 &class_dev->dev->kobj, "device");
588 class_name); 602 if (error)
603 goto out6;
604 error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
605 class_name);
606 if (error)
607 goto out7;
589 } 608 }
590 609
591 class_device_add_groups(class_dev); 610 error = class_device_add_groups(class_dev);
611 if (error)
612 goto out8;
592 613
593 kobject_uevent(&class_dev->kobj, KOBJ_ADD); 614 kobject_uevent(&class_dev->kobj, KOBJ_ADD);
594 615
@@ -601,11 +622,28 @@ int class_device_add(struct class_device *class_dev)
601 } 622 }
602 up(&parent_class->sem); 623 up(&parent_class->sem);
603 624
604 register_done: 625 goto out1;
605 if (error) { 626
606 class_put(parent_class); 627 out8:
628 if (class_dev->dev)
629 sysfs_remove_link(&class_dev->kobj, class_name);
630 out7:
631 if (class_dev->dev)
632 sysfs_remove_link(&class_dev->kobj, "device");
633 out6:
634 class_device_remove_attrs(class_dev);
635 out5:
636 if (class_dev->devt_attr)
637 class_device_remove_file(class_dev, class_dev->devt_attr);
638 out4:
639 class_device_remove_file(class_dev, &class_dev->uevent_attr);
640 out3:
641 kobject_del(&class_dev->kobj);
642 out2:
643 if(parent_class_dev)
607 class_device_put(parent_class_dev); 644 class_device_put(parent_class_dev);
608 } 645 class_put(parent_class);
646 out1:
609 class_device_put(class_dev); 647 class_device_put(class_dev);
610 kfree(class_name); 648 kfree(class_name);
611 return error; 649 return error;
@@ -695,10 +733,12 @@ void class_device_del(struct class_device *class_dev)
695 } 733 }
696 734
697 if (class_dev->dev) { 735 if (class_dev->dev) {
698 class_name = make_class_name(class_dev); 736 class_name = make_class_name(class_dev->class->name,
737 &class_dev->kobj);
699 sysfs_remove_link(&class_dev->kobj, "device"); 738 sysfs_remove_link(&class_dev->kobj, "device");
700 sysfs_remove_link(&class_dev->dev->kobj, class_name); 739 sysfs_remove_link(&class_dev->dev->kobj, class_name);
701 } 740 }
741 sysfs_remove_link(&class_dev->kobj, "subsystem");
702 class_device_remove_file(class_dev, &class_dev->uevent_attr); 742 class_device_remove_file(class_dev, &class_dev->uevent_attr);
703 if (class_dev->devt_attr) 743 if (class_dev->devt_attr)
704 class_device_remove_file(class_dev, class_dev->devt_attr); 744 class_device_remove_file(class_dev, class_dev->devt_attr);
@@ -760,14 +800,16 @@ int class_device_rename(struct class_device *class_dev, char *new_name)
760 new_name); 800 new_name);
761 801
762 if (class_dev->dev) 802 if (class_dev->dev)
763 old_class_name = make_class_name(class_dev); 803 old_class_name = make_class_name(class_dev->class->name,
804 &class_dev->kobj);
764 805
765 strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN); 806 strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
766 807
767 error = kobject_rename(&class_dev->kobj, new_name); 808 error = kobject_rename(&class_dev->kobj, new_name);
768 809
769 if (class_dev->dev) { 810 if (class_dev->dev) {
770 new_class_name = make_class_name(class_dev); 811 new_class_name = make_class_name(class_dev->class->name,
812 &class_dev->kobj);
771 sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, 813 sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
772 new_class_name); 814 new_class_name);
773 sysfs_remove_link(&class_dev->dev->kobj, old_class_name); 815 sysfs_remove_link(&class_dev->dev->kobj, old_class_name);
@@ -858,8 +900,6 @@ EXPORT_SYMBOL_GPL(class_create_file);
858EXPORT_SYMBOL_GPL(class_remove_file); 900EXPORT_SYMBOL_GPL(class_remove_file);
859EXPORT_SYMBOL_GPL(class_register); 901EXPORT_SYMBOL_GPL(class_register);
860EXPORT_SYMBOL_GPL(class_unregister); 902EXPORT_SYMBOL_GPL(class_unregister);
861EXPORT_SYMBOL_GPL(class_get);
862EXPORT_SYMBOL_GPL(class_put);
863EXPORT_SYMBOL_GPL(class_create); 903EXPORT_SYMBOL_GPL(class_create);
864EXPORT_SYMBOL_GPL(class_destroy); 904EXPORT_SYMBOL_GPL(class_destroy);
865 905
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 6b355bd7816d..d0f84ff78776 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/string.h> 17#include <linux/string.h>
18#include <linux/kdev_t.h>
18 19
19#include <asm/semaphore.h> 20#include <asm/semaphore.h>
20 21
@@ -28,6 +29,22 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
28 * sysfs bindings for devices. 29 * sysfs bindings for devices.
29 */ 30 */
30 31
32/**
33 * dev_driver_string - Return a device's driver name, if at all possible
34 * @dev: struct device to get the name of
35 *
36 * Will return the device's driver's name if it is bound to a device. If
37 * the device is not bound to a device, it will return the name of the bus
38 * it is attached to. If it is not attached to a bus either, an empty
39 * string will be returned.
40 */
41const char *dev_driver_string(struct device *dev)
42{
43 return dev->driver ? dev->driver->name :
44 (dev->bus ? dev->bus->name : "");
45}
46EXPORT_SYMBOL_GPL(dev_driver_string);
47
31#define to_dev(obj) container_of(obj, struct device, kobj) 48#define to_dev(obj) container_of(obj, struct device, kobj)
32#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) 49#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
33 50
@@ -98,6 +115,8 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
98 struct device *dev = to_dev(kobj); 115 struct device *dev = to_dev(kobj);
99 if (dev->bus) 116 if (dev->bus)
100 return 1; 117 return 1;
118 if (dev->class)
119 return 1;
101 } 120 }
102 return 0; 121 return 0;
103} 122}
@@ -106,7 +125,11 @@ static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj)
106{ 125{
107 struct device *dev = to_dev(kobj); 126 struct device *dev = to_dev(kobj);
108 127
109 return dev->bus->name; 128 if (dev->bus)
129 return dev->bus->name;
130 if (dev->class)
131 return dev->class->name;
132 return NULL;
110} 133}
111 134
112static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, 135static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
@@ -117,6 +140,16 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
117 int length = 0; 140 int length = 0;
118 int retval = 0; 141 int retval = 0;
119 142
143 /* add the major/minor if present */
144 if (MAJOR(dev->devt)) {
145 add_uevent_var(envp, num_envp, &i,
146 buffer, buffer_size, &length,
147 "MAJOR=%u", MAJOR(dev->devt));
148 add_uevent_var(envp, num_envp, &i,
149 buffer, buffer_size, &length,
150 "MINOR=%u", MINOR(dev->devt));
151 }
152
120 /* add bus name of physical device */ 153 /* add bus name of physical device */
121 if (dev->bus) 154 if (dev->bus)
122 add_uevent_var(envp, num_envp, &i, 155 add_uevent_var(envp, num_envp, &i,
@@ -161,6 +194,12 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
161 return count; 194 return count;
162} 195}
163 196
197static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
198 char *buf)
199{
200 return print_dev_t(buf, dev->devt);
201}
202
164/* 203/*
165 * devices_subsys - structure to be registered with kobject core. 204 * devices_subsys - structure to be registered with kobject core.
166 */ 205 */
@@ -231,6 +270,7 @@ void device_initialize(struct device *dev)
231 klist_init(&dev->klist_children, klist_children_get, 270 klist_init(&dev->klist_children, klist_children_get,
232 klist_children_put); 271 klist_children_put);
233 INIT_LIST_HEAD(&dev->dma_pools); 272 INIT_LIST_HEAD(&dev->dma_pools);
273 INIT_LIST_HEAD(&dev->node);
234 init_MUTEX(&dev->sem); 274 init_MUTEX(&dev->sem);
235 device_init_wakeup(dev, 0); 275 device_init_wakeup(dev, 0);
236} 276}
@@ -249,6 +289,7 @@ void device_initialize(struct device *dev)
249int device_add(struct device *dev) 289int device_add(struct device *dev)
250{ 290{
251 struct device *parent = NULL; 291 struct device *parent = NULL;
292 char *class_name = NULL;
252 int error = -EINVAL; 293 int error = -EINVAL;
253 294
254 dev = get_device(dev); 295 dev = get_device(dev);
@@ -274,11 +315,44 @@ int device_add(struct device *dev)
274 dev->uevent_attr.store = store_uevent; 315 dev->uevent_attr.store = store_uevent;
275 device_create_file(dev, &dev->uevent_attr); 316 device_create_file(dev, &dev->uevent_attr);
276 317
277 kobject_uevent(&dev->kobj, KOBJ_ADD); 318 if (MAJOR(dev->devt)) {
319 struct device_attribute *attr;
320 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
321 if (!attr) {
322 error = -ENOMEM;
323 goto PMError;
324 }
325 attr->attr.name = "dev";
326 attr->attr.mode = S_IRUGO;
327 if (dev->driver)
328 attr->attr.owner = dev->driver->owner;
329 attr->show = show_dev;
330 error = device_create_file(dev, attr);
331 if (error) {
332 kfree(attr);
333 goto attrError;
334 }
335
336 dev->devt_attr = attr;
337 }
338
339 if (dev->class) {
340 sysfs_create_link(&dev->kobj, &dev->class->subsys.kset.kobj,
341 "subsystem");
342 sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj,
343 dev->bus_id);
344
345 sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device");
346 class_name = make_class_name(dev->class->name, &dev->kobj);
347 sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name);
348 }
349
278 if ((error = device_pm_add(dev))) 350 if ((error = device_pm_add(dev)))
279 goto PMError; 351 goto PMError;
280 if ((error = bus_add_device(dev))) 352 if ((error = bus_add_device(dev)))
281 goto BusError; 353 goto BusError;
354 kobject_uevent(&dev->kobj, KOBJ_ADD);
355 bus_attach_device(dev);
282 if (parent) 356 if (parent)
283 klist_add_tail(&dev->knode_parent, &parent->klist_children); 357 klist_add_tail(&dev->knode_parent, &parent->klist_children);
284 358
@@ -286,11 +360,17 @@ int device_add(struct device *dev)
286 if (platform_notify) 360 if (platform_notify)
287 platform_notify(dev); 361 platform_notify(dev);
288 Done: 362 Done:
363 kfree(class_name);
289 put_device(dev); 364 put_device(dev);
290 return error; 365 return error;
291 BusError: 366 BusError:
292 device_pm_remove(dev); 367 device_pm_remove(dev);
293 PMError: 368 PMError:
369 if (dev->devt_attr) {
370 device_remove_file(dev, dev->devt_attr);
371 kfree(dev->devt_attr);
372 }
373 attrError:
294 kobject_uevent(&dev->kobj, KOBJ_REMOVE); 374 kobject_uevent(&dev->kobj, KOBJ_REMOVE);
295 kobject_del(&dev->kobj); 375 kobject_del(&dev->kobj);
296 Error: 376 Error:
@@ -362,9 +442,20 @@ void put_device(struct device * dev)
362void device_del(struct device * dev) 442void device_del(struct device * dev)
363{ 443{
364 struct device * parent = dev->parent; 444 struct device * parent = dev->parent;
445 char *class_name = NULL;
365 446
366 if (parent) 447 if (parent)
367 klist_del(&dev->knode_parent); 448 klist_del(&dev->knode_parent);
449 if (dev->devt_attr)
450 device_remove_file(dev, dev->devt_attr);
451 if (dev->class) {
452 sysfs_remove_link(&dev->kobj, "subsystem");
453 sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id);
454 class_name = make_class_name(dev->class->name, &dev->kobj);
455 sysfs_remove_link(&dev->kobj, "device");
456 sysfs_remove_link(&dev->parent->kobj, class_name);
457 kfree(class_name);
458 }
368 device_remove_file(dev, &dev->uevent_attr); 459 device_remove_file(dev, &dev->uevent_attr);
369 460
370 /* Notify the platform of the removal, in case they 461 /* Notify the platform of the removal, in case they
@@ -449,3 +540,105 @@ EXPORT_SYMBOL_GPL(put_device);
449 540
450EXPORT_SYMBOL_GPL(device_create_file); 541EXPORT_SYMBOL_GPL(device_create_file);
451EXPORT_SYMBOL_GPL(device_remove_file); 542EXPORT_SYMBOL_GPL(device_remove_file);
543
544
545static void device_create_release(struct device *dev)
546{
547 pr_debug("%s called for %s\n", __FUNCTION__, dev->bus_id);
548 kfree(dev);
549}
550
551/**
552 * device_create - creates a device and registers it with sysfs
553 * @cs: pointer to the struct class that this device should be registered to.
554 * @parent: pointer to the parent struct device of this new device, if any.
555 * @dev: the dev_t for the char device to be added.
556 * @fmt: string for the class device's name
557 *
558 * This function can be used by char device classes. A struct
559 * device will be created in sysfs, registered to the specified
560 * class.
561 * A "dev" file will be created, showing the dev_t for the device, if
562 * the dev_t is not 0,0.
563 * If a pointer to a parent struct device is passed in, the newly
564 * created struct device will be a child of that device in sysfs. The
565 * pointer to the struct device will be returned from the call. Any
566 * further sysfs files that might be required can be created using this
567 * pointer.
568 *
569 * Note: the struct class passed to this function must have previously
570 * been created with a call to class_create().
571 */
572struct device *device_create(struct class *class, struct device *parent,
573 dev_t devt, char *fmt, ...)
574{
575 va_list args;
576 struct device *dev = NULL;
577 int retval = -ENODEV;
578
579 if (class == NULL || IS_ERR(class))
580 goto error;
581 if (parent == NULL) {
582 printk(KERN_WARNING "%s does not work yet for NULL parents\n", __FUNCTION__);
583 goto error;
584 }
585
586 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
587 if (!dev) {
588 retval = -ENOMEM;
589 goto error;
590 }
591
592 dev->devt = devt;
593 dev->class = class;
594 dev->parent = parent;
595 dev->release = device_create_release;
596
597 va_start(args, fmt);
598 vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args);
599 va_end(args);
600 retval = device_register(dev);
601 if (retval)
602 goto error;
603
604 /* tie the class to the device */
605 down(&class->sem);
606 list_add_tail(&dev->node, &class->devices);
607 up(&class->sem);
608
609 return dev;
610
611error:
612 kfree(dev);
613 return ERR_PTR(retval);
614}
615EXPORT_SYMBOL_GPL(device_create);
616
617/**
618 * device_destroy - removes a device that was created with device_create()
619 * @class: the pointer to the struct class that this device was registered * with.
620 * @dev: the dev_t of the device that was previously registered.
621 *
622 * This call unregisters and cleans up a class device that was created with a
623 * call to class_device_create()
624 */
625void device_destroy(struct class *class, dev_t devt)
626{
627 struct device *dev = NULL;
628 struct device *dev_tmp;
629
630 down(&class->sem);
631 list_for_each_entry(dev_tmp, &class->devices, node) {
632 if (dev_tmp->devt == devt) {
633 dev = dev_tmp;
634 break;
635 }
636 }
637 up(&class->sem);
638
639 if (dev) {
640 list_del_init(&dev->node);
641 device_unregister(dev);
642 }
643}
644EXPORT_SYMBOL_GPL(device_destroy);
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 0c99ae6a3407..5d6c011183f5 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -15,7 +15,7 @@
15#include <linux/vmalloc.h> 15#include <linux/vmalloc.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/bitops.h> 17#include <linux/bitops.h>
18#include <asm/semaphore.h> 18#include <linux/mutex.h>
19 19
20#include <linux/firmware.h> 20#include <linux/firmware.h>
21#include "base.h" 21#include "base.h"
@@ -36,7 +36,7 @@ static int loading_timeout = 10; /* In seconds */
36 36
37/* fw_lock could be moved to 'struct firmware_priv' but since it is just 37/* fw_lock could be moved to 'struct firmware_priv' but since it is just
38 * guarding for corner cases a global lock should be OK */ 38 * guarding for corner cases a global lock should be OK */
39static DECLARE_MUTEX(fw_lock); 39static DEFINE_MUTEX(fw_lock);
40 40
41struct firmware_priv { 41struct firmware_priv {
42 char fw_id[FIRMWARE_NAME_MAX]; 42 char fw_id[FIRMWARE_NAME_MAX];
@@ -142,9 +142,9 @@ firmware_loading_store(struct class_device *class_dev,
142 142
143 switch (loading) { 143 switch (loading) {
144 case 1: 144 case 1:
145 down(&fw_lock); 145 mutex_lock(&fw_lock);
146 if (!fw_priv->fw) { 146 if (!fw_priv->fw) {
147 up(&fw_lock); 147 mutex_unlock(&fw_lock);
148 break; 148 break;
149 } 149 }
150 vfree(fw_priv->fw->data); 150 vfree(fw_priv->fw->data);
@@ -152,7 +152,7 @@ firmware_loading_store(struct class_device *class_dev,
152 fw_priv->fw->size = 0; 152 fw_priv->fw->size = 0;
153 fw_priv->alloc_size = 0; 153 fw_priv->alloc_size = 0;
154 set_bit(FW_STATUS_LOADING, &fw_priv->status); 154 set_bit(FW_STATUS_LOADING, &fw_priv->status);
155 up(&fw_lock); 155 mutex_unlock(&fw_lock);
156 break; 156 break;
157 case 0: 157 case 0:
158 if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) { 158 if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) {
@@ -185,7 +185,7 @@ firmware_data_read(struct kobject *kobj,
185 struct firmware *fw; 185 struct firmware *fw;
186 ssize_t ret_count = count; 186 ssize_t ret_count = count;
187 187
188 down(&fw_lock); 188 mutex_lock(&fw_lock);
189 fw = fw_priv->fw; 189 fw = fw_priv->fw;
190 if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { 190 if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) {
191 ret_count = -ENODEV; 191 ret_count = -ENODEV;
@@ -200,7 +200,7 @@ firmware_data_read(struct kobject *kobj,
200 200
201 memcpy(buffer, fw->data + offset, ret_count); 201 memcpy(buffer, fw->data + offset, ret_count);
202out: 202out:
203 up(&fw_lock); 203 mutex_unlock(&fw_lock);
204 return ret_count; 204 return ret_count;
205} 205}
206 206
@@ -253,7 +253,7 @@ firmware_data_write(struct kobject *kobj,
253 if (!capable(CAP_SYS_RAWIO)) 253 if (!capable(CAP_SYS_RAWIO))
254 return -EPERM; 254 return -EPERM;
255 255
256 down(&fw_lock); 256 mutex_lock(&fw_lock);
257 fw = fw_priv->fw; 257 fw = fw_priv->fw;
258 if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { 258 if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) {
259 retval = -ENODEV; 259 retval = -ENODEV;
@@ -268,7 +268,7 @@ firmware_data_write(struct kobject *kobj,
268 fw->size = max_t(size_t, offset + count, fw->size); 268 fw->size = max_t(size_t, offset + count, fw->size);
269 retval = count; 269 retval = count;
270out: 270out:
271 up(&fw_lock); 271 mutex_unlock(&fw_lock);
272 return retval; 272 return retval;
273} 273}
274 274
@@ -436,14 +436,14 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
436 } else 436 } else
437 wait_for_completion(&fw_priv->completion); 437 wait_for_completion(&fw_priv->completion);
438 438
439 down(&fw_lock); 439 mutex_lock(&fw_lock);
440 if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) { 440 if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) {
441 retval = -ENOENT; 441 retval = -ENOENT;
442 release_firmware(fw_priv->fw); 442 release_firmware(fw_priv->fw);
443 *firmware_p = NULL; 443 *firmware_p = NULL;
444 } 444 }
445 fw_priv->fw = NULL; 445 fw_priv->fw = NULL;
446 up(&fw_lock); 446 mutex_unlock(&fw_lock);
447 class_device_unregister(class_dev); 447 class_device_unregister(class_dev);
448 goto out; 448 goto out;
449 449
diff --git a/drivers/base/hypervisor.c b/drivers/base/hypervisor.c
new file mode 100644
index 000000000000..0c85e9d6a448
--- /dev/null
+++ b/drivers/base/hypervisor.c
@@ -0,0 +1,19 @@
1/*
2 * hypervisor.c - /sys/hypervisor subsystem.
3 *
4 * This file is released under the GPLv2
5 *
6 */
7
8#include <linux/kobject.h>
9#include <linux/device.h>
10
11#include "base.h"
12
13decl_subsys(hypervisor, NULL, NULL);
14EXPORT_SYMBOL_GPL(hypervisor_subsys);
15
16int __init hypervisor_init(void)
17{
18 return subsystem_register(&hypervisor_subsys);
19}
diff --git a/drivers/base/init.c b/drivers/base/init.c
index c648914b9cde..37138154f9e8 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -27,6 +27,7 @@ void __init driver_init(void)
27 buses_init(); 27 buses_init();
28 classes_init(); 28 classes_init();
29 firmware_init(); 29 firmware_init();
30 hypervisor_init();
30 31
31 /* These are also core pieces, but must come after the 32 /* These are also core pieces, but must come after the
32 * core core pieces. 33 * core core pieces.
diff --git a/drivers/base/isa.c b/drivers/base/isa.c
new file mode 100644
index 000000000000..d2222397a401
--- /dev/null
+++ b/drivers/base/isa.c
@@ -0,0 +1,180 @@
1/*
2 * ISA bus.
3 */
4
5#include <linux/device.h>
6#include <linux/kernel.h>
7#include <linux/slab.h>
8#include <linux/module.h>
9#include <linux/init.h>
10#include <linux/isa.h>
11
12static struct device isa_bus = {
13 .bus_id = "isa"
14};
15
16struct isa_dev {
17 struct device dev;
18 struct device *next;
19 unsigned int id;
20};
21
22#define to_isa_dev(x) container_of((x), struct isa_dev, dev)
23
24static int isa_bus_match(struct device *dev, struct device_driver *driver)
25{
26 struct isa_driver *isa_driver = to_isa_driver(driver);
27
28 if (dev->platform_data == isa_driver) {
29 if (!isa_driver->match ||
30 isa_driver->match(dev, to_isa_dev(dev)->id))
31 return 1;
32 dev->platform_data = NULL;
33 }
34 return 0;
35}
36
37static int isa_bus_probe(struct device *dev)
38{
39 struct isa_driver *isa_driver = dev->platform_data;
40
41 if (isa_driver->probe)
42 return isa_driver->probe(dev, to_isa_dev(dev)->id);
43
44 return 0;
45}
46
47static int isa_bus_remove(struct device *dev)
48{
49 struct isa_driver *isa_driver = dev->platform_data;
50
51 if (isa_driver->remove)
52 return isa_driver->remove(dev, to_isa_dev(dev)->id);
53
54 return 0;
55}
56
57static void isa_bus_shutdown(struct device *dev)
58{
59 struct isa_driver *isa_driver = dev->platform_data;
60
61 if (isa_driver->shutdown)
62 isa_driver->shutdown(dev, to_isa_dev(dev)->id);
63}
64
65static int isa_bus_suspend(struct device *dev, pm_message_t state)
66{
67 struct isa_driver *isa_driver = dev->platform_data;
68
69 if (isa_driver->suspend)
70 return isa_driver->suspend(dev, to_isa_dev(dev)->id, state);
71
72 return 0;
73}
74
75static int isa_bus_resume(struct device *dev)
76{
77 struct isa_driver *isa_driver = dev->platform_data;
78
79 if (isa_driver->resume)
80 return isa_driver->resume(dev, to_isa_dev(dev)->id);
81
82 return 0;
83}
84
85static struct bus_type isa_bus_type = {
86 .name = "isa",
87 .match = isa_bus_match,
88 .probe = isa_bus_probe,
89 .remove = isa_bus_remove,
90 .shutdown = isa_bus_shutdown,
91 .suspend = isa_bus_suspend,
92 .resume = isa_bus_resume
93};
94
95static void isa_dev_release(struct device *dev)
96{
97 kfree(to_isa_dev(dev));
98}
99
100void isa_unregister_driver(struct isa_driver *isa_driver)
101{
102 struct device *dev = isa_driver->devices;
103
104 while (dev) {
105 struct device *tmp = to_isa_dev(dev)->next;
106 device_unregister(dev);
107 dev = tmp;
108 }
109 driver_unregister(&isa_driver->driver);
110}
111EXPORT_SYMBOL_GPL(isa_unregister_driver);
112
113int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev)
114{
115 int error;
116 unsigned int id;
117
118 isa_driver->driver.bus = &isa_bus_type;
119 isa_driver->devices = NULL;
120
121 error = driver_register(&isa_driver->driver);
122 if (error)
123 return error;
124
125 for (id = 0; id < ndev; id++) {
126 struct isa_dev *isa_dev;
127
128 isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL);
129 if (!isa_dev) {
130 error = -ENOMEM;
131 break;
132 }
133
134 isa_dev->dev.parent = &isa_bus;
135 isa_dev->dev.bus = &isa_bus_type;
136
137 snprintf(isa_dev->dev.bus_id, BUS_ID_SIZE, "%s.%u",
138 isa_driver->driver.name, id);
139
140 isa_dev->dev.platform_data = isa_driver;
141 isa_dev->dev.release = isa_dev_release;
142 isa_dev->id = id;
143
144 error = device_register(&isa_dev->dev);
145 if (error) {
146 put_device(&isa_dev->dev);
147 break;
148 }
149
150 if (isa_dev->dev.platform_data) {
151 isa_dev->next = isa_driver->devices;
152 isa_driver->devices = &isa_dev->dev;
153 } else
154 device_unregister(&isa_dev->dev);
155 }
156
157 if (!error && !isa_driver->devices)
158 error = -ENODEV;
159
160 if (error)
161 isa_unregister_driver(isa_driver);
162
163 return error;
164}
165EXPORT_SYMBOL_GPL(isa_register_driver);
166
167static int __init isa_bus_init(void)
168{
169 int error;
170
171 error = bus_register(&isa_bus_type);
172 if (!error) {
173 error = device_register(&isa_bus);
174 if (error)
175 bus_unregister(&isa_bus_type);
176 }
177 return error;
178}
179
180device_initcall(isa_bus_init);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 83f5c5984d1a..2b8755db76c6 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -275,7 +275,7 @@ int platform_device_add(struct platform_device *pdev)
275 pr_debug("Registering platform device '%s'. Parent at %s\n", 275 pr_debug("Registering platform device '%s'. Parent at %s\n",
276 pdev->dev.bus_id, pdev->dev.parent->bus_id); 276 pdev->dev.bus_id, pdev->dev.parent->bus_id);
277 277
278 ret = device_register(&pdev->dev); 278 ret = device_add(&pdev->dev);
279 if (ret == 0) 279 if (ret == 0)
280 return ret; 280 return ret;
281 281
@@ -452,6 +452,37 @@ void platform_driver_unregister(struct platform_driver *drv)
452EXPORT_SYMBOL_GPL(platform_driver_unregister); 452EXPORT_SYMBOL_GPL(platform_driver_unregister);
453 453
454 454
455/* modalias support enables more hands-off userspace setup:
456 * (a) environment variable lets new-style hotplug events work once system is
457 * fully running: "modprobe $MODALIAS"
458 * (b) sysfs attribute lets new-style coldplug recover from hotplug events
459 * mishandled before system is fully running: "modprobe $(cat modalias)"
460 */
461static ssize_t
462modalias_show(struct device *dev, struct device_attribute *a, char *buf)
463{
464 struct platform_device *pdev = to_platform_device(dev);
465 int len = snprintf(buf, PAGE_SIZE, "%s\n", pdev->name);
466
467 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
468}
469
470static struct device_attribute platform_dev_attrs[] = {
471 __ATTR_RO(modalias),
472 __ATTR_NULL,
473};
474
475static int platform_uevent(struct device *dev, char **envp, int num_envp,
476 char *buffer, int buffer_size)
477{
478 struct platform_device *pdev = to_platform_device(dev);
479
480 envp[0] = buffer;
481 snprintf(buffer, buffer_size, "MODALIAS=%s", pdev->name);
482 return 0;
483}
484
485
455/** 486/**
456 * platform_match - bind platform device to platform driver. 487 * platform_match - bind platform device to platform driver.
457 * @dev: device. 488 * @dev: device.
@@ -496,7 +527,9 @@ static int platform_resume(struct device * dev)
496 527
497struct bus_type platform_bus_type = { 528struct bus_type platform_bus_type = {
498 .name = "platform", 529 .name = "platform",
530 .dev_attrs = platform_dev_attrs,
499 .match = platform_match, 531 .match = platform_match,
532 .uevent = platform_uevent,
500 .suspend = platform_suspend, 533 .suspend = platform_suspend,
501 .resume = platform_resume, 534 .resume = platform_resume,
502}; 535};
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile
index c0219ad94aca..ceeeba2c56c7 100644
--- a/drivers/base/power/Makefile
+++ b/drivers/base/power/Makefile
@@ -4,3 +4,6 @@ obj-$(CONFIG_PM) += main.o suspend.o resume.o runtime.o sysfs.o
4ifeq ($(CONFIG_DEBUG_DRIVER),y) 4ifeq ($(CONFIG_DEBUG_DRIVER),y)
5EXTRA_CFLAGS += -DDEBUG 5EXTRA_CFLAGS += -DDEBUG
6endif 6endif
7ifeq ($(CONFIG_PM_DEBUG),y)
8EXTRA_CFLAGS += -DDEBUG
9endif
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index 2a769cc6f5f9..1a1fe43a3057 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -29,6 +29,15 @@
29 * lists. This way, the ancestors will be accessed before their descendents. 29 * lists. This way, the ancestors will be accessed before their descendents.
30 */ 30 */
31 31
32static inline char *suspend_verb(u32 event)
33{
34 switch (event) {
35 case PM_EVENT_SUSPEND: return "suspend";
36 case PM_EVENT_FREEZE: return "freeze";
37 default: return "(unknown suspend event)";
38 }
39}
40
32 41
33/** 42/**
34 * suspend_device - Save state of one device. 43 * suspend_device - Save state of one device.
@@ -57,7 +66,13 @@ int suspend_device(struct device * dev, pm_message_t state)
57 dev->power.prev_state = dev->power.power_state; 66 dev->power.prev_state = dev->power.power_state;
58 67
59 if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) { 68 if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) {
60 dev_dbg(dev, "suspending\n"); 69 dev_dbg(dev, "%s%s\n",
70 suspend_verb(state.event),
71 ((state.event == PM_EVENT_SUSPEND)
72 && device_may_wakeup(dev))
73 ? ", may wakeup"
74 : ""
75 );
61 error = dev->bus->suspend(dev, state); 76 error = dev->bus->suspend(dev, state);
62 suspend_report_result(dev->bus->suspend, error); 77 suspend_report_result(dev->bus->suspend, error);
63 } 78 }
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 6fc23ab127bd..6858178b3aff 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -80,10 +80,59 @@ void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a)
80EXPORT_SYMBOL_GPL(sysdev_create_file); 80EXPORT_SYMBOL_GPL(sysdev_create_file);
81EXPORT_SYMBOL_GPL(sysdev_remove_file); 81EXPORT_SYMBOL_GPL(sysdev_remove_file);
82 82
83#define to_sysdev_class(k) container_of(k, struct sysdev_class, kset.kobj)
84#define to_sysdev_class_attr(a) container_of(a, \
85 struct sysdev_class_attribute, attr)
86
87static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
88 char *buffer)
89{
90 struct sysdev_class * class = to_sysdev_class(kobj);
91 struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
92
93 if (class_attr->show)
94 return class_attr->show(class, buffer);
95 return -EIO;
96}
97
98static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr,
99 const char *buffer, size_t count)
100{
101 struct sysdev_class * class = to_sysdev_class(kobj);
102 struct sysdev_class_attribute * class_attr = to_sysdev_class_attr(attr);
103
104 if (class_attr->store)
105 return class_attr->store(class, buffer, count);
106 return -EIO;
107}
108
109static struct sysfs_ops sysfs_class_ops = {
110 .show = sysdev_class_show,
111 .store = sysdev_class_store,
112};
113
114static struct kobj_type ktype_sysdev_class = {
115 .sysfs_ops = &sysfs_class_ops,
116};
117
118int sysdev_class_create_file(struct sysdev_class *c,
119 struct sysdev_class_attribute *a)
120{
121 return sysfs_create_file(&c->kset.kobj, &a->attr);
122}
123EXPORT_SYMBOL_GPL(sysdev_class_create_file);
124
125void sysdev_class_remove_file(struct sysdev_class *c,
126 struct sysdev_class_attribute *a)
127{
128 sysfs_remove_file(&c->kset.kobj, &a->attr);
129}
130EXPORT_SYMBOL_GPL(sysdev_class_remove_file);
131
83/* 132/*
84 * declare system_subsys 133 * declare system_subsys
85 */ 134 */
86static decl_subsys(system, &ktype_sysdev, NULL); 135static decl_subsys(system, &ktype_sysdev_class, NULL);
87 136
88int sysdev_class_register(struct sysdev_class * cls) 137int sysdev_class_register(struct sysdev_class * cls)
89{ 138{
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 1319d8f20640..25c3c4a5da81 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3237,6 +3237,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
3237 disk->fops = &cciss_fops; 3237 disk->fops = &cciss_fops;
3238 disk->queue = q; 3238 disk->queue = q;
3239 disk->private_data = drv; 3239 disk->private_data = drv;
3240 disk->driverfs_dev = &pdev->dev;
3240 /* we must register the controller even if no disks exist */ 3241 /* we must register the controller even if no disks exist */
3241 /* this is for the online array utilities */ 3242 /* this is for the online array utilities */
3242 if(!drv->heads && j) 3243 if(!drv->heads && j)
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index c688c25992e4..60e9a9457c6b 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -10,17 +10,13 @@
10 * TODO (sorted by decreasing priority) 10 * TODO (sorted by decreasing priority)
11 * -- set readonly flag for CDs, set removable flag for CF readers 11 * -- set readonly flag for CDs, set removable flag for CF readers
12 * -- do inquiry and verify we got a disk and not a tape (for LUN mismatch) 12 * -- do inquiry and verify we got a disk and not a tape (for LUN mismatch)
13 * -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
14 * -- verify the 13 conditions and do bulk resets 13 * -- verify the 13 conditions and do bulk resets
15 * -- kill last_pipe and simply do two-state clearing on both pipes
16 * -- highmem 14 * -- highmem
17 * -- move top_sense and work_bcs into separate allocations (if they survive) 15 * -- move top_sense and work_bcs into separate allocations (if they survive)
18 * for cache purists and esoteric architectures. 16 * for cache purists and esoteric architectures.
19 * -- Allocate structure for LUN 0 before the first ub_sync_tur, avoid NULL. ? 17 * -- Allocate structure for LUN 0 before the first ub_sync_tur, avoid NULL. ?
20 * -- prune comments, they are too volumnous 18 * -- prune comments, they are too volumnous
21 * -- Exterminate P3 printks
22 * -- Resove XXX's 19 * -- Resove XXX's
23 * -- Redo "benh's retries", perhaps have spin-up code to handle them. V:D=?
24 * -- CLEAR, CLR2STS, CLRRS seem to be ripe for refactoring. 20 * -- CLEAR, CLR2STS, CLRRS seem to be ripe for refactoring.
25 */ 21 */
26#include <linux/kernel.h> 22#include <linux/kernel.h>
@@ -180,7 +176,6 @@ struct ub_dev;
180#define UB_DIR_ILLEGAL2 2 176#define UB_DIR_ILLEGAL2 2
181#define UB_DIR_WRITE 3 177#define UB_DIR_WRITE 3
182 178
183/* P3 */
184#define UB_DIR_CHAR(c) (((c)==UB_DIR_WRITE)? 'w': \ 179#define UB_DIR_CHAR(c) (((c)==UB_DIR_WRITE)? 'w': \
185 (((c)==UB_DIR_READ)? 'r': 'n')) 180 (((c)==UB_DIR_READ)? 'r': 'n'))
186 181
@@ -669,8 +664,9 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
669 */ 664 */
670 n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]); 665 n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]);
671 if (n_elem < 0) { 666 if (n_elem < 0) {
667 /* Impossible, because blk_rq_map_sg should not hit ENOMEM. */
672 printk(KERN_INFO "%s: failed request map (%d)\n", 668 printk(KERN_INFO "%s: failed request map (%d)\n",
673 lun->name, n_elem); /* P3 */ 669 lun->name, n_elem);
674 goto drop; 670 goto drop;
675 } 671 }
676 if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */ 672 if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */
@@ -824,7 +820,9 @@ static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
824 if (urq->current_try >= 3) 820 if (urq->current_try >= 3)
825 return -EIO; 821 return -EIO;
826 urq->current_try++; 822 urq->current_try++;
827 /* P3 */ printk("%s: dir %c len/act %d/%d " 823
824 /* Remove this if anyone complains of flooding. */
825 printk(KERN_DEBUG "%s: dir %c len/act %d/%d "
828 "[sense %x %02x %02x] retry %d\n", 826 "[sense %x %02x %02x] retry %d\n",
829 sc->name, UB_DIR_CHAR(cmd->dir), cmd->len, cmd->act_len, 827 sc->name, UB_DIR_CHAR(cmd->dir), cmd->len, cmd->act_len,
830 cmd->key, cmd->asc, cmd->ascq, urq->current_try); 828 cmd->key, cmd->asc, cmd->ascq, urq->current_try);
@@ -1241,8 +1239,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
1241 * to check. But it's not all right if the device 1239 * to check. But it's not all right if the device
1242 * counts disagree with our counts. 1240 * counts disagree with our counts.
1243 */ 1241 */
1244 /* P3 */ printk("%s: resid %d len %d act %d\n",
1245 sc->name, len, cmd->len, cmd->act_len);
1246 goto Bad_End; 1242 goto Bad_End;
1247 } 1243 }
1248 1244
@@ -1253,7 +1249,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
1253 ub_state_sense(sc, cmd); 1249 ub_state_sense(sc, cmd);
1254 return; 1250 return;
1255 case US_BULK_STAT_PHASE: 1251 case US_BULK_STAT_PHASE:
1256 /* P3 */ printk("%s: status PHASE\n", sc->name);
1257 goto Bad_End; 1252 goto Bad_End;
1258 default: 1253 default:
1259 printk(KERN_INFO "%s: unknown CSW status 0x%x\n", 1254 printk(KERN_INFO "%s: unknown CSW status 0x%x\n",
@@ -1568,16 +1563,14 @@ static void ub_reset_task(void *arg)
1568 } 1563 }
1569 1564
1570 if (atomic_read(&sc->poison)) { 1565 if (atomic_read(&sc->poison)) {
1571 printk(KERN_NOTICE "%s: Not resetting disconnected device\n", 1566 ;
1572 sc->name); /* P3 This floods. Remove soon. XXX */
1573 } else if ((sc->reset & 1) == 0) { 1567 } else if ((sc->reset & 1) == 0) {
1574 ub_sync_reset(sc); 1568 ub_sync_reset(sc);
1575 msleep(700); /* usb-storage sleeps 6s (!) */ 1569 msleep(700); /* usb-storage sleeps 6s (!) */
1576 ub_probe_clear_stall(sc, sc->recv_bulk_pipe); 1570 ub_probe_clear_stall(sc, sc->recv_bulk_pipe);
1577 ub_probe_clear_stall(sc, sc->send_bulk_pipe); 1571 ub_probe_clear_stall(sc, sc->send_bulk_pipe);
1578 } else if (sc->dev->actconfig->desc.bNumInterfaces != 1) { 1572 } else if (sc->dev->actconfig->desc.bNumInterfaces != 1) {
1579 printk(KERN_NOTICE "%s: Not resetting multi-interface device\n", 1573 ;
1580 sc->name); /* P3 This floods. Remove soon. XXX */
1581 } else { 1574 } else {
1582 if ((lkr = usb_lock_device_for_reset(sc->dev, sc->intf)) < 0) { 1575 if ((lkr = usb_lock_device_for_reset(sc->dev, sc->intf)) < 0) {
1583 printk(KERN_NOTICE 1576 printk(KERN_NOTICE
@@ -1651,15 +1644,11 @@ static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun)
1651static int ub_bd_open(struct inode *inode, struct file *filp) 1644static int ub_bd_open(struct inode *inode, struct file *filp)
1652{ 1645{
1653 struct gendisk *disk = inode->i_bdev->bd_disk; 1646 struct gendisk *disk = inode->i_bdev->bd_disk;
1654 struct ub_lun *lun; 1647 struct ub_lun *lun = disk->private_data;
1655 struct ub_dev *sc; 1648 struct ub_dev *sc = lun->udev;
1656 unsigned long flags; 1649 unsigned long flags;
1657 int rc; 1650 int rc;
1658 1651
1659 if ((lun = disk->private_data) == NULL)
1660 return -ENXIO;
1661 sc = lun->udev;
1662
1663 spin_lock_irqsave(&ub_lock, flags); 1652 spin_lock_irqsave(&ub_lock, flags);
1664 if (atomic_read(&sc->poison)) { 1653 if (atomic_read(&sc->poison)) {
1665 spin_unlock_irqrestore(&ub_lock, flags); 1654 spin_unlock_irqrestore(&ub_lock, flags);
@@ -1823,10 +1812,8 @@ static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun)
1823 rc = ub_submit_scsi(sc, cmd); 1812 rc = ub_submit_scsi(sc, cmd);
1824 spin_unlock_irqrestore(sc->lock, flags); 1813 spin_unlock_irqrestore(sc->lock, flags);
1825 1814
1826 if (rc != 0) { 1815 if (rc != 0)
1827 printk("ub: testing ready: submit error (%d)\n", rc); /* P3 */
1828 goto err_submit; 1816 goto err_submit;
1829 }
1830 1817
1831 wait_for_completion(&compl); 1818 wait_for_completion(&compl);
1832 1819
@@ -1884,20 +1871,16 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
1884 rc = ub_submit_scsi(sc, cmd); 1871 rc = ub_submit_scsi(sc, cmd);
1885 spin_unlock_irqrestore(sc->lock, flags); 1872 spin_unlock_irqrestore(sc->lock, flags);
1886 1873
1887 if (rc != 0) { 1874 if (rc != 0)
1888 printk("ub: reading capacity: submit error (%d)\n", rc); /* P3 */
1889 goto err_submit; 1875 goto err_submit;
1890 }
1891 1876
1892 wait_for_completion(&compl); 1877 wait_for_completion(&compl);
1893 1878
1894 if (cmd->error != 0) { 1879 if (cmd->error != 0) {
1895 printk("ub: reading capacity: error %d\n", cmd->error); /* P3 */
1896 rc = -EIO; 1880 rc = -EIO;
1897 goto err_read; 1881 goto err_read;
1898 } 1882 }
1899 if (cmd->act_len != 8) { 1883 if (cmd->act_len != 8) {
1900 printk("ub: reading capacity: size %d\n", cmd->act_len); /* P3 */
1901 rc = -EIO; 1884 rc = -EIO;
1902 goto err_read; 1885 goto err_read;
1903 } 1886 }
@@ -1911,7 +1894,6 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
1911 case 2048: shift = 2; break; 1894 case 2048: shift = 2; break;
1912 case 4096: shift = 3; break; 1895 case 4096: shift = 3; break;
1913 default: 1896 default:
1914 printk("ub: Bad sector size %u\n", bsize); /* P3 */
1915 rc = -EDOM; 1897 rc = -EDOM;
1916 goto err_inv_bsize; 1898 goto err_inv_bsize;
1917 } 1899 }
@@ -2023,17 +2005,8 @@ static int ub_sync_getmaxlun(struct ub_dev *sc)
2023 sc->work_urb.error_count = 0; 2005 sc->work_urb.error_count = 0;
2024 sc->work_urb.status = 0; 2006 sc->work_urb.status = 0;
2025 2007
2026 if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { 2008 if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0)
2027 if (rc == -EPIPE) {
2028 printk("%s: Stall submitting GetMaxLUN, using 1 LUN\n",
2029 sc->name); /* P3 */
2030 } else {
2031 printk(KERN_NOTICE
2032 "%s: Unable to submit GetMaxLUN (%d)\n",
2033 sc->name, rc);
2034 }
2035 goto err_submit; 2009 goto err_submit;
2036 }
2037 2010
2038 init_timer(&timer); 2011 init_timer(&timer);
2039 timer.function = ub_probe_timeout; 2012 timer.function = ub_probe_timeout;
@@ -2046,21 +2019,10 @@ static int ub_sync_getmaxlun(struct ub_dev *sc)
2046 del_timer_sync(&timer); 2019 del_timer_sync(&timer);
2047 usb_kill_urb(&sc->work_urb); 2020 usb_kill_urb(&sc->work_urb);
2048 2021
2049 if ((rc = sc->work_urb.status) < 0) { 2022 if ((rc = sc->work_urb.status) < 0)
2050 if (rc == -EPIPE) {
2051 printk("%s: Stall at GetMaxLUN, using 1 LUN\n",
2052 sc->name); /* P3 */
2053 } else {
2054 printk(KERN_NOTICE
2055 "%s: Error at GetMaxLUN (%d)\n",
2056 sc->name, rc);
2057 }
2058 goto err_io; 2023 goto err_io;
2059 }
2060 2024
2061 if (sc->work_urb.actual_length != 1) { 2025 if (sc->work_urb.actual_length != 1) {
2062 printk("%s: GetMaxLUN returned %d bytes\n", sc->name,
2063 sc->work_urb.actual_length); /* P3 */
2064 nluns = 0; 2026 nluns = 0;
2065 } else { 2027 } else {
2066 if ((nluns = *p) == 55) { 2028 if ((nluns = *p) == 55) {
@@ -2071,8 +2033,6 @@ static int ub_sync_getmaxlun(struct ub_dev *sc)
2071 if (nluns > UB_MAX_LUNS) 2033 if (nluns > UB_MAX_LUNS)
2072 nluns = UB_MAX_LUNS; 2034 nluns = UB_MAX_LUNS;
2073 } 2035 }
2074 printk("%s: GetMaxLUN returned %d, using %d LUNs\n", sc->name,
2075 *p, nluns); /* P3 */
2076 } 2036 }
2077 2037
2078 kfree(p); 2038 kfree(p);
@@ -2270,7 +2230,7 @@ static int ub_probe(struct usb_interface *intf,
2270 * has to succeed, so we clear checks with an additional one here. 2230 * has to succeed, so we clear checks with an additional one here.
2271 * In any case it's not our business how revaliadation is implemented. 2231 * In any case it's not our business how revaliadation is implemented.
2272 */ 2232 */
2273 for (i = 0; i < 3; i++) { /* Retries for benh's key */ 2233 for (i = 0; i < 3; i++) { /* Retries for the schwag key from KS'04 */
2274 if ((rc = ub_sync_tur(sc, NULL)) <= 0) break; 2234 if ((rc = ub_sync_tur(sc, NULL)) <= 0) break;
2275 if (rc != 0x6) break; 2235 if (rc != 0x6) break;
2276 msleep(10); 2236 msleep(10);
@@ -2318,7 +2278,6 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
2318 goto err_id; 2278 goto err_id;
2319 2279
2320 lun->udev = sc; 2280 lun->udev = sc;
2321 list_add(&lun->link, &sc->luns);
2322 2281
2323 snprintf(lun->name, 16, DRV_NAME "%c(%d.%d.%d)", 2282 snprintf(lun->name, 16, DRV_NAME "%c(%d.%d.%d)",
2324 lun->id + 'a', sc->dev->bus->busnum, sc->dev->devnum, lun->num); 2283 lun->id + 'a', sc->dev->bus->busnum, sc->dev->devnum, lun->num);
@@ -2331,7 +2290,6 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
2331 if ((disk = alloc_disk(UB_PARTS_PER_LUN)) == NULL) 2290 if ((disk = alloc_disk(UB_PARTS_PER_LUN)) == NULL)
2332 goto err_diskalloc; 2291 goto err_diskalloc;
2333 2292
2334 lun->disk = disk;
2335 sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); 2293 sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a');
2336 sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a'); 2294 sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a');
2337 disk->major = UB_MAJOR; 2295 disk->major = UB_MAJOR;
@@ -2353,7 +2311,9 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
2353 blk_queue_max_sectors(q, UB_MAX_SECTORS); 2311 blk_queue_max_sectors(q, UB_MAX_SECTORS);
2354 blk_queue_hardsect_size(q, lun->capacity.bsize); 2312 blk_queue_hardsect_size(q, lun->capacity.bsize);
2355 2313
2314 lun->disk = disk;
2356 q->queuedata = lun; 2315 q->queuedata = lun;
2316 list_add(&lun->link, &sc->luns);
2357 2317
2358 set_capacity(disk, lun->capacity.nsec); 2318 set_capacity(disk, lun->capacity.nsec);
2359 if (lun->removable) 2319 if (lun->removable)
@@ -2366,7 +2326,6 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
2366err_blkqinit: 2326err_blkqinit:
2367 put_disk(disk); 2327 put_disk(disk);
2368err_diskalloc: 2328err_diskalloc:
2369 list_del(&lun->link);
2370 ub_id_put(lun->id); 2329 ub_id_put(lun->id);
2371err_id: 2330err_id:
2372 kfree(lun); 2331 kfree(lun);
@@ -2379,7 +2338,6 @@ static void ub_disconnect(struct usb_interface *intf)
2379 struct ub_dev *sc = usb_get_intfdata(intf); 2338 struct ub_dev *sc = usb_get_intfdata(intf);
2380 struct list_head *p; 2339 struct list_head *p;
2381 struct ub_lun *lun; 2340 struct ub_lun *lun;
2382 struct gendisk *disk;
2383 unsigned long flags; 2341 unsigned long flags;
2384 2342
2385 /* 2343 /*
@@ -2435,9 +2393,7 @@ static void ub_disconnect(struct usb_interface *intf)
2435 */ 2393 */
2436 list_for_each (p, &sc->luns) { 2394 list_for_each (p, &sc->luns) {
2437 lun = list_entry(p, struct ub_lun, link); 2395 lun = list_entry(p, struct ub_lun, link);
2438 disk = lun->disk; 2396 del_gendisk(lun->disk);
2439 if (disk->flags & GENHD_FL_UP)
2440 del_gendisk(disk);
2441 /* 2397 /*
2442 * I wish I could do: 2398 * I wish I could do:
2443 * set_bit(QUEUE_FLAG_DEAD, &q->queue_flags); 2399 * set_bit(QUEUE_FLAG_DEAD, &q->queue_flags);
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index 7c88c060a9e6..46685a540772 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -1,7 +1,6 @@
1config AGP 1config AGP
2 tristate "/dev/agpgart (AGP Support)" if !GART_IOMMU 2 tristate "/dev/agpgart (AGP Support)"
3 depends on ALPHA || IA64 || PPC || X86 3 depends on ALPHA || IA64 || PPC || X86
4 default y if GART_IOMMU
5 ---help--- 4 ---help---
6 AGP (Accelerated Graphics Port) is a bus system mainly used to 5 AGP (Accelerated Graphics Port) is a bus system mainly used to
7 connect graphics cards to the rest of the system. 6 connect graphics cards to the rest of the system.
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index a88b94a82b14..8b2a59969868 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2961,12 +2961,14 @@ static struct class *tty_class;
2961 * This field is optional, if there is no known struct device for this 2961 * This field is optional, if there is no known struct device for this
2962 * tty device it can be set to NULL safely. 2962 * tty device it can be set to NULL safely.
2963 * 2963 *
2964 * Returns a pointer to the class device (or ERR_PTR(-EFOO) on error).
2965 *
2964 * This call is required to be made to register an individual tty device if 2966 * This call is required to be made to register an individual tty device if
2965 * the tty driver's flags have the TTY_DRIVER_NO_DEVFS bit set. If that 2967 * the tty driver's flags have the TTY_DRIVER_NO_DEVFS bit set. If that
2966 * bit is not set, this function should not be called. 2968 * bit is not set, this function should not be called.
2967 */ 2969 */
2968void tty_register_device(struct tty_driver *driver, unsigned index, 2970struct class_device *tty_register_device(struct tty_driver *driver,
2969 struct device *device) 2971 unsigned index, struct device *device)
2970{ 2972{
2971 char name[64]; 2973 char name[64];
2972 dev_t dev = MKDEV(driver->major, driver->minor_start) + index; 2974 dev_t dev = MKDEV(driver->major, driver->minor_start) + index;
@@ -2974,7 +2976,7 @@ void tty_register_device(struct tty_driver *driver, unsigned index,
2974 if (index >= driver->num) { 2976 if (index >= driver->num) {
2975 printk(KERN_ERR "Attempt to register invalid tty line number " 2977 printk(KERN_ERR "Attempt to register invalid tty line number "
2976 " (%d).\n", index); 2978 " (%d).\n", index);
2977 return; 2979 return ERR_PTR(-EINVAL);
2978 } 2980 }
2979 2981
2980 devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR, 2982 devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
@@ -2984,7 +2986,8 @@ void tty_register_device(struct tty_driver *driver, unsigned index,
2984 pty_line_name(driver, index, name); 2986 pty_line_name(driver, index, name);
2985 else 2987 else
2986 tty_line_name(driver, index, name); 2988 tty_line_name(driver, index, name);
2987 class_device_create(tty_class, NULL, dev, device, "%s", name); 2989
2990 return class_device_create(tty_class, NULL, dev, device, "%s", name);
2988} 2991}
2989 2992
2990/** 2993/**
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index e55767b2ccd3..acb7e2656780 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -460,6 +460,9 @@ void gigaset_freecs(struct cardstate *cs)
460 460
461 switch (cs->cs_init) { 461 switch (cs->cs_init) {
462 default: 462 default:
463 /* clear device sysfs */
464 gigaset_free_dev_sysfs(cs);
465
463 gigaset_if_free(cs); 466 gigaset_if_free(cs);
464 467
465 gig_dbg(DEBUG_INIT, "clearing hw"); 468 gig_dbg(DEBUG_INIT, "clearing hw");
@@ -699,6 +702,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
699 cs->open_count = 0; 702 cs->open_count = 0;
700 cs->dev = NULL; 703 cs->dev = NULL;
701 cs->tty = NULL; 704 cs->tty = NULL;
705 cs->class = NULL;
702 cs->cidmode = cidmode != 0; 706 cs->cidmode = cidmode != 0;
703 707
704 //if(onechannel) { //FIXME 708 //if(onechannel) { //FIXME
@@ -760,6 +764,9 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
760 764
761 gigaset_if_init(cs); 765 gigaset_if_init(cs);
762 766
767 /* set up device sysfs */
768 gigaset_init_dev_sysfs(cs);
769
763 spin_lock_irqsave(&cs->lock, flags); 770 spin_lock_irqsave(&cs->lock, flags);
764 cs->running = 1; 771 cs->running = 1;
765 spin_unlock_irqrestore(&cs->lock, flags); 772 spin_unlock_irqrestore(&cs->lock, flags);
@@ -902,9 +909,6 @@ int gigaset_start(struct cardstate *cs)
902 909
903 wait_event(cs->waitqueue, !cs->waiting); 910 wait_event(cs->waitqueue, !cs->waiting);
904 911
905 /* set up device sysfs */
906 gigaset_init_dev_sysfs(cs);
907
908 mutex_unlock(&cs->mutex); 912 mutex_unlock(&cs->mutex);
909 return 1; 913 return 1;
910 914
@@ -969,9 +973,6 @@ void gigaset_stop(struct cardstate *cs)
969 //FIXME 973 //FIXME
970 } 974 }
971 975
972 /* clear device sysfs */
973 gigaset_free_dev_sysfs(cs);
974
975 cleanup_cs(cs); 976 cleanup_cs(cs);
976 977
977exit: 978exit:
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index 22b9693f7c0a..8d63d822104f 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -445,6 +445,7 @@ struct cardstate {
445 struct gigaset_driver *driver; 445 struct gigaset_driver *driver;
446 unsigned minor_index; 446 unsigned minor_index;
447 struct device *dev; 447 struct device *dev;
448 struct class_device *class;
448 449
449 const struct gigaset_ops *ops; 450 const struct gigaset_ops *ops;
450 451
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index 08e4c4eea14d..74fd234956c8 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -625,7 +625,14 @@ void gigaset_if_init(struct cardstate *cs)
625 return; 625 return;
626 626
627 tasklet_init(&cs->if_wake_tasklet, &if_wake, (unsigned long) cs); 627 tasklet_init(&cs->if_wake_tasklet, &if_wake, (unsigned long) cs);
628 tty_register_device(drv->tty, cs->minor_index, NULL); 628 cs->class = tty_register_device(drv->tty, cs->minor_index, NULL);
629
630 if (!IS_ERR(cs->class))
631 class_set_devdata(cs->class, cs);
632 else {
633 warn("could not register device to the tty subsystem");
634 cs->class = NULL;
635 }
629} 636}
630 637
631void gigaset_if_free(struct cardstate *cs) 638void gigaset_if_free(struct cardstate *cs)
@@ -638,6 +645,7 @@ void gigaset_if_free(struct cardstate *cs)
638 645
639 tasklet_disable(&cs->if_wake_tasklet); 646 tasklet_disable(&cs->if_wake_tasklet);
640 tasklet_kill(&cs->if_wake_tasklet); 647 tasklet_kill(&cs->if_wake_tasklet);
648 cs->class = NULL;
641 tty_unregister_device(drv->tty, cs->minor_index); 649 tty_unregister_device(drv->tty, cs->minor_index);
642} 650}
643 651
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c
index d267a636b53c..9ae3a7f3e7b3 100644
--- a/drivers/isdn/gigaset/proc.c
+++ b/drivers/isdn/gigaset/proc.c
@@ -16,12 +16,11 @@
16#include "gigaset.h" 16#include "gigaset.h"
17#include <linux/ctype.h> 17#include <linux/ctype.h>
18 18
19static ssize_t show_cidmode(struct device *dev, struct device_attribute *attr, 19static ssize_t show_cidmode(struct class_device *class, char *buf)
20 char *buf)
21{ 20{
22 int ret; 21 int ret;
23 unsigned long flags; 22 unsigned long flags;
24 struct cardstate *cs = dev_get_drvdata(dev); 23 struct cardstate *cs = class_get_devdata(class);
25 24
26 spin_lock_irqsave(&cs->lock, flags); 25 spin_lock_irqsave(&cs->lock, flags);
27 ret = sprintf(buf, "%u\n", cs->cidmode); 26 ret = sprintf(buf, "%u\n", cs->cidmode);
@@ -30,10 +29,10 @@ static ssize_t show_cidmode(struct device *dev, struct device_attribute *attr,
30 return ret; 29 return ret;
31} 30}
32 31
33static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, 32static ssize_t set_cidmode(struct class_device *class,
34 const char *buf, size_t count) 33 const char *buf, size_t count)
35{ 34{
36 struct cardstate *cs = dev_get_drvdata(dev); 35 struct cardstate *cs = class_get_devdata(class);
37 long int value; 36 long int value;
38 char *end; 37 char *end;
39 38
@@ -65,18 +64,24 @@ static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr,
65 return count; 64 return count;
66} 65}
67 66
68static DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); 67static CLASS_DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode);
69 68
70/* free sysfs for device */ 69/* free sysfs for device */
71void gigaset_free_dev_sysfs(struct cardstate *cs) 70void gigaset_free_dev_sysfs(struct cardstate *cs)
72{ 71{
72 if (!cs->class)
73 return;
74
73 gig_dbg(DEBUG_INIT, "removing sysfs entries"); 75 gig_dbg(DEBUG_INIT, "removing sysfs entries");
74 device_remove_file(cs->dev, &dev_attr_cidmode); 76 class_device_remove_file(cs->class, &class_device_attr_cidmode);
75} 77}
76 78
77/* initialize sysfs for device */ 79/* initialize sysfs for device */
78void gigaset_init_dev_sysfs(struct cardstate *cs) 80void gigaset_init_dev_sysfs(struct cardstate *cs)
79{ 81{
82 if (!cs->class)
83 return;
84
80 gig_dbg(DEBUG_INIT, "setting up sysfs"); 85 gig_dbg(DEBUG_INIT, "setting up sysfs");
81 device_create_file(cs->dev, &dev_attr_cidmode); 86 class_device_create_file(cs->class, &class_device_attr_cidmode);
82} 87}
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
index c11f5d46b114..6f31ecc88843 100644
--- a/drivers/media/video/usbvideo/konicawc.c
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -15,8 +15,7 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/input.h> 18#include <linux/usb/input.h>
19#include <linux/usb_input.h>
20 19
21#include "usbvideo.h" 20#include "usbvideo.h"
22 21
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index e1feb58bd661..1a2b9785e998 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -2120,7 +2120,7 @@ abort_linearize:
2120 goto drop; 2120 goto drop;
2121 } 2121 }
2122 2122
2123 if (skb_linearize(skb, GFP_ATOMIC)) 2123 if (skb_linearize(skb))
2124 goto drop; 2124 goto drop;
2125 2125
2126 mgp->tx_linearized++; 2126 mgp->tx_linearized++;
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 9b7d9769fdcc..c7123bf71c58 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/
48obj-$(CONFIG_USB_SERIAL) += serial/ 48obj-$(CONFIG_USB_SERIAL) += serial/
49 49
50obj-$(CONFIG_USB_AUERSWALD) += misc/ 50obj-$(CONFIG_USB_AUERSWALD) += misc/
51obj-$(CONFIG_USB_CY7C63) += misc/
51obj-$(CONFIG_USB_CYTHERM) += misc/ 52obj-$(CONFIG_USB_CYTHERM) += misc/
52obj-$(CONFIG_USB_EMI26) += misc/ 53obj-$(CONFIG_USB_EMI26) += misc/
53obj-$(CONFIG_USB_EMI62) += misc/ 54obj-$(CONFIG_USB_EMI62) += misc/
@@ -61,6 +62,7 @@ obj-$(CONFIG_USB_TEST) += misc/
61obj-$(CONFIG_USB_USS720) += misc/ 62obj-$(CONFIG_USB_USS720) += misc/
62obj-$(CONFIG_USB_PHIDGETSERVO) += misc/ 63obj-$(CONFIG_USB_PHIDGETSERVO) += misc/
63obj-$(CONFIG_USB_SISUSBVGA) += misc/ 64obj-$(CONFIG_USB_SISUSBVGA) += misc/
65obj-$(CONFIG_USB_APPLEDISPLAY) += misc/
64 66
65obj-$(CONFIG_USB_ATM) += atm/ 67obj-$(CONFIG_USB_ATM) += atm/
66obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ 68obj-$(CONFIG_USB_SPEEDTOUCH) += atm/
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index 546249843b8e..a38701c742c3 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -1039,7 +1039,7 @@ static void usbatm_tasklet_schedule(unsigned long data)
1039 tasklet_schedule((struct tasklet_struct *) data); 1039 tasklet_schedule((struct tasklet_struct *) data);
1040} 1040}
1041 1041
1042static inline void usbatm_init_channel(struct usbatm_channel *channel) 1042static void usbatm_init_channel(struct usbatm_channel *channel)
1043{ 1043{
1044 spin_lock_init(&channel->lock); 1044 spin_lock_init(&channel->lock);
1045 INIT_LIST_HEAD(&channel->list); 1045 INIT_LIST_HEAD(&channel->list);
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c
index 42d6823b82b3..70125c6d3be4 100644
--- a/drivers/usb/atm/xusbatm.c
+++ b/drivers/usb/atm/xusbatm.c
@@ -20,7 +20,6 @@
20 ******************************************************************************/ 20 ******************************************************************************/
21 21
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/netdevice.h> /* FIXME: required by linux/etherdevice.h */
24#include <linux/etherdevice.h> /* for random_ether_addr() */ 23#include <linux/etherdevice.h> /* for random_ether_addr() */
25 24
26#include "usbatm.h" 25#include "usbatm.h"
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 6dd339f4c0fc..d41dc67ba4cc 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -63,7 +63,7 @@
63#include <linux/mutex.h> 63#include <linux/mutex.h>
64#include <asm/uaccess.h> 64#include <asm/uaccess.h>
65#include <linux/usb.h> 65#include <linux/usb.h>
66#include <linux/usb_cdc.h> 66#include <linux/usb/cdc.h>
67#include <asm/byteorder.h> 67#include <asm/byteorder.h>
68#include <asm/unaligned.h> 68#include <asm/unaligned.h>
69#include <linux/list.h> 69#include <linux/list.h>
@@ -127,8 +127,8 @@ static int acm_wb_alloc(struct acm *acm)
127 wb->use = 1; 127 wb->use = 1;
128 return wbn; 128 return wbn;
129 } 129 }
130 wbn = (wbn + 1) % ACM_NWB; 130 wbn = (wbn + 1) % ACM_NW;
131 if (++i >= ACM_NWB) 131 if (++i >= ACM_NW)
132 return -1; 132 return -1;
133 } 133 }
134} 134}
@@ -142,10 +142,9 @@ static int acm_wb_is_avail(struct acm *acm)
142{ 142{
143 int i, n; 143 int i, n;
144 144
145 n = 0; 145 n = ACM_NW;
146 for (i = 0; i < ACM_NWB; i++) { 146 for (i = 0; i < ACM_NW; i++) {
147 if (!acm->wb[i].use) 147 n -= acm->wb[i].use;
148 n++;
149 } 148 }
150 return n; 149 return n;
151} 150}
@@ -167,7 +166,7 @@ static void acm_write_done(struct acm *acm)
167 acm->write_ready = 1; 166 acm->write_ready = 1;
168 wbn = acm->write_current; 167 wbn = acm->write_current;
169 acm_wb_free(acm, wbn); 168 acm_wb_free(acm, wbn);
170 acm->write_current = (wbn + 1) % ACM_NWB; 169 acm->write_current = (wbn + 1) % ACM_NW;
171 spin_unlock_irqrestore(&acm->write_lock, flags); 170 spin_unlock_irqrestore(&acm->write_lock, flags);
172} 171}
173 172
@@ -291,22 +290,32 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
291 struct acm_rb *buf; 290 struct acm_rb *buf;
292 struct acm_ru *rcv = urb->context; 291 struct acm_ru *rcv = urb->context;
293 struct acm *acm = rcv->instance; 292 struct acm *acm = rcv->instance;
293 int status = urb->status;
294 dbg("Entering acm_read_bulk with status %d\n", urb->status); 294 dbg("Entering acm_read_bulk with status %d\n", urb->status);
295 295
296 if (!ACM_READY(acm)) 296 if (!ACM_READY(acm))
297 return; 297 return;
298 298
299 if (urb->status) 299 if (status)
300 dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status); 300 dev_dbg(&acm->data->dev, "bulk rx status %d\n", status);
301 301
302 buf = rcv->buffer; 302 buf = rcv->buffer;
303 buf->size = urb->actual_length; 303 buf->size = urb->actual_length;
304 304
305 spin_lock(&acm->read_lock); 305 if (likely(status == 0)) {
306 list_add_tail(&rcv->list, &acm->spare_read_urbs); 306 spin_lock(&acm->read_lock);
307 list_add_tail(&buf->list, &acm->filled_read_bufs); 307 list_add_tail(&rcv->list, &acm->spare_read_urbs);
308 spin_unlock(&acm->read_lock); 308 list_add_tail(&buf->list, &acm->filled_read_bufs);
309 309 spin_unlock(&acm->read_lock);
310 } else {
311 /* we drop the buffer due to an error */
312 spin_lock(&acm->read_lock);
313 list_add_tail(&rcv->list, &acm->spare_read_urbs);
314 list_add(&buf->list, &acm->spare_read_bufs);
315 spin_unlock(&acm->read_lock);
316 /* nevertheless the tasklet must be kicked unconditionally
317 so the queue cannot dry up */
318 }
310 tasklet_schedule(&acm->urb_task); 319 tasklet_schedule(&acm->urb_task);
311} 320}
312 321
@@ -464,10 +473,10 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
464 INIT_LIST_HEAD(&acm->spare_read_urbs); 473 INIT_LIST_HEAD(&acm->spare_read_urbs);
465 INIT_LIST_HEAD(&acm->spare_read_bufs); 474 INIT_LIST_HEAD(&acm->spare_read_bufs);
466 INIT_LIST_HEAD(&acm->filled_read_bufs); 475 INIT_LIST_HEAD(&acm->filled_read_bufs);
467 for (i = 0; i < ACM_NRU; i++) { 476 for (i = 0; i < acm->rx_buflimit; i++) {
468 list_add(&(acm->ru[i].list), &acm->spare_read_urbs); 477 list_add(&(acm->ru[i].list), &acm->spare_read_urbs);
469 } 478 }
470 for (i = 0; i < ACM_NRB; i++) { 479 for (i = 0; i < acm->rx_buflimit; i++) {
471 list_add(&(acm->rb[i].list), &acm->spare_read_bufs); 480 list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
472 } 481 }
473 482
@@ -488,14 +497,15 @@ bail_out:
488 497
489static void acm_tty_unregister(struct acm *acm) 498static void acm_tty_unregister(struct acm *acm)
490{ 499{
491 int i; 500 int i,nr;
492 501
502 nr = acm->rx_buflimit;
493 tty_unregister_device(acm_tty_driver, acm->minor); 503 tty_unregister_device(acm_tty_driver, acm->minor);
494 usb_put_intf(acm->control); 504 usb_put_intf(acm->control);
495 acm_table[acm->minor] = NULL; 505 acm_table[acm->minor] = NULL;
496 usb_free_urb(acm->ctrlurb); 506 usb_free_urb(acm->ctrlurb);
497 usb_free_urb(acm->writeurb); 507 usb_free_urb(acm->writeurb);
498 for (i = 0; i < ACM_NRU; i++) 508 for (i = 0; i < nr; i++)
499 usb_free_urb(acm->ru[i].urb); 509 usb_free_urb(acm->ru[i].urb);
500 kfree(acm); 510 kfree(acm);
501} 511}
@@ -503,18 +513,19 @@ static void acm_tty_unregister(struct acm *acm)
503static void acm_tty_close(struct tty_struct *tty, struct file *filp) 513static void acm_tty_close(struct tty_struct *tty, struct file *filp)
504{ 514{
505 struct acm *acm = tty->driver_data; 515 struct acm *acm = tty->driver_data;
506 int i; 516 int i,nr;
507 517
508 if (!acm || !acm->used) 518 if (!acm || !acm->used)
509 return; 519 return;
510 520
521 nr = acm->rx_buflimit;
511 mutex_lock(&open_mutex); 522 mutex_lock(&open_mutex);
512 if (!--acm->used) { 523 if (!--acm->used) {
513 if (acm->dev) { 524 if (acm->dev) {
514 acm_set_control(acm, acm->ctrlout = 0); 525 acm_set_control(acm, acm->ctrlout = 0);
515 usb_kill_urb(acm->ctrlurb); 526 usb_kill_urb(acm->ctrlurb);
516 usb_kill_urb(acm->writeurb); 527 usb_kill_urb(acm->writeurb);
517 for (i = 0; i < ACM_NRU; i++) 528 for (i = 0; i < nr; i++)
518 usb_kill_urb(acm->ru[i].urb); 529 usb_kill_urb(acm->ru[i].urb);
519 } else 530 } else
520 acm_tty_unregister(acm); 531 acm_tty_unregister(acm);
@@ -576,7 +587,7 @@ static int acm_tty_chars_in_buffer(struct tty_struct *tty)
576 /* 587 /*
577 * This is inaccurate (overcounts), but it works. 588 * This is inaccurate (overcounts), but it works.
578 */ 589 */
579 return (ACM_NWB - acm_wb_is_avail(acm)) * acm->writesize; 590 return (ACM_NW - acm_wb_is_avail(acm)) * acm->writesize;
580} 591}
581 592
582static void acm_tty_throttle(struct tty_struct *tty) 593static void acm_tty_throttle(struct tty_struct *tty)
@@ -712,7 +723,7 @@ static void acm_write_buffers_free(struct acm *acm)
712 int i; 723 int i;
713 struct acm_wb *wb; 724 struct acm_wb *wb;
714 725
715 for (wb = &acm->wb[0], i = 0; i < ACM_NWB; i++, wb++) { 726 for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) {
716 usb_buffer_free(acm->dev, acm->writesize, wb->buf, wb->dmah); 727 usb_buffer_free(acm->dev, acm->writesize, wb->buf, wb->dmah);
717 } 728 }
718} 729}
@@ -723,7 +734,7 @@ static int acm_write_buffers_alloc(struct acm *acm)
723 int i; 734 int i;
724 struct acm_wb *wb; 735 struct acm_wb *wb;
725 736
726 for (wb = &acm->wb[0], i = 0; i < ACM_NWB; i++, wb++) { 737 for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) {
727 wb->buf = usb_buffer_alloc(acm->dev, acm->writesize, GFP_KERNEL, 738 wb->buf = usb_buffer_alloc(acm->dev, acm->writesize, GFP_KERNEL,
728 &wb->dmah); 739 &wb->dmah);
729 if (!wb->buf) { 740 if (!wb->buf) {
@@ -760,10 +771,14 @@ static int acm_probe (struct usb_interface *intf,
760 int call_interface_num = -1; 771 int call_interface_num = -1;
761 int data_interface_num; 772 int data_interface_num;
762 unsigned long quirks; 773 unsigned long quirks;
774 int num_rx_buf;
763 int i; 775 int i;
764 776
765 /* handle quirks deadly to normal probing*/ 777 /* normal quirks */
766 quirks = (unsigned long)id->driver_info; 778 quirks = (unsigned long)id->driver_info;
779 num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR;
780
781 /* handle quirks deadly to normal probing*/
767 if (quirks == NO_UNION_NORMAL) { 782 if (quirks == NO_UNION_NORMAL) {
768 data_interface = usb_ifnum_to_if(usb_dev, 1); 783 data_interface = usb_ifnum_to_if(usb_dev, 1);
769 control_interface = usb_ifnum_to_if(usb_dev, 0); 784 control_interface = usb_ifnum_to_if(usb_dev, 0);
@@ -900,7 +915,7 @@ skip_normal_probe:
900 } 915 }
901 916
902 ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); 917 ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
903 readsize = le16_to_cpu(epread->wMaxPacketSize)*2; 918 readsize = le16_to_cpu(epread->wMaxPacketSize)* ( quirks == SINGLE_RX_URB ? 1 : 2);
904 acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize); 919 acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize);
905 acm->control = control_interface; 920 acm->control = control_interface;
906 acm->data = data_interface; 921 acm->data = data_interface;
@@ -909,6 +924,7 @@ skip_normal_probe:
909 acm->ctrl_caps = ac_management_function; 924 acm->ctrl_caps = ac_management_function;
910 acm->ctrlsize = ctrlsize; 925 acm->ctrlsize = ctrlsize;
911 acm->readsize = readsize; 926 acm->readsize = readsize;
927 acm->rx_buflimit = num_rx_buf;
912 acm->urb_task.func = acm_rx_tasklet; 928 acm->urb_task.func = acm_rx_tasklet;
913 acm->urb_task.data = (unsigned long) acm; 929 acm->urb_task.data = (unsigned long) acm;
914 INIT_WORK(&acm->work, acm_softint, acm); 930 INIT_WORK(&acm->work, acm_softint, acm);
@@ -935,7 +951,7 @@ skip_normal_probe:
935 dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); 951 dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n");
936 goto alloc_fail5; 952 goto alloc_fail5;
937 } 953 }
938 for (i = 0; i < ACM_NRU; i++) { 954 for (i = 0; i < num_rx_buf; i++) {
939 struct acm_ru *rcv = &(acm->ru[i]); 955 struct acm_ru *rcv = &(acm->ru[i]);
940 956
941 if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) { 957 if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
@@ -946,10 +962,9 @@ skip_normal_probe:
946 rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 962 rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
947 rcv->instance = acm; 963 rcv->instance = acm;
948 } 964 }
949 for (i = 0; i < ACM_NRB; i++) { 965 for (i = 0; i < num_rx_buf; i++) {
950 struct acm_rb *buf = &(acm->rb[i]); 966 struct acm_rb *buf = &(acm->rb[i]);
951 967
952 // Using usb_buffer_alloc instead of kmalloc as Oliver suggested
953 if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) { 968 if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) {
954 dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n"); 969 dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
955 goto alloc_fail7; 970 goto alloc_fail7;
@@ -988,9 +1003,9 @@ skip_normal_probe:
988 return 0; 1003 return 0;
989 1004
990alloc_fail7: 1005alloc_fail7:
991 for (i = 0; i < ACM_NRB; i++) 1006 for (i = 0; i < num_rx_buf; i++)
992 usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); 1007 usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
993 for (i = 0; i < ACM_NRU; i++) 1008 for (i = 0; i < num_rx_buf; i++)
994 usb_free_urb(acm->ru[i].urb); 1009 usb_free_urb(acm->ru[i].urb);
995 usb_free_urb(acm->ctrlurb); 1010 usb_free_urb(acm->ctrlurb);
996alloc_fail5: 1011alloc_fail5:
@@ -1027,7 +1042,7 @@ static void acm_disconnect(struct usb_interface *intf)
1027 1042
1028 usb_kill_urb(acm->ctrlurb); 1043 usb_kill_urb(acm->ctrlurb);
1029 usb_kill_urb(acm->writeurb); 1044 usb_kill_urb(acm->writeurb);
1030 for (i = 0; i < ACM_NRU; i++) 1045 for (i = 0; i < acm->rx_buflimit; i++)
1031 usb_kill_urb(acm->ru[i].urb); 1046 usb_kill_urb(acm->ru[i].urb);
1032 1047
1033 INIT_LIST_HEAD(&acm->filled_read_bufs); 1048 INIT_LIST_HEAD(&acm->filled_read_bufs);
@@ -1039,7 +1054,7 @@ static void acm_disconnect(struct usb_interface *intf)
1039 1054
1040 acm_write_buffers_free(acm); 1055 acm_write_buffers_free(acm);
1041 usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); 1056 usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
1042 for (i = 0; i < ACM_NRB; i++) 1057 for (i = 0; i < acm->rx_buflimit; i++)
1043 usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); 1058 usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
1044 1059
1045 usb_driver_release_interface(&acm_driver, intf == acm->control ? acm->data : intf); 1060 usb_driver_release_interface(&acm_driver, intf == acm->control ? acm->data : intf);
@@ -1068,6 +1083,9 @@ static struct usb_device_id acm_ids[] = {
1068 { USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */ 1083 { USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */
1069 .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ 1084 .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
1070 }, 1085 },
1086 { USB_DEVICE(0x0ace, 0x1608), /* ZyDAS 56K USB MODEM */
1087 .driver_info = SINGLE_RX_URB, /* firmware bug */
1088 },
1071 /* control interfaces with various AT-command sets */ 1089 /* control interfaces with various AT-command sets */
1072 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, 1090 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
1073 USB_CDC_ACM_PROTO_AT_V25TER) }, 1091 USB_CDC_ACM_PROTO_AT_V25TER) },
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index fd2aaccdcbac..1bcaea32cfc1 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -56,11 +56,11 @@
56 * in line disciplines. They ask for empty space amount, receive our URB size, 56 * in line disciplines. They ask for empty space amount, receive our URB size,
57 * and proceed to issue several 1-character writes, assuming they will fit. 57 * and proceed to issue several 1-character writes, assuming they will fit.
58 * The very first write takes a complete URB. Fortunately, this only happens 58 * The very first write takes a complete URB. Fortunately, this only happens
59 * when processing onlcr, so we only need 2 buffers. 59 * when processing onlcr, so we only need 2 buffers. These values must be
60 * powers of 2.
60 */ 61 */
61#define ACM_NWB 2 62#define ACM_NW 2
62#define ACM_NRU 16 63#define ACM_NR 16
63#define ACM_NRB 16
64 64
65struct acm_wb { 65struct acm_wb {
66 unsigned char *buf; 66 unsigned char *buf;
@@ -91,9 +91,10 @@ struct acm {
91 struct urb *ctrlurb, *writeurb; /* urbs */ 91 struct urb *ctrlurb, *writeurb; /* urbs */
92 u8 *ctrl_buffer; /* buffers of urbs */ 92 u8 *ctrl_buffer; /* buffers of urbs */
93 dma_addr_t ctrl_dma; /* dma handles of buffers */ 93 dma_addr_t ctrl_dma; /* dma handles of buffers */
94 struct acm_wb wb[ACM_NWB]; 94 struct acm_wb wb[ACM_NW];
95 struct acm_ru ru[ACM_NRU]; 95 struct acm_ru ru[ACM_NR];
96 struct acm_rb rb[ACM_NRB]; 96 struct acm_rb rb[ACM_NR];
97 int rx_buflimit;
97 int rx_endpoint; 98 int rx_endpoint;
98 spinlock_t read_lock; 99 spinlock_t read_lock;
99 struct list_head spare_read_urbs; 100 struct list_head spare_read_urbs;
@@ -122,3 +123,4 @@ struct acm {
122 123
123/* constants describing various quirks and errors */ 124/* constants describing various quirks and errors */
124#define NO_UNION_NORMAL 1 125#define NO_UNION_NORMAL 1
126#define SINGLE_RX_URB 2
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 28329ddf187c..ec510922af63 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -3,7 +3,8 @@
3# 3#
4 4
5usbcore-objs := usb.o hub.o hcd.o urb.o message.o driver.o \ 5usbcore-objs := usb.o hub.o hcd.o urb.o message.o driver.o \
6 config.o file.o buffer.o sysfs.o devio.o notify.o 6 config.o file.o buffer.o sysfs.o endpoint.o \
7 devio.o notify.o
7 8
8ifeq ($(CONFIG_PCI),y) 9ifeq ($(CONFIG_PCI),y)
9 usbcore-objs += hcd-pci.o 10 usbcore-objs += hcd-pci.o
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 545da37afca7..3f8e06279c92 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -515,19 +515,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig
515 515
516static struct usb_device *usbdev_lookup_minor(int minor) 516static struct usb_device *usbdev_lookup_minor(int minor)
517{ 517{
518 struct class_device *class_dev; 518 struct device *device;
519 struct usb_device *dev = NULL; 519 struct usb_device *udev = NULL;
520 520
521 down(&usb_device_class->sem); 521 down(&usb_device_class->sem);
522 list_for_each_entry(class_dev, &usb_device_class->children, node) { 522 list_for_each_entry(device, &usb_device_class->devices, node) {
523 if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { 523 if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) {
524 dev = class_dev->class_data; 524 udev = device->platform_data;
525 break; 525 break;
526 } 526 }
527 } 527 }
528 up(&usb_device_class->sem); 528 up(&usb_device_class->sem);
529 529
530 return dev; 530 return udev;
531}; 531};
532 532
533/* 533/*
@@ -823,8 +823,7 @@ static int proc_connectinfo(struct dev_state *ps, void __user *arg)
823 823
824static int proc_resetdevice(struct dev_state *ps) 824static int proc_resetdevice(struct dev_state *ps)
825{ 825{
826 return usb_reset_device(ps->dev); 826 return usb_reset_composite_device(ps->dev, NULL);
827
828} 827}
829 828
830static int proc_setintf(struct dev_state *ps, void __user *arg) 829static int proc_setintf(struct dev_state *ps, void __user *arg)
@@ -923,8 +922,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
923 if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) 922 if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
924 != USB_ENDPOINT_XFER_CONTROL) 923 != USB_ENDPOINT_XFER_CONTROL)
925 return -EINVAL; 924 return -EINVAL;
926 /* min 8 byte setup packet, max arbitrary */ 925 /* min 8 byte setup packet, max 8 byte setup plus an arbitrary data stage */
927 if (uurb->buffer_length < 8 || uurb->buffer_length > PAGE_SIZE) 926 if (uurb->buffer_length < 8 || uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE))
928 return -EINVAL; 927 return -EINVAL;
929 if (!(dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL))) 928 if (!(dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL)))
930 return -ENOMEM; 929 return -ENOMEM;
@@ -982,7 +981,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
982 return -EFAULT; 981 return -EFAULT;
983 } 982 }
984 for (totlen = u = 0; u < uurb->number_of_packets; u++) { 983 for (totlen = u = 0; u < uurb->number_of_packets; u++) {
985 if (isopkt[u].length > 1023) { 984 /* arbitrary limit, sufficient for USB 2.0 high-bandwidth iso */
985 if (isopkt[u].length > 8192) {
986 kfree(isopkt); 986 kfree(isopkt);
987 return -EINVAL; 987 return -EINVAL;
988 } 988 }
@@ -1078,7 +1078,9 @@ static int proc_submiturb(struct dev_state *ps, void __user *arg)
1078 if (copy_from_user(&uurb, arg, sizeof(uurb))) 1078 if (copy_from_user(&uurb, arg, sizeof(uurb)))
1079 return -EFAULT; 1079 return -EFAULT;
1080 1080
1081 return proc_do_submiturb(ps, &uurb, (((struct usbdevfs_urb __user *)arg)->iso_frame_desc), arg); 1081 return proc_do_submiturb(ps, &uurb,
1082 (struct usbdevfs_iso_packet_desc __user *)uurb.iso_frame_desc,
1083 arg);
1082} 1084}
1083 1085
1084static int proc_unlinkurb(struct dev_state *ps, void __user *arg) 1086static int proc_unlinkurb(struct dev_state *ps, void __user *arg)
@@ -1203,7 +1205,9 @@ static int proc_submiturb_compat(struct dev_state *ps, void __user *arg)
1203 if (get_urb32(&uurb,(struct usbdevfs_urb32 *)arg)) 1205 if (get_urb32(&uurb,(struct usbdevfs_urb32 *)arg))
1204 return -EFAULT; 1206 return -EFAULT;
1205 1207
1206 return proc_do_submiturb(ps, &uurb, ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc, arg); 1208 return proc_do_submiturb(ps, &uurb,
1209 (struct usbdevfs_iso_packet_desc __user *)uurb.iso_frame_desc,
1210 arg);
1207} 1211}
1208 1212
1209static int processcompl_compat(struct async *as, void __user * __user *arg) 1213static int processcompl_compat(struct async *as, void __user * __user *arg)
@@ -1576,16 +1580,16 @@ static void usbdev_add(struct usb_device *dev)
1576{ 1580{
1577 int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); 1581 int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
1578 1582
1579 dev->class_dev = class_device_create(usb_device_class, NULL, 1583 dev->usbfs_dev = device_create(usb_device_class, &dev->dev,
1580 MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev, 1584 MKDEV(USB_DEVICE_MAJOR, minor),
1581 "usbdev%d.%d", dev->bus->busnum, dev->devnum); 1585 "usbdev%d.%d", dev->bus->busnum, dev->devnum);
1582 1586
1583 dev->class_dev->class_data = dev; 1587 dev->usbfs_dev->platform_data = dev;
1584} 1588}
1585 1589
1586static void usbdev_remove(struct usb_device *dev) 1590static void usbdev_remove(struct usb_device *dev)
1587{ 1591{
1588 class_device_unregister(dev->class_dev); 1592 device_unregister(dev->usbfs_dev);
1589} 1593}
1590 1594
1591static int usbdev_notify(struct notifier_block *self, unsigned long action, 1595static int usbdev_notify(struct notifier_block *self, unsigned long action,
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
new file mode 100644
index 000000000000..247b5a4913a8
--- /dev/null
+++ b/drivers/usb/core/endpoint.c
@@ -0,0 +1,275 @@
1/*
2 * drivers/usb/core/endpoint.c
3 *
4 * (C) Copyright 2002,2004,2006 Greg Kroah-Hartman
5 * (C) Copyright 2002,2004 IBM Corp.
6 * (C) Copyright 2006 Novell Inc.
7 *
8 * Endpoint sysfs stuff
9 *
10 */
11
12#include <linux/kernel.h>
13#include <linux/usb.h>
14#include "usb.h"
15
16/* endpoint stuff */
17
18struct ep_device {
19 struct usb_endpoint_descriptor *desc;
20 struct usb_device *udev;
21 struct device dev;
22};
23#define to_ep_device(_dev) \
24 container_of(_dev, struct ep_device, dev)
25
26struct ep_attribute {
27 struct attribute attr;
28 ssize_t (*show)(struct usb_device *,
29 struct usb_endpoint_descriptor *, char *);
30};
31#define to_ep_attribute(_attr) \
32 container_of(_attr, struct ep_attribute, attr)
33
34#define usb_ep_attr(field, format_string) \
35static ssize_t show_ep_##field(struct device *dev, \
36 struct device_attribute *attr, \
37 char *buf) \
38{ \
39 struct ep_device *ep = to_ep_device(dev); \
40 return sprintf(buf, format_string, ep->desc->field); \
41} \
42static DEVICE_ATTR(field, S_IRUGO, show_ep_##field, NULL);
43
44usb_ep_attr(bLength, "%02x\n")
45usb_ep_attr(bEndpointAddress, "%02x\n")
46usb_ep_attr(bmAttributes, "%02x\n")
47usb_ep_attr(bInterval, "%02x\n")
48
49static ssize_t show_ep_wMaxPacketSize(struct device *dev,
50 struct device_attribute *attr, char *buf)
51{
52 struct ep_device *ep = to_ep_device(dev);
53 return sprintf(buf, "%04x\n",
54 le16_to_cpu(ep->desc->wMaxPacketSize) & 0x07ff);
55}
56static DEVICE_ATTR(wMaxPacketSize, S_IRUGO, show_ep_wMaxPacketSize, NULL);
57
58static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr,
59 char *buf)
60{
61 struct ep_device *ep = to_ep_device(dev);
62 char *type = "unknown";
63
64 switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
65 case USB_ENDPOINT_XFER_CONTROL:
66 type = "Control";
67 break;
68 case USB_ENDPOINT_XFER_ISOC:
69 type = "Isoc";
70 break;
71 case USB_ENDPOINT_XFER_BULK:
72 type = "Bulk";
73 break;
74 case USB_ENDPOINT_XFER_INT:
75 type = "Interrupt";
76 break;
77 }
78 return sprintf(buf, "%s\n", type);
79}
80static DEVICE_ATTR(type, S_IRUGO, show_ep_type, NULL);
81
82static ssize_t show_ep_interval(struct device *dev,
83 struct device_attribute *attr, char *buf)
84{
85 struct ep_device *ep = to_ep_device(dev);
86 char unit;
87 unsigned interval = 0;
88 unsigned in;
89
90 in = (ep->desc->bEndpointAddress & USB_DIR_IN);
91
92 switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
93 case USB_ENDPOINT_XFER_CONTROL:
94 if (ep->udev->speed == USB_SPEED_HIGH) /* uframes per NAK */
95 interval = ep->desc->bInterval;
96 break;
97 case USB_ENDPOINT_XFER_ISOC:
98 interval = 1 << (ep->desc->bInterval - 1);
99 break;
100 case USB_ENDPOINT_XFER_BULK:
101 if (ep->udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */
102 interval = ep->desc->bInterval;
103 break;
104 case USB_ENDPOINT_XFER_INT:
105 if (ep->udev->speed == USB_SPEED_HIGH)
106 interval = 1 << (ep->desc->bInterval - 1);
107 else
108 interval = ep->desc->bInterval;
109 break;
110 }
111 interval *= (ep->udev->speed == USB_SPEED_HIGH) ? 125 : 1000;
112 if (interval % 1000)
113 unit = 'u';
114 else {
115 unit = 'm';
116 interval /= 1000;
117 }
118
119 return sprintf(buf, "%d%cs\n", interval, unit);
120}
121static DEVICE_ATTR(interval, S_IRUGO, show_ep_interval, NULL);
122
123static ssize_t show_ep_direction(struct device *dev,
124 struct device_attribute *attr, char *buf)
125{
126 struct ep_device *ep = to_ep_device(dev);
127 char *direction;
128
129 if ((ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
130 USB_ENDPOINT_XFER_CONTROL)
131 direction = "both";
132 else if (ep->desc->bEndpointAddress & USB_DIR_IN)
133 direction = "in";
134 else
135 direction = "out";
136 return sprintf(buf, "%s\n", direction);
137}
138static DEVICE_ATTR(direction, S_IRUGO, show_ep_direction, NULL);
139
140static struct attribute *ep_dev_attrs[] = {
141 &dev_attr_bLength.attr,
142 &dev_attr_bEndpointAddress.attr,
143 &dev_attr_bmAttributes.attr,
144 &dev_attr_bInterval.attr,
145 &dev_attr_wMaxPacketSize.attr,
146 &dev_attr_interval.attr,
147 &dev_attr_type.attr,
148 &dev_attr_direction.attr,
149 NULL,
150};
151static struct attribute_group ep_dev_attr_grp = {
152 .attrs = ep_dev_attrs,
153};
154
155static struct endpoint_class {
156 struct kref kref;
157 struct class *class;
158} *ep_class;
159
160static int init_endpoint_class(void)
161{
162 int result = 0;
163
164 if (ep_class != NULL) {
165 kref_get(&ep_class->kref);
166 goto exit;
167 }
168
169 ep_class = kmalloc(sizeof(*ep_class), GFP_KERNEL);
170 if (!ep_class) {
171 result = -ENOMEM;
172 goto exit;
173 }
174
175 kref_init(&ep_class->kref);
176 ep_class->class = class_create(THIS_MODULE, "usb_endpoint");
177 if (IS_ERR(ep_class->class)) {
178 result = IS_ERR(ep_class->class);
179 kfree(ep_class);
180 ep_class = NULL;
181 goto exit;
182 }
183
184exit:
185 return result;
186}
187
188static void release_endpoint_class(struct kref *kref)
189{
190 /* Ok, we cheat as we know we only have one ep_class */
191 class_destroy(ep_class->class);
192 kfree(ep_class);
193 ep_class = NULL;
194}
195
196static void destroy_endpoint_class(void)
197{
198 if (ep_class)
199 kref_put(&ep_class->kref, release_endpoint_class);
200}
201
202static void ep_device_release(struct device *dev)
203{
204 struct ep_device *ep_dev = to_ep_device(dev);
205
206 dev_dbg(dev, "%s called for %s\n", __FUNCTION__, dev->bus_id);
207 kfree(ep_dev);
208}
209
210void usb_create_ep_files(struct device *parent,
211 struct usb_host_endpoint *endpoint,
212 struct usb_device *udev)
213{
214 char name[8];
215 struct ep_device *ep_dev;
216 int minor;
217 int retval;
218
219 retval = init_endpoint_class();
220 if (retval)
221 goto exit;
222
223 ep_dev = kzalloc(sizeof(*ep_dev), GFP_KERNEL);
224 if (!ep_dev) {
225 retval = -ENOMEM;
226 goto exit;
227 }
228
229 /* fun calculation to determine the minor of this endpoint */
230 minor = (((udev->bus->busnum - 1) * 128) * 16) + (udev->devnum - 1);
231
232 ep_dev->desc = &endpoint->desc;
233 ep_dev->udev = udev;
234 ep_dev->dev.devt = MKDEV(442, minor); // FIXME fake number...
235 ep_dev->dev.class = ep_class->class;
236 ep_dev->dev.parent = parent;
237 ep_dev->dev.release = ep_device_release;
238 snprintf(ep_dev->dev.bus_id, BUS_ID_SIZE, "usbdev%d.%d_ep%02x",
239 udev->bus->busnum, udev->devnum,
240 endpoint->desc.bEndpointAddress);
241
242 retval = device_register(&ep_dev->dev);
243 if (retval)
244 goto error;
245 sysfs_create_group(&ep_dev->dev.kobj, &ep_dev_attr_grp);
246
247 endpoint->ep_dev = ep_dev;
248
249 /* create the symlink to the old-style "ep_XX" directory */
250 sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress);
251 sysfs_create_link(&parent->kobj, &endpoint->ep_dev->dev.kobj, name);
252
253exit:
254 return;
255error:
256 kfree(ep_dev);
257 return;
258}
259
260void usb_remove_ep_files(struct usb_host_endpoint *endpoint)
261{
262
263 if (endpoint->ep_dev) {
264 char name[8];
265
266 sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress);
267 sysfs_remove_link(&endpoint->ep_dev->dev.parent->kobj, name);
268 sysfs_remove_group(&endpoint->ep_dev->dev.kobj, &ep_dev_attr_grp);
269 device_unregister(&endpoint->ep_dev->dev);
270 endpoint->ep_dev = NULL;
271 }
272 destroy_endpoint_class();
273}
274
275
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index b263a54a13c0..f65b193cde3d 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -61,33 +61,66 @@ static struct file_operations usb_fops = {
61 .open = usb_open, 61 .open = usb_open,
62}; 62};
63 63
64static struct class *usb_class; 64static struct usb_class {
65 struct kref kref;
66 struct class *class;
67} *usb_class;
65 68
66int usb_major_init(void) 69static int init_usb_class(void)
67{ 70{
68 int error; 71 int result = 0;
69 72
70 error = register_chrdev(USB_MAJOR, "usb", &usb_fops); 73 if (usb_class != NULL) {
71 if (error) { 74 kref_get(&usb_class->kref);
72 err("unable to get major %d for usb devices", USB_MAJOR); 75 goto exit;
73 goto out; 76 }
77
78 usb_class = kmalloc(sizeof(*usb_class), GFP_KERNEL);
79 if (!usb_class) {
80 result = -ENOMEM;
81 goto exit;
74 } 82 }
75 83
76 usb_class = class_create(THIS_MODULE, "usb"); 84 kref_init(&usb_class->kref);
77 if (IS_ERR(usb_class)) { 85 usb_class->class = class_create(THIS_MODULE, "usb");
78 error = PTR_ERR(usb_class); 86 if (IS_ERR(usb_class->class)) {
87 result = IS_ERR(usb_class->class);
79 err("class_create failed for usb devices"); 88 err("class_create failed for usb devices");
80 unregister_chrdev(USB_MAJOR, "usb"); 89 kfree(usb_class);
81 goto out; 90 usb_class = NULL;
82 } 91 }
83 92
84out: 93exit:
94 return result;
95}
96
97static void release_usb_class(struct kref *kref)
98{
99 /* Ok, we cheat as we know we only have one usb_class */
100 class_destroy(usb_class->class);
101 kfree(usb_class);
102 usb_class = NULL;
103}
104
105static void destroy_usb_class(void)
106{
107 if (usb_class)
108 kref_put(&usb_class->kref, release_usb_class);
109}
110
111int usb_major_init(void)
112{
113 int error;
114
115 error = register_chrdev(USB_MAJOR, "usb", &usb_fops);
116 if (error)
117 err("unable to get major %d for usb devices", USB_MAJOR);
118
85 return error; 119 return error;
86} 120}
87 121
88void usb_major_cleanup(void) 122void usb_major_cleanup(void)
89{ 123{
90 class_destroy(usb_class);
91 unregister_chrdev(USB_MAJOR, "usb"); 124 unregister_chrdev(USB_MAJOR, "usb");
92} 125}
93 126
@@ -149,6 +182,10 @@ int usb_register_dev(struct usb_interface *intf,
149 if (retval) 182 if (retval)
150 goto exit; 183 goto exit;
151 184
185 retval = init_usb_class();
186 if (retval)
187 goto exit;
188
152 intf->minor = minor; 189 intf->minor = minor;
153 190
154 /* create a usb class device for this usb interface */ 191 /* create a usb class device for this usb interface */
@@ -158,14 +195,13 @@ int usb_register_dev(struct usb_interface *intf,
158 ++temp; 195 ++temp;
159 else 196 else
160 temp = name; 197 temp = name;
161 intf->class_dev = class_device_create(usb_class, NULL, 198 intf->usb_dev = device_create(usb_class->class, &intf->dev,
162 MKDEV(USB_MAJOR, minor), 199 MKDEV(USB_MAJOR, minor), "%s", temp);
163 &intf->dev, "%s", temp); 200 if (IS_ERR(intf->usb_dev)) {
164 if (IS_ERR(intf->class_dev)) {
165 spin_lock (&minor_lock); 201 spin_lock (&minor_lock);
166 usb_minors[intf->minor] = NULL; 202 usb_minors[intf->minor] = NULL;
167 spin_unlock (&minor_lock); 203 spin_unlock (&minor_lock);
168 retval = PTR_ERR(intf->class_dev); 204 retval = PTR_ERR(intf->usb_dev);
169 } 205 }
170exit: 206exit:
171 return retval; 207 return retval;
@@ -206,9 +242,10 @@ void usb_deregister_dev(struct usb_interface *intf,
206 spin_unlock (&minor_lock); 242 spin_unlock (&minor_lock);
207 243
208 snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); 244 snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);
209 class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor)); 245 device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
210 intf->class_dev = NULL; 246 intf->usb_dev = NULL;
211 intf->minor = -1; 247 intf->minor = -1;
248 destroy_usb_class();
212} 249}
213EXPORT_SYMBOL(usb_deregister_dev); 250EXPORT_SYMBOL(usb_deregister_dev);
214 251
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 90b8d43c6b33..e1731ff8af4d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -432,15 +432,22 @@ static void hub_power_on(struct usb_hub *hub)
432{ 432{
433 int port1; 433 int port1;
434 unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2; 434 unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2;
435 u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); 435 u16 wHubCharacteristics =
436 436 le16_to_cpu(hub->descriptor->wHubCharacteristics);
437 /* if hub supports power switching, enable power on each port */ 437
438 if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2) { 438 /* Enable power on each port. Some hubs have reserved values
439 * of LPSM (> 2) in their descriptors, even though they are
440 * USB 2.0 hubs. Some hubs do not implement port-power switching
441 * but only emulate it. In all cases, the ports won't work
442 * unless we send these messages to the hub.
443 */
444 if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2)
439 dev_dbg(hub->intfdev, "enabling power on all ports\n"); 445 dev_dbg(hub->intfdev, "enabling power on all ports\n");
440 for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) 446 else
441 set_port_feature(hub->hdev, port1, 447 dev_dbg(hub->intfdev, "trying to enable port power on "
442 USB_PORT_FEAT_POWER); 448 "non-switchable hub\n");
443 } 449 for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++)
450 set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER);
444 451
445 /* Wait at least 100 msec for power to become stable */ 452 /* Wait at least 100 msec for power to become stable */
446 msleep(max(pgood_delay, (unsigned) 100)); 453 msleep(max(pgood_delay, (unsigned) 100));
@@ -518,15 +525,16 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
518 525
519 526
520/* caller has locked the hub device */ 527/* caller has locked the hub device */
521static void hub_pre_reset(struct usb_hub *hub, int disable_ports) 528static void hub_pre_reset(struct usb_interface *intf)
522{ 529{
530 struct usb_hub *hub = usb_get_intfdata(intf);
523 struct usb_device *hdev = hub->hdev; 531 struct usb_device *hdev = hub->hdev;
524 int port1; 532 int port1;
525 533
526 for (port1 = 1; port1 <= hdev->maxchild; ++port1) { 534 for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
527 if (hdev->children[port1 - 1]) { 535 if (hdev->children[port1 - 1]) {
528 usb_disconnect(&hdev->children[port1 - 1]); 536 usb_disconnect(&hdev->children[port1 - 1]);
529 if (disable_ports) 537 if (hub->error == 0)
530 hub_port_disable(hub, port1, 0); 538 hub_port_disable(hub, port1, 0);
531 } 539 }
532 } 540 }
@@ -534,8 +542,10 @@ static void hub_pre_reset(struct usb_hub *hub, int disable_ports)
534} 542}
535 543
536/* caller has locked the hub device */ 544/* caller has locked the hub device */
537static void hub_post_reset(struct usb_hub *hub) 545static void hub_post_reset(struct usb_interface *intf)
538{ 546{
547 struct usb_hub *hub = usb_get_intfdata(intf);
548
539 hub_activate(hub); 549 hub_activate(hub);
540 hub_power_on(hub); 550 hub_power_on(hub);
541} 551}
@@ -795,15 +805,16 @@ static void hub_disconnect(struct usb_interface *intf)
795 struct usb_hub *hub = usb_get_intfdata (intf); 805 struct usb_hub *hub = usb_get_intfdata (intf);
796 struct usb_device *hdev; 806 struct usb_device *hdev;
797 807
808 /* Disconnect all children and quiesce the hub */
809 hub->error = 0;
810 hub_pre_reset(intf);
811
798 usb_set_intfdata (intf, NULL); 812 usb_set_intfdata (intf, NULL);
799 hdev = hub->hdev; 813 hdev = hub->hdev;
800 814
801 if (hdev->speed == USB_SPEED_HIGH) 815 if (hdev->speed == USB_SPEED_HIGH)
802 highspeed_hubs--; 816 highspeed_hubs--;
803 817
804 /* Disconnect all children and quiesce the hub */
805 hub_pre_reset(hub, 1);
806
807 usb_free_urb(hub->urb); 818 usb_free_urb(hub->urb);
808 hub->urb = NULL; 819 hub->urb = NULL;
809 820
@@ -1169,6 +1180,7 @@ static int choose_configuration(struct usb_device *udev)
1169{ 1180{
1170 int i; 1181 int i;
1171 int num_configs; 1182 int num_configs;
1183 int insufficient_power = 0;
1172 struct usb_host_config *c, *best; 1184 struct usb_host_config *c, *best;
1173 1185
1174 best = NULL; 1186 best = NULL;
@@ -1221,8 +1233,10 @@ static int choose_configuration(struct usb_device *udev)
1221 */ 1233 */
1222 1234
1223 /* Rule out configs that draw too much bus current */ 1235 /* Rule out configs that draw too much bus current */
1224 if (c->desc.bMaxPower * 2 > udev->bus_mA) 1236 if (c->desc.bMaxPower * 2 > udev->bus_mA) {
1237 insufficient_power++;
1225 continue; 1238 continue;
1239 }
1226 1240
1227 /* If the first config's first interface is COMM/2/0xff 1241 /* If the first config's first interface is COMM/2/0xff
1228 * (MSFT RNDIS), rule it out unless Linux has host-side 1242 * (MSFT RNDIS), rule it out unless Linux has host-side
@@ -1231,7 +1245,7 @@ static int choose_configuration(struct usb_device *udev)
1231 && desc->bInterfaceClass == USB_CLASS_COMM 1245 && desc->bInterfaceClass == USB_CLASS_COMM
1232 && desc->bInterfaceSubClass == 2 1246 && desc->bInterfaceSubClass == 2
1233 && desc->bInterfaceProtocol == 0xff) { 1247 && desc->bInterfaceProtocol == 0xff) {
1234#ifndef CONFIG_USB_NET_RNDIS 1248#ifndef CONFIG_USB_NET_RNDIS_HOST
1235 continue; 1249 continue;
1236#else 1250#else
1237 best = c; 1251 best = c;
@@ -1256,6 +1270,11 @@ static int choose_configuration(struct usb_device *udev)
1256 best = c; 1270 best = c;
1257 } 1271 }
1258 1272
1273 if (insufficient_power > 0)
1274 dev_info(&udev->dev, "rejected %d configuration%s "
1275 "due to insufficient available bus power\n",
1276 insufficient_power, plural(insufficient_power));
1277
1259 if (best) { 1278 if (best) {
1260 i = best->desc.bConfigurationValue; 1279 i = best->desc.bConfigurationValue;
1261 dev_info(&udev->dev, 1280 dev_info(&udev->dev,
@@ -2732,7 +2751,8 @@ static void hub_events(void)
2732 2751
2733 /* If the hub has died, clean up after it */ 2752 /* If the hub has died, clean up after it */
2734 if (hdev->state == USB_STATE_NOTATTACHED) { 2753 if (hdev->state == USB_STATE_NOTATTACHED) {
2735 hub_pre_reset(hub, 0); 2754 hub->error = -ENODEV;
2755 hub_pre_reset(intf);
2736 goto loop; 2756 goto loop;
2737 } 2757 }
2738 2758
@@ -2744,7 +2764,7 @@ static void hub_events(void)
2744 dev_dbg (hub_dev, "resetting for error %d\n", 2764 dev_dbg (hub_dev, "resetting for error %d\n",
2745 hub->error); 2765 hub->error);
2746 2766
2747 ret = usb_reset_device(hdev); 2767 ret = usb_reset_composite_device(hdev, intf);
2748 if (ret) { 2768 if (ret) {
2749 dev_dbg (hub_dev, 2769 dev_dbg (hub_dev,
2750 "error resetting hub: %d\n", ret); 2770 "error resetting hub: %d\n", ret);
@@ -2913,6 +2933,8 @@ static struct usb_driver hub_driver = {
2913 .disconnect = hub_disconnect, 2933 .disconnect = hub_disconnect,
2914 .suspend = hub_suspend, 2934 .suspend = hub_suspend,
2915 .resume = hub_resume, 2935 .resume = hub_resume,
2936 .pre_reset = hub_pre_reset,
2937 .post_reset = hub_post_reset,
2916 .ioctl = hub_ioctl, 2938 .ioctl = hub_ioctl,
2917 .id_table = hub_id_table, 2939 .id_table = hub_id_table,
2918}; 2940};
@@ -2992,9 +3014,9 @@ static int config_descriptors_changed(struct usb_device *udev)
2992 * usb_reset_device - perform a USB port reset to reinitialize a device 3014 * usb_reset_device - perform a USB port reset to reinitialize a device
2993 * @udev: device to reset (not in SUSPENDED or NOTATTACHED state) 3015 * @udev: device to reset (not in SUSPENDED or NOTATTACHED state)
2994 * 3016 *
2995 * WARNING - don't reset any device unless drivers for all of its 3017 * WARNING - don't use this routine to reset a composite device
2996 * interfaces are expecting that reset! Maybe some driver->reset() 3018 * (one with multiple interfaces owned by separate drivers)!
2997 * method should eventually help ensure sufficient cooperation. 3019 * Use usb_reset_composite_device() instead.
2998 * 3020 *
2999 * Do a port reset, reassign the device's address, and establish its 3021 * Do a port reset, reassign the device's address, and establish its
3000 * former operating configuration. If the reset fails, or the device's 3022 * former operating configuration. If the reset fails, or the device's
@@ -3018,7 +3040,6 @@ int usb_reset_device(struct usb_device *udev)
3018 struct usb_device *parent_hdev = udev->parent; 3040 struct usb_device *parent_hdev = udev->parent;
3019 struct usb_hub *parent_hub; 3041 struct usb_hub *parent_hub;
3020 struct usb_device_descriptor descriptor = udev->descriptor; 3042 struct usb_device_descriptor descriptor = udev->descriptor;
3021 struct usb_hub *hub = NULL;
3022 int i, ret = 0; 3043 int i, ret = 0;
3023 int port1 = udev->portnum; 3044 int port1 = udev->portnum;
3024 3045
@@ -3036,14 +3057,6 @@ int usb_reset_device(struct usb_device *udev)
3036 } 3057 }
3037 parent_hub = hdev_to_hub(parent_hdev); 3058 parent_hub = hdev_to_hub(parent_hdev);
3038 3059
3039 /* If we're resetting an active hub, take some special actions */
3040 if (udev->actconfig && udev->actconfig->desc.bNumInterfaces > 0 &&
3041 udev->actconfig->interface[0]->dev.driver ==
3042 &hub_driver.driver &&
3043 (hub = hdev_to_hub(udev)) != NULL) {
3044 hub_pre_reset(hub, 0);
3045 }
3046
3047 set_bit(port1, parent_hub->busy_bits); 3060 set_bit(port1, parent_hub->busy_bits);
3048 for (i = 0; i < SET_CONFIG_TRIES; ++i) { 3061 for (i = 0; i < SET_CONFIG_TRIES; ++i) {
3049 3062
@@ -3102,11 +3115,87 @@ int usb_reset_device(struct usb_device *udev)
3102 } 3115 }
3103 3116
3104done: 3117done:
3105 if (hub)
3106 hub_post_reset(hub);
3107 return 0; 3118 return 0;
3108 3119
3109re_enumerate: 3120re_enumerate:
3110 hub_port_logical_disconnect(parent_hub, port1); 3121 hub_port_logical_disconnect(parent_hub, port1);
3111 return -ENODEV; 3122 return -ENODEV;
3112} 3123}
3124
3125/**
3126 * usb_reset_composite_device - warn interface drivers and perform a USB port reset
3127 * @udev: device to reset (not in SUSPENDED or NOTATTACHED state)
3128 * @iface: interface bound to the driver making the request (optional)
3129 *
3130 * Warns all drivers bound to registered interfaces (using their pre_reset
3131 * method), performs the port reset, and then lets the drivers know that
3132 * the reset is over (using their post_reset method).
3133 *
3134 * Return value is the same as for usb_reset_device().
3135 *
3136 * The caller must own the device lock. For example, it's safe to use
3137 * this from a driver probe() routine after downloading new firmware.
3138 * For calls that might not occur during probe(), drivers should lock
3139 * the device using usb_lock_device_for_reset().
3140 *
3141 * The interface locks are acquired during the pre_reset stage and released
3142 * during the post_reset stage. However if iface is not NULL and is
3143 * currently being probed, we assume that the caller already owns its
3144 * lock.
3145 */
3146int usb_reset_composite_device(struct usb_device *udev,
3147 struct usb_interface *iface)
3148{
3149 int ret;
3150 struct usb_host_config *config = udev->actconfig;
3151
3152 if (udev->state == USB_STATE_NOTATTACHED ||
3153 udev->state == USB_STATE_SUSPENDED) {
3154 dev_dbg(&udev->dev, "device reset not allowed in state %d\n",
3155 udev->state);
3156 return -EINVAL;
3157 }
3158
3159 if (iface && iface->condition != USB_INTERFACE_BINDING)
3160 iface = NULL;
3161
3162 if (config) {
3163 int i;
3164 struct usb_interface *cintf;
3165 struct usb_driver *drv;
3166
3167 for (i = 0; i < config->desc.bNumInterfaces; ++i) {
3168 cintf = config->interface[i];
3169 if (cintf != iface)
3170 down(&cintf->dev.sem);
3171 if (device_is_registered(&cintf->dev) &&
3172 cintf->dev.driver) {
3173 drv = to_usb_driver(cintf->dev.driver);
3174 if (drv->pre_reset)
3175 (drv->pre_reset)(cintf);
3176 }
3177 }
3178 }
3179
3180 ret = usb_reset_device(udev);
3181
3182 if (config) {
3183 int i;
3184 struct usb_interface *cintf;
3185 struct usb_driver *drv;
3186
3187 for (i = config->desc.bNumInterfaces - 1; i >= 0; --i) {
3188 cintf = config->interface[i];
3189 if (device_is_registered(&cintf->dev) &&
3190 cintf->dev.driver) {
3191 drv = to_usb_driver(cintf->dev.driver);
3192 if (drv->post_reset)
3193 (drv->post_reset)(cintf);
3194 }
3195 if (cintf != iface)
3196 up(&cintf->dev.sem);
3197 }
3198 }
3199
3200 return ret;
3201}
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 08fb20f06f3e..8569600f3130 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -158,6 +158,37 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u
158 158
159 159
160/** 160/**
161 * usb_interrupt_msg - Builds an interrupt urb, sends it off and waits for completion
162 * @usb_dev: pointer to the usb device to send the message to
163 * @pipe: endpoint "pipe" to send the message to
164 * @data: pointer to the data to send
165 * @len: length in bytes of the data to send
166 * @actual_length: pointer to a location to put the actual length transferred in bytes
167 * @timeout: time in msecs to wait for the message to complete before
168 * timing out (if 0 the wait is forever)
169 * Context: !in_interrupt ()
170 *
171 * This function sends a simple interrupt message to a specified endpoint and
172 * waits for the message to complete, or timeout.
173 *
174 * If successful, it returns 0, otherwise a negative error number. The number
175 * of actual bytes transferred will be stored in the actual_length paramater.
176 *
177 * Don't use this function from within an interrupt context, like a bottom half
178 * handler. If you need an asynchronous message, or need to send a message
179 * from within interrupt context, use usb_submit_urb() If a thread in your
180 * driver uses this call, make sure your disconnect() method can wait for it to
181 * complete. Since you don't have a handle on the URB used, you can't cancel
182 * the request.
183 */
184int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,
185 void *data, int len, int *actual_length, int timeout)
186{
187 return usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout);
188}
189EXPORT_SYMBOL_GPL(usb_interrupt_msg);
190
191/**
161 * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion 192 * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion
162 * @usb_dev: pointer to the usb device to send the message to 193 * @usb_dev: pointer to the usb device to send the message to
163 * @pipe: endpoint "pipe" to send the message to 194 * @pipe: endpoint "pipe" to send the message to
@@ -1380,15 +1411,7 @@ free_interfaces:
1380 return ret; 1411 return ret;
1381 } 1412 }
1382 } 1413 }
1383 }
1384
1385 /* if it's already configured, clear out old state first.
1386 * getting rid of old interfaces means unbinding their drivers.
1387 */
1388 if (dev->state != USB_STATE_ADDRESS)
1389 usb_disable_device (dev, 1); // Skip ep0
1390 1414
1391 if (cp) {
1392 i = dev->bus_mA - cp->desc.bMaxPower * 2; 1415 i = dev->bus_mA - cp->desc.bMaxPower * 2;
1393 if (i < 0) 1416 if (i < 0)
1394 dev_warn(&dev->dev, "new config #%d exceeds power " 1417 dev_warn(&dev->dev, "new config #%d exceeds power "
@@ -1396,84 +1419,91 @@ free_interfaces:
1396 configuration, -i); 1419 configuration, -i);
1397 } 1420 }
1398 1421
1422 /* if it's already configured, clear out old state first.
1423 * getting rid of old interfaces means unbinding their drivers.
1424 */
1425 if (dev->state != USB_STATE_ADDRESS)
1426 usb_disable_device (dev, 1); // Skip ep0
1427
1399 if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 1428 if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1400 USB_REQ_SET_CONFIGURATION, 0, configuration, 0, 1429 USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
1401 NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) 1430 NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) {
1402 goto free_interfaces; 1431
1432 /* All the old state is gone, so what else can we do?
1433 * The device is probably useless now anyway.
1434 */
1435 cp = NULL;
1436 }
1403 1437
1404 dev->actconfig = cp; 1438 dev->actconfig = cp;
1405 if (!cp) 1439 if (!cp) {
1406 usb_set_device_state(dev, USB_STATE_ADDRESS); 1440 usb_set_device_state(dev, USB_STATE_ADDRESS);
1407 else { 1441 goto free_interfaces;
1408 usb_set_device_state(dev, USB_STATE_CONFIGURED); 1442 }
1443 usb_set_device_state(dev, USB_STATE_CONFIGURED);
1409 1444
1410 /* Initialize the new interface structures and the 1445 /* Initialize the new interface structures and the
1411 * hc/hcd/usbcore interface/endpoint state. 1446 * hc/hcd/usbcore interface/endpoint state.
1412 */ 1447 */
1413 for (i = 0; i < nintf; ++i) { 1448 for (i = 0; i < nintf; ++i) {
1414 struct usb_interface_cache *intfc; 1449 struct usb_interface_cache *intfc;
1415 struct usb_interface *intf; 1450 struct usb_interface *intf;
1416 struct usb_host_interface *alt; 1451 struct usb_host_interface *alt;
1417 1452
1418 cp->interface[i] = intf = new_interfaces[i]; 1453 cp->interface[i] = intf = new_interfaces[i];
1419 intfc = cp->intf_cache[i]; 1454 intfc = cp->intf_cache[i];
1420 intf->altsetting = intfc->altsetting; 1455 intf->altsetting = intfc->altsetting;
1421 intf->num_altsetting = intfc->num_altsetting; 1456 intf->num_altsetting = intfc->num_altsetting;
1422 kref_get(&intfc->ref); 1457 kref_get(&intfc->ref);
1423
1424 alt = usb_altnum_to_altsetting(intf, 0);
1425
1426 /* No altsetting 0? We'll assume the first altsetting.
1427 * We could use a GetInterface call, but if a device is
1428 * so non-compliant that it doesn't have altsetting 0
1429 * then I wouldn't trust its reply anyway.
1430 */
1431 if (!alt)
1432 alt = &intf->altsetting[0];
1433
1434 intf->cur_altsetting = alt;
1435 usb_enable_interface(dev, intf);
1436 intf->dev.parent = &dev->dev;
1437 intf->dev.driver = NULL;
1438 intf->dev.bus = &usb_bus_type;
1439 intf->dev.dma_mask = dev->dev.dma_mask;
1440 intf->dev.release = release_interface;
1441 device_initialize (&intf->dev);
1442 mark_quiesced(intf);
1443 sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d",
1444 dev->bus->busnum, dev->devpath,
1445 configuration,
1446 alt->desc.bInterfaceNumber);
1447 }
1448 kfree(new_interfaces);
1449 1458
1450 if (cp->string == NULL) 1459 alt = usb_altnum_to_altsetting(intf, 0);
1451 cp->string = usb_cache_string(dev,
1452 cp->desc.iConfiguration);
1453 1460
1454 /* Now that all the interfaces are set up, register them 1461 /* No altsetting 0? We'll assume the first altsetting.
1455 * to trigger binding of drivers to interfaces. probe() 1462 * We could use a GetInterface call, but if a device is
1456 * routines may install different altsettings and may 1463 * so non-compliant that it doesn't have altsetting 0
1457 * claim() any interfaces not yet bound. Many class drivers 1464 * then I wouldn't trust its reply anyway.
1458 * need that: CDC, audio, video, etc.
1459 */ 1465 */
1460 for (i = 0; i < nintf; ++i) { 1466 if (!alt)
1461 struct usb_interface *intf = cp->interface[i]; 1467 alt = &intf->altsetting[0];
1462 1468
1463 dev_dbg (&dev->dev, 1469 intf->cur_altsetting = alt;
1464 "adding %s (config #%d, interface %d)\n", 1470 usb_enable_interface(dev, intf);
1465 intf->dev.bus_id, configuration, 1471 intf->dev.parent = &dev->dev;
1466 intf->cur_altsetting->desc.bInterfaceNumber); 1472 intf->dev.driver = NULL;
1467 ret = device_add (&intf->dev); 1473 intf->dev.bus = &usb_bus_type;
1468 if (ret != 0) { 1474 intf->dev.dma_mask = dev->dev.dma_mask;
1469 dev_err(&dev->dev, 1475 intf->dev.release = release_interface;
1470 "device_add(%s) --> %d\n", 1476 device_initialize (&intf->dev);
1471 intf->dev.bus_id, 1477 mark_quiesced(intf);
1472 ret); 1478 sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d",
1473 continue; 1479 dev->bus->busnum, dev->devpath,
1474 } 1480 configuration, alt->desc.bInterfaceNumber);
1475 usb_create_sysfs_intf_files (intf); 1481 }
1482 kfree(new_interfaces);
1483
1484 if (cp->string == NULL)
1485 cp->string = usb_cache_string(dev, cp->desc.iConfiguration);
1486
1487 /* Now that all the interfaces are set up, register them
1488 * to trigger binding of drivers to interfaces. probe()
1489 * routines may install different altsettings and may
1490 * claim() any interfaces not yet bound. Many class drivers
1491 * need that: CDC, audio, video, etc.
1492 */
1493 for (i = 0; i < nintf; ++i) {
1494 struct usb_interface *intf = cp->interface[i];
1495
1496 dev_dbg (&dev->dev,
1497 "adding %s (config #%d, interface %d)\n",
1498 intf->dev.bus_id, configuration,
1499 intf->cur_altsetting->desc.bInterfaceNumber);
1500 ret = device_add (&intf->dev);
1501 if (ret != 0) {
1502 dev_err(&dev->dev, "device_add(%s) --> %d\n",
1503 intf->dev.bus_id, ret);
1504 continue;
1476 } 1505 }
1506 usb_create_sysfs_intf_files (intf);
1477 } 1507 }
1478 1508
1479 return 0; 1509 return 0;
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 71d881327e88..3f49bf51cff7 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -15,203 +15,6 @@
15#include <linux/usb.h> 15#include <linux/usb.h>
16#include "usb.h" 16#include "usb.h"
17 17
18/* endpoint stuff */
19struct ep_object {
20 struct usb_endpoint_descriptor *desc;
21 struct usb_device *udev;
22 struct kobject kobj;
23};
24#define to_ep_object(_kobj) \
25 container_of(_kobj, struct ep_object, kobj)
26
27struct ep_attribute {
28 struct attribute attr;
29 ssize_t (*show)(struct usb_device *,
30 struct usb_endpoint_descriptor *, char *);
31};
32#define to_ep_attribute(_attr) \
33 container_of(_attr, struct ep_attribute, attr)
34
35#define EP_ATTR(_name) \
36struct ep_attribute ep_##_name = { \
37 .attr = {.name = #_name, .owner = THIS_MODULE, \
38 .mode = S_IRUGO}, \
39 .show = show_ep_##_name}
40
41#define usb_ep_attr(field, format_string) \
42static ssize_t show_ep_##field(struct usb_device *udev, \
43 struct usb_endpoint_descriptor *desc, \
44 char *buf) \
45{ \
46 return sprintf(buf, format_string, desc->field); \
47} \
48static EP_ATTR(field);
49
50usb_ep_attr(bLength, "%02x\n")
51usb_ep_attr(bEndpointAddress, "%02x\n")
52usb_ep_attr(bmAttributes, "%02x\n")
53usb_ep_attr(bInterval, "%02x\n")
54
55static ssize_t show_ep_wMaxPacketSize(struct usb_device *udev,
56 struct usb_endpoint_descriptor *desc, char *buf)
57{
58 return sprintf(buf, "%04x\n",
59 le16_to_cpu(desc->wMaxPacketSize) & 0x07ff);
60}
61static EP_ATTR(wMaxPacketSize);
62
63static ssize_t show_ep_type(struct usb_device *udev,
64 struct usb_endpoint_descriptor *desc, char *buf)
65{
66 char *type = "unknown";
67
68 switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
69 case USB_ENDPOINT_XFER_CONTROL:
70 type = "Control";
71 break;
72 case USB_ENDPOINT_XFER_ISOC:
73 type = "Isoc";
74 break;
75 case USB_ENDPOINT_XFER_BULK:
76 type = "Bulk";
77 break;
78 case USB_ENDPOINT_XFER_INT:
79 type = "Interrupt";
80 break;
81 }
82 return sprintf(buf, "%s\n", type);
83}
84static EP_ATTR(type);
85
86static ssize_t show_ep_interval(struct usb_device *udev,
87 struct usb_endpoint_descriptor *desc, char *buf)
88{
89 char unit;
90 unsigned interval = 0;
91 unsigned in;
92
93 in = (desc->bEndpointAddress & USB_DIR_IN);
94
95 switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
96 case USB_ENDPOINT_XFER_CONTROL:
97 if (udev->speed == USB_SPEED_HIGH) /* uframes per NAK */
98 interval = desc->bInterval;
99 break;
100 case USB_ENDPOINT_XFER_ISOC:
101 interval = 1 << (desc->bInterval - 1);
102 break;
103 case USB_ENDPOINT_XFER_BULK:
104 if (udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */
105 interval = desc->bInterval;
106 break;
107 case USB_ENDPOINT_XFER_INT:
108 if (udev->speed == USB_SPEED_HIGH)
109 interval = 1 << (desc->bInterval - 1);
110 else
111 interval = desc->bInterval;
112 break;
113 }
114 interval *= (udev->speed == USB_SPEED_HIGH) ? 125 : 1000;
115 if (interval % 1000)
116 unit = 'u';
117 else {
118 unit = 'm';
119 interval /= 1000;
120 }
121
122 return sprintf(buf, "%d%cs\n", interval, unit);
123}
124static EP_ATTR(interval);
125
126static ssize_t show_ep_direction(struct usb_device *udev,
127 struct usb_endpoint_descriptor *desc, char *buf)
128{
129 char *direction;
130
131 if ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
132 USB_ENDPOINT_XFER_CONTROL)
133 direction = "both";
134 else if (desc->bEndpointAddress & USB_DIR_IN)
135 direction = "in";
136 else
137 direction = "out";
138 return sprintf(buf, "%s\n", direction);
139}
140static EP_ATTR(direction);
141
142static struct attribute *ep_attrs[] = {
143 &ep_bLength.attr,
144 &ep_bEndpointAddress.attr,
145 &ep_bmAttributes.attr,
146 &ep_bInterval.attr,
147 &ep_wMaxPacketSize.attr,
148 &ep_type.attr,
149 &ep_interval.attr,
150 &ep_direction.attr,
151 NULL,
152};
153
154static void ep_object_release(struct kobject *kobj)
155{
156 kfree(to_ep_object(kobj));
157}
158
159static ssize_t ep_object_show(struct kobject *kobj, struct attribute *attr,
160 char *buf)
161{
162 struct ep_object *ep_obj = to_ep_object(kobj);
163 struct ep_attribute *ep_attr = to_ep_attribute(attr);
164
165 return (ep_attr->show)(ep_obj->udev, ep_obj->desc, buf);
166}
167
168static struct sysfs_ops ep_object_sysfs_ops = {
169 .show = ep_object_show,
170};
171
172static struct kobj_type ep_object_ktype = {
173 .release = ep_object_release,
174 .sysfs_ops = &ep_object_sysfs_ops,
175 .default_attrs = ep_attrs,
176};
177
178static void usb_create_ep_files(struct kobject *parent,
179 struct usb_host_endpoint *endpoint,
180 struct usb_device *udev)
181{
182 struct ep_object *ep_obj;
183 struct kobject *kobj;
184
185 ep_obj = kzalloc(sizeof(struct ep_object), GFP_KERNEL);
186 if (!ep_obj)
187 return;
188
189 ep_obj->desc = &endpoint->desc;
190 ep_obj->udev = udev;
191
192 kobj = &ep_obj->kobj;
193 kobject_set_name(kobj, "ep_%02x", endpoint->desc.bEndpointAddress);
194 kobj->parent = parent;
195 kobj->ktype = &ep_object_ktype;
196
197 /* Don't use kobject_register, because it generates a hotplug event */
198 kobject_init(kobj);
199 if (kobject_add(kobj) == 0)
200 endpoint->kobj = kobj;
201 else
202 kobject_put(kobj);
203}
204
205static void usb_remove_ep_files(struct usb_host_endpoint *endpoint)
206{
207
208 if (endpoint->kobj) {
209 kobject_del(endpoint->kobj);
210 kobject_put(endpoint->kobj);
211 endpoint->kobj = NULL;
212 }
213}
214
215/* Active configuration fields */ 18/* Active configuration fields */
216#define usb_actconfig_show(field, multiplier, format_string) \ 19#define usb_actconfig_show(field, multiplier, format_string) \
217static ssize_t show_##field (struct device *dev, \ 20static ssize_t show_##field (struct device *dev, \
@@ -420,7 +223,7 @@ void usb_create_sysfs_dev_files (struct usb_device *udev)
420 if (udev->serial) 223 if (udev->serial)
421 device_create_file (dev, &dev_attr_serial); 224 device_create_file (dev, &dev_attr_serial);
422 device_create_file (dev, &dev_attr_configuration); 225 device_create_file (dev, &dev_attr_configuration);
423 usb_create_ep_files(&dev->kobj, &udev->ep0, udev); 226 usb_create_ep_files(dev, &udev->ep0, udev);
424} 227}
425 228
426void usb_remove_sysfs_dev_files (struct usb_device *udev) 229void usb_remove_sysfs_dev_files (struct usb_device *udev)
@@ -524,7 +327,7 @@ static inline void usb_create_intf_ep_files(struct usb_interface *intf,
524 327
525 iface_desc = intf->cur_altsetting; 328 iface_desc = intf->cur_altsetting;
526 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) 329 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i)
527 usb_create_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i], 330 usb_create_ep_files(&intf->dev, &iface_desc->endpoint[i],
528 udev); 331 udev);
529} 332}
530 333
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index b7fdc1cd134a..515310751303 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1207,6 +1207,7 @@ EXPORT_SYMBOL(usb_ifnum_to_if);
1207EXPORT_SYMBOL(usb_altnum_to_altsetting); 1207EXPORT_SYMBOL(usb_altnum_to_altsetting);
1208 1208
1209EXPORT_SYMBOL(usb_reset_device); 1209EXPORT_SYMBOL(usb_reset_device);
1210EXPORT_SYMBOL(usb_reset_composite_device);
1210 1211
1211EXPORT_SYMBOL(__usb_get_extra_descriptor); 1212EXPORT_SYMBOL(__usb_get_extra_descriptor);
1212 1213
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 4647e1ebc68d..7a650c763a62 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -4,6 +4,9 @@ extern void usb_create_sysfs_dev_files (struct usb_device *dev);
4extern void usb_remove_sysfs_dev_files (struct usb_device *dev); 4extern void usb_remove_sysfs_dev_files (struct usb_device *dev);
5extern void usb_create_sysfs_intf_files (struct usb_interface *intf); 5extern void usb_create_sysfs_intf_files (struct usb_interface *intf);
6extern void usb_remove_sysfs_intf_files (struct usb_interface *intf); 6extern void usb_remove_sysfs_intf_files (struct usb_interface *intf);
7extern void usb_create_ep_files(struct device *parent, struct usb_host_endpoint *endpoint,
8 struct usb_device *udev);
9extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint);
7 10
8extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr); 11extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr);
9extern void usb_disable_interface (struct usb_device *dev, 12extern void usb_disable_interface (struct usb_device *dev,
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 9c4422ac9de4..078daa026718 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -49,7 +49,7 @@
49#include <asm/unaligned.h> 49#include <asm/unaligned.h>
50 50
51#include <linux/usb_ch9.h> 51#include <linux/usb_ch9.h>
52#include <linux/usb_cdc.h> 52#include <linux/usb/cdc.h>
53#include <linux/usb_gadget.h> 53#include <linux/usb_gadget.h>
54 54
55#include <linux/random.h> 55#include <linux/random.h>
@@ -101,9 +101,9 @@ static const char driver_desc [] = DRIVER_DESC;
101 101
102/* CDC and RNDIS support the same host-chosen outgoing packet filters. */ 102/* CDC and RNDIS support the same host-chosen outgoing packet filters. */
103#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \ 103#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \
104 |USB_CDC_PACKET_TYPE_ALL_MULTICAST \ 104 |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
105 |USB_CDC_PACKET_TYPE_PROMISCUOUS \ 105 |USB_CDC_PACKET_TYPE_PROMISCUOUS \
106 |USB_CDC_PACKET_TYPE_DIRECTED) 106 |USB_CDC_PACKET_TYPE_DIRECTED)
107 107
108 108
109/*-------------------------------------------------------------------------*/ 109/*-------------------------------------------------------------------------*/
@@ -318,7 +318,7 @@ static inline int rndis_active(struct eth_dev *dev)
318#define DEFAULT_QLEN 2 /* double buffering by default */ 318#define DEFAULT_QLEN 2 /* double buffering by default */
319 319
320/* peak bulk transfer bits-per-second */ 320/* peak bulk transfer bits-per-second */
321#define HS_BPS (13 * 512 * 8 * 1000 * 8) 321#define HS_BPS (13 * 512 * 8 * 1000 * 8)
322#define FS_BPS (19 * 64 * 1 * 1000 * 8) 322#define FS_BPS (19 * 64 * 1 * 1000 * 8)
323 323
324#ifdef CONFIG_USB_GADGET_DUALSPEED 324#ifdef CONFIG_USB_GADGET_DUALSPEED
@@ -466,7 +466,7 @@ eth_config = {
466}; 466};
467 467
468#ifdef CONFIG_USB_ETH_RNDIS 468#ifdef CONFIG_USB_ETH_RNDIS
469static struct usb_config_descriptor 469static struct usb_config_descriptor
470rndis_config = { 470rndis_config = {
471 .bLength = sizeof rndis_config, 471 .bLength = sizeof rndis_config,
472 .bDescriptorType = USB_DT_CONFIG, 472 .bDescriptorType = USB_DT_CONFIG,
@@ -511,7 +511,7 @@ static const struct usb_interface_descriptor
511rndis_control_intf = { 511rndis_control_intf = {
512 .bLength = sizeof rndis_control_intf, 512 .bLength = sizeof rndis_control_intf,
513 .bDescriptorType = USB_DT_INTERFACE, 513 .bDescriptorType = USB_DT_INTERFACE,
514 514
515 .bInterfaceNumber = 0, 515 .bInterfaceNumber = 0,
516 .bNumEndpoints = 1, 516 .bNumEndpoints = 1,
517 .bInterfaceClass = USB_CLASS_COMM, 517 .bInterfaceClass = USB_CLASS_COMM,
@@ -545,20 +545,20 @@ static const struct usb_cdc_union_desc union_desc = {
545#ifdef CONFIG_USB_ETH_RNDIS 545#ifdef CONFIG_USB_ETH_RNDIS
546 546
547static const struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor = { 547static const struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor = {
548 .bLength = sizeof call_mgmt_descriptor, 548 .bLength = sizeof call_mgmt_descriptor,
549 .bDescriptorType = USB_DT_CS_INTERFACE, 549 .bDescriptorType = USB_DT_CS_INTERFACE,
550 .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, 550 .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE,
551 551
552 .bmCapabilities = 0x00, 552 .bmCapabilities = 0x00,
553 .bDataInterface = 0x01, 553 .bDataInterface = 0x01,
554}; 554};
555 555
556static const struct usb_cdc_acm_descriptor acm_descriptor = { 556static const struct usb_cdc_acm_descriptor acm_descriptor = {
557 .bLength = sizeof acm_descriptor, 557 .bLength = sizeof acm_descriptor,
558 .bDescriptorType = USB_DT_CS_INTERFACE, 558 .bDescriptorType = USB_DT_CS_INTERFACE,
559 .bDescriptorSubType = USB_CDC_ACM_TYPE, 559 .bDescriptorSubType = USB_CDC_ACM_TYPE,
560 560
561 .bmCapabilities = 0x00, 561 .bmCapabilities = 0x00,
562}; 562};
563 563
564#endif 564#endif
@@ -595,7 +595,7 @@ static const struct usb_cdc_ether_desc ether_desc = {
595 * RNDIS requires the status endpoint, since it uses that encapsulation 595 * RNDIS requires the status endpoint, since it uses that encapsulation
596 * mechanism for its funky RPC scheme. 596 * mechanism for its funky RPC scheme.
597 */ 597 */
598 598
599#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ 599#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
600#define STATUS_BYTECOUNT 16 /* 8 byte header + data */ 600#define STATUS_BYTECOUNT 16 /* 8 byte header + data */
601 601
@@ -978,7 +978,7 @@ set_ether_config (struct eth_dev *dev, gfp_t gfp_flags)
978 978
979 result = usb_ep_enable (dev->status_ep, dev->status); 979 result = usb_ep_enable (dev->status_ep, dev->status);
980 if (result != 0) { 980 if (result != 0) {
981 DEBUG (dev, "enable %s --> %d\n", 981 DEBUG (dev, "enable %s --> %d\n",
982 dev->status_ep->name, result); 982 dev->status_ep->name, result);
983 goto done; 983 goto done;
984 } 984 }
@@ -1002,15 +1002,15 @@ set_ether_config (struct eth_dev *dev, gfp_t gfp_flags)
1002 if (!cdc_active(dev)) { 1002 if (!cdc_active(dev)) {
1003 result = usb_ep_enable (dev->in_ep, dev->in); 1003 result = usb_ep_enable (dev->in_ep, dev->in);
1004 if (result != 0) { 1004 if (result != 0) {
1005 DEBUG(dev, "enable %s --> %d\n", 1005 DEBUG(dev, "enable %s --> %d\n",
1006 dev->in_ep->name, result); 1006 dev->in_ep->name, result);
1007 goto done; 1007 goto done;
1008 } 1008 }
1009 1009
1010 result = usb_ep_enable (dev->out_ep, dev->out); 1010 result = usb_ep_enable (dev->out_ep, dev->out);
1011 if (result != 0) { 1011 if (result != 0) {
1012 DEBUG (dev, "enable %s --> %d\n", 1012 DEBUG (dev, "enable %s --> %d\n",
1013 dev->in_ep->name, result); 1013 dev->out_ep->name, result);
1014 goto done; 1014 goto done;
1015 } 1015 }
1016 } 1016 }
@@ -1144,7 +1144,7 @@ eth_set_config (struct eth_dev *dev, unsigned number, gfp_t gfp_flags)
1144#ifdef CONFIG_USB_GADGET_DUALSPEED 1144#ifdef CONFIG_USB_GADGET_DUALSPEED
1145 case USB_SPEED_HIGH: speed = "high"; break; 1145 case USB_SPEED_HIGH: speed = "high"; break;
1146#endif 1146#endif
1147 default: speed = "?"; break; 1147 default: speed = "?"; break;
1148 } 1148 }
1149 1149
1150 dev->config = number; 1150 dev->config = number;
@@ -1206,7 +1206,7 @@ static void issue_start_status (struct eth_dev *dev)
1206 struct usb_request *req = dev->stat_req; 1206 struct usb_request *req = dev->stat_req;
1207 struct usb_cdc_notification *event; 1207 struct usb_cdc_notification *event;
1208 int value; 1208 int value;
1209 1209
1210 DEBUG (dev, "%s, flush old status first\n", __FUNCTION__); 1210 DEBUG (dev, "%s, flush old status first\n", __FUNCTION__);
1211 1211
1212 /* flush old status 1212 /* flush old status
@@ -1268,7 +1268,7 @@ static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
1268{ 1268{
1269 struct eth_dev *dev = ep->driver_data; 1269 struct eth_dev *dev = ep->driver_data;
1270 int status; 1270 int status;
1271 1271
1272 /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */ 1272 /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
1273 spin_lock(&dev->lock); 1273 spin_lock(&dev->lock);
1274 status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf); 1274 status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf);
@@ -1472,7 +1472,7 @@ done_set_intf:
1472 1472
1473#endif /* DEV_CONFIG_CDC */ 1473#endif /* DEV_CONFIG_CDC */
1474 1474
1475#ifdef CONFIG_USB_ETH_RNDIS 1475#ifdef CONFIG_USB_ETH_RNDIS
1476 /* RNDIS uses the CDC command encapsulation mechanism to implement 1476 /* RNDIS uses the CDC command encapsulation mechanism to implement
1477 * an RPC scheme, with much getting/setting of attributes by OID. 1477 * an RPC scheme, with much getting/setting of attributes by OID.
1478 */ 1478 */
@@ -1489,7 +1489,7 @@ done_set_intf:
1489 req->complete = rndis_command_complete; 1489 req->complete = rndis_command_complete;
1490 /* later, rndis_control_ack () sends a notification */ 1490 /* later, rndis_control_ack () sends a notification */
1491 break; 1491 break;
1492 1492
1493 case USB_CDC_GET_ENCAPSULATED_RESPONSE: 1493 case USB_CDC_GET_ENCAPSULATED_RESPONSE:
1494 if ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE) 1494 if ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)
1495 == ctrl->bRequestType 1495 == ctrl->bRequestType
@@ -1641,7 +1641,7 @@ rx_submit (struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
1641 DEBUG (dev, "no rx skb\n"); 1641 DEBUG (dev, "no rx skb\n");
1642 goto enomem; 1642 goto enomem;
1643 } 1643 }
1644 1644
1645 /* Some platforms perform better when IP packets are aligned, 1645 /* Some platforms perform better when IP packets are aligned,
1646 * but on at least one, checksumming fails otherwise. Note: 1646 * but on at least one, checksumming fails otherwise. Note:
1647 * RNDIS headers involve variable numbers of LE32 values. 1647 * RNDIS headers involve variable numbers of LE32 values.
@@ -1720,7 +1720,7 @@ quiesce:
1720 case -EOVERFLOW: 1720 case -EOVERFLOW:
1721 dev->stats.rx_over_errors++; 1721 dev->stats.rx_over_errors++;
1722 // FALLTHROUGH 1722 // FALLTHROUGH
1723 1723
1724 default: 1724 default:
1725 dev->stats.rx_errors++; 1725 dev->stats.rx_errors++;
1726 DEBUG (dev, "rx status %d\n", status); 1726 DEBUG (dev, "rx status %d\n", status);
@@ -1915,7 +1915,7 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
1915 sizeof (struct rndis_packet_msg_type)); 1915 sizeof (struct rndis_packet_msg_type));
1916 if (!skb_rndis) 1916 if (!skb_rndis)
1917 goto drop; 1917 goto drop;
1918 1918
1919 dev_kfree_skb_any (skb); 1919 dev_kfree_skb_any (skb);
1920 skb = skb_rndis; 1920 skb = skb_rndis;
1921 rndis_add_hdr (skb); 1921 rndis_add_hdr (skb);
@@ -2001,7 +2001,7 @@ static int rndis_control_ack (struct net_device *net)
2001 struct eth_dev *dev = netdev_priv(net); 2001 struct eth_dev *dev = netdev_priv(net);
2002 u32 length; 2002 u32 length;
2003 struct usb_request *resp = dev->stat_req; 2003 struct usb_request *resp = dev->stat_req;
2004 2004
2005 /* in case RNDIS calls this after disconnect */ 2005 /* in case RNDIS calls this after disconnect */
2006 if (!dev->status) { 2006 if (!dev->status) {
2007 DEBUG (dev, "status ENODEV\n"); 2007 DEBUG (dev, "status ENODEV\n");
@@ -2021,16 +2021,16 @@ static int rndis_control_ack (struct net_device *net)
2021 resp->length = 8; 2021 resp->length = 8;
2022 resp->complete = rndis_control_ack_complete; 2022 resp->complete = rndis_control_ack_complete;
2023 resp->context = dev; 2023 resp->context = dev;
2024 2024
2025 *((__le32 *) resp->buf) = __constant_cpu_to_le32 (1); 2025 *((__le32 *) resp->buf) = __constant_cpu_to_le32 (1);
2026 *((__le32 *) resp->buf + 1) = __constant_cpu_to_le32 (0); 2026 *((__le32 *) resp->buf + 1) = __constant_cpu_to_le32 (0);
2027 2027
2028 length = usb_ep_queue (dev->status_ep, resp, GFP_ATOMIC); 2028 length = usb_ep_queue (dev->status_ep, resp, GFP_ATOMIC);
2029 if (length < 0) { 2029 if (length < 0) {
2030 resp->status = 0; 2030 resp->status = 0;
2031 rndis_control_ack_complete (dev->status_ep, resp); 2031 rndis_control_ack_complete (dev->status_ep, resp);
2032 } 2032 }
2033 2033
2034 return 0; 2034 return 0;
2035} 2035}
2036 2036
@@ -2047,7 +2047,7 @@ static void eth_start (struct eth_dev *dev, gfp_t gfp_flags)
2047 /* fill the rx queue */ 2047 /* fill the rx queue */
2048 rx_fill (dev, gfp_flags); 2048 rx_fill (dev, gfp_flags);
2049 2049
2050 /* and open the tx floodgates */ 2050 /* and open the tx floodgates */
2051 atomic_set (&dev->tx_qlen, 0); 2051 atomic_set (&dev->tx_qlen, 0);
2052 netif_wake_queue (dev->net); 2052 netif_wake_queue (dev->net);
2053 if (rndis_active(dev)) { 2053 if (rndis_active(dev)) {
@@ -2076,7 +2076,7 @@ static int eth_stop (struct net_device *net)
2076 netif_stop_queue (net); 2076 netif_stop_queue (net);
2077 2077
2078 DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n", 2078 DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n",
2079 dev->stats.rx_packets, dev->stats.tx_packets, 2079 dev->stats.rx_packets, dev->stats.tx_packets,
2080 dev->stats.rx_errors, dev->stats.tx_errors 2080 dev->stats.rx_errors, dev->stats.tx_errors
2081 ); 2081 );
2082 2082
@@ -2095,7 +2095,7 @@ static int eth_stop (struct net_device *net)
2095 usb_ep_enable (dev->status_ep, dev->status); 2095 usb_ep_enable (dev->status_ep, dev->status);
2096 } 2096 }
2097 } 2097 }
2098 2098
2099 if (rndis_active(dev)) { 2099 if (rndis_active(dev)) {
2100 rndis_set_param_medium (dev->rndis_config, 2100 rndis_set_param_medium (dev->rndis_config,
2101 NDIS_MEDIUM_802_3, 0); 2101 NDIS_MEDIUM_802_3, 0);
@@ -2301,7 +2301,7 @@ autoconf_fail:
2301 return -ENODEV; 2301 return -ENODEV;
2302 } 2302 }
2303 in_ep->driver_data = in_ep; /* claim */ 2303 in_ep->driver_data = in_ep; /* claim */
2304 2304
2305 out_ep = usb_ep_autoconfig (gadget, &fs_sink_desc); 2305 out_ep = usb_ep_autoconfig (gadget, &fs_sink_desc);
2306 if (!out_ep) 2306 if (!out_ep)
2307 goto autoconf_fail; 2307 goto autoconf_fail;
@@ -2374,8 +2374,8 @@ autoconf_fail:
2374#endif 2374#endif
2375 } 2375 }
2376 2376
2377 net = alloc_etherdev (sizeof *dev); 2377 net = alloc_etherdev (sizeof *dev);
2378 if (!net) 2378 if (!net)
2379 return status; 2379 return status;
2380 dev = netdev_priv(net); 2380 dev = netdev_priv(net);
2381 spin_lock_init (&dev->lock); 2381 spin_lock_init (&dev->lock);
@@ -2454,7 +2454,7 @@ autoconf_fail:
2454 dev->gadget = gadget; 2454 dev->gadget = gadget;
2455 set_gadget_data (gadget, dev); 2455 set_gadget_data (gadget, dev);
2456 gadget->ep0->driver_data = dev; 2456 gadget->ep0->driver_data = dev;
2457 2457
2458 /* two kinds of host-initiated state changes: 2458 /* two kinds of host-initiated state changes:
2459 * - iff DATA transfer is active, carrier is "on" 2459 * - iff DATA transfer is active, carrier is "on"
2460 * - tx queueing enabled if open *and* carrier is "on" 2460 * - tx queueing enabled if open *and* carrier is "on"
@@ -2462,8 +2462,8 @@ autoconf_fail:
2462 netif_stop_queue (dev->net); 2462 netif_stop_queue (dev->net);
2463 netif_carrier_off (dev->net); 2463 netif_carrier_off (dev->net);
2464 2464
2465 SET_NETDEV_DEV (dev->net, &gadget->dev); 2465 SET_NETDEV_DEV (dev->net, &gadget->dev);
2466 status = register_netdev (dev->net); 2466 status = register_netdev (dev->net);
2467 if (status < 0) 2467 if (status < 0)
2468 goto fail1; 2468 goto fail1;
2469 2469
@@ -2488,7 +2488,7 @@ autoconf_fail:
2488 u32 vendorID = 0; 2488 u32 vendorID = 0;
2489 2489
2490 /* FIXME RNDIS vendor id == "vendor NIC code" == ? */ 2490 /* FIXME RNDIS vendor id == "vendor NIC code" == ? */
2491 2491
2492 dev->rndis_config = rndis_register (rndis_control_ack); 2492 dev->rndis_config = rndis_register (rndis_control_ack);
2493 if (dev->rndis_config < 0) { 2493 if (dev->rndis_config < 0) {
2494fail0: 2494fail0:
@@ -2496,7 +2496,7 @@ fail0:
2496 status = -ENODEV; 2496 status = -ENODEV;
2497 goto fail; 2497 goto fail;
2498 } 2498 }
2499 2499
2500 /* these set up a lot of the OIDs that RNDIS needs */ 2500 /* these set up a lot of the OIDs that RNDIS needs */
2501 rndis_set_host_mac (dev->rndis_config, dev->host_mac); 2501 rndis_set_host_mac (dev->rndis_config, dev->host_mac);
2502 if (rndis_set_param_dev (dev->rndis_config, dev->net, 2502 if (rndis_set_param_dev (dev->rndis_config, dev->net,
@@ -2556,7 +2556,7 @@ static struct usb_gadget_driver eth_driver = {
2556 .suspend = eth_suspend, 2556 .suspend = eth_suspend,
2557 .resume = eth_resume, 2557 .resume = eth_resume,
2558 2558
2559 .driver = { 2559 .driver = {
2560 .name = (char *) shortname, 2560 .name = (char *) shortname,
2561 .owner = THIS_MODULE, 2561 .owner = THIS_MODULE,
2562 }, 2562 },
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 0eb010a3f5bc..aef0722b8f17 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -528,7 +528,7 @@ struct kiocb_priv {
528 struct usb_request *req; 528 struct usb_request *req;
529 struct ep_data *epdata; 529 struct ep_data *epdata;
530 void *buf; 530 void *buf;
531 char __user *ubuf; 531 char __user *ubuf; /* NULL for writes */
532 unsigned actual; 532 unsigned actual;
533}; 533};
534 534
@@ -566,7 +566,6 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb)
566 status = priv->actual; 566 status = priv->actual;
567 kfree(priv->buf); 567 kfree(priv->buf);
568 kfree(priv); 568 kfree(priv);
569 aio_put_req(iocb);
570 return status; 569 return status;
571} 570}
572 571
@@ -580,8 +579,8 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)
580 spin_lock(&epdata->dev->lock); 579 spin_lock(&epdata->dev->lock);
581 priv->req = NULL; 580 priv->req = NULL;
582 priv->epdata = NULL; 581 priv->epdata = NULL;
583 if (NULL == iocb->ki_retry 582 if (priv->ubuf == NULL
584 || unlikely(0 == req->actual) 583 || unlikely(req->actual == 0)
585 || unlikely(kiocbIsCancelled(iocb))) { 584 || unlikely(kiocbIsCancelled(iocb))) {
586 kfree(req->buf); 585 kfree(req->buf);
587 kfree(priv); 586 kfree(priv);
@@ -618,7 +617,7 @@ ep_aio_rwtail(
618 char __user *ubuf 617 char __user *ubuf
619) 618)
620{ 619{
621 struct kiocb_priv *priv = (void *) &iocb->private; 620 struct kiocb_priv *priv;
622 struct usb_request *req; 621 struct usb_request *req;
623 ssize_t value; 622 ssize_t value;
624 623
@@ -670,7 +669,7 @@ fail:
670 kfree(priv); 669 kfree(priv);
671 put_ep(epdata); 670 put_ep(epdata);
672 } else 671 } else
673 value = -EIOCBQUEUED; 672 value = (ubuf ? -EIOCBRETRY : -EIOCBQUEUED);
674 return value; 673 return value;
675} 674}
676 675
@@ -1039,7 +1038,7 @@ scan:
1039 /* ep0 can't deliver events when STATE_SETUP */ 1038 /* ep0 can't deliver events when STATE_SETUP */
1040 for (i = 0; i < n; i++) { 1039 for (i = 0; i < n; i++) {
1041 if (dev->event [i].type == GADGETFS_SETUP) { 1040 if (dev->event [i].type == GADGETFS_SETUP) {
1042 len = n = i + 1; 1041 len = i + 1;
1043 len *= sizeof (struct usb_gadgetfs_event); 1042 len *= sizeof (struct usb_gadgetfs_event);
1044 n = 0; 1043 n = 0;
1045 break; 1044 break;
@@ -1587,13 +1586,13 @@ gadgetfs_create_file (struct super_block *sb, char const *name,
1587static int activate_ep_files (struct dev_data *dev) 1586static int activate_ep_files (struct dev_data *dev)
1588{ 1587{
1589 struct usb_ep *ep; 1588 struct usb_ep *ep;
1589 struct ep_data *data;
1590 1590
1591 gadget_for_each_ep (ep, dev->gadget) { 1591 gadget_for_each_ep (ep, dev->gadget) {
1592 struct ep_data *data;
1593 1592
1594 data = kzalloc(sizeof(*data), GFP_KERNEL); 1593 data = kzalloc(sizeof(*data), GFP_KERNEL);
1595 if (!data) 1594 if (!data)
1596 goto enomem; 1595 goto enomem0;
1597 data->state = STATE_EP_DISABLED; 1596 data->state = STATE_EP_DISABLED;
1598 init_MUTEX (&data->lock); 1597 init_MUTEX (&data->lock);
1599 init_waitqueue_head (&data->wait); 1598 init_waitqueue_head (&data->wait);
@@ -1608,21 +1607,23 @@ static int activate_ep_files (struct dev_data *dev)
1608 1607
1609 data->req = usb_ep_alloc_request (ep, GFP_KERNEL); 1608 data->req = usb_ep_alloc_request (ep, GFP_KERNEL);
1610 if (!data->req) 1609 if (!data->req)
1611 goto enomem; 1610 goto enomem1;
1612 1611
1613 data->inode = gadgetfs_create_file (dev->sb, data->name, 1612 data->inode = gadgetfs_create_file (dev->sb, data->name,
1614 data, &ep_config_operations, 1613 data, &ep_config_operations,
1615 &data->dentry); 1614 &data->dentry);
1616 if (!data->inode) { 1615 if (!data->inode)
1617 usb_ep_free_request(ep, data->req); 1616 goto enomem2;
1618 kfree (data);
1619 goto enomem;
1620 }
1621 list_add_tail (&data->epfiles, &dev->epfiles); 1617 list_add_tail (&data->epfiles, &dev->epfiles);
1622 } 1618 }
1623 return 0; 1619 return 0;
1624 1620
1625enomem: 1621enomem2:
1622 usb_ep_free_request (ep, data->req);
1623enomem1:
1624 put_dev (dev);
1625 kfree (data);
1626enomem0:
1626 DBG (dev, "%s enomem\n", __FUNCTION__); 1627 DBG (dev, "%s enomem\n", __FUNCTION__);
1627 destroy_ep_files (dev); 1628 destroy_ep_files (dev);
1628 return -ENOMEM; 1629 return -ENOMEM;
@@ -1793,7 +1794,7 @@ static struct usb_gadget_driver probe_driver = {
1793 * 1794 *
1794 * After initialization, the device stays active for as long as that 1795 * After initialization, the device stays active for as long as that
1795 * $CHIP file is open. Events may then be read from that descriptor, 1796 * $CHIP file is open. Events may then be read from that descriptor,
1796 * such configuration notifications. More complex drivers will handle 1797 * such as configuration notifications. More complex drivers will handle
1797 * some control requests in user space. 1798 * some control requests in user space.
1798 */ 1799 */
1799 1800
@@ -2033,12 +2034,10 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent)
2033 NULL, &simple_dir_operations, 2034 NULL, &simple_dir_operations,
2034 S_IFDIR | S_IRUGO | S_IXUGO); 2035 S_IFDIR | S_IRUGO | S_IXUGO);
2035 if (!inode) 2036 if (!inode)
2036 return -ENOMEM; 2037 goto enomem0;
2037 inode->i_op = &simple_dir_inode_operations; 2038 inode->i_op = &simple_dir_inode_operations;
2038 if (!(d = d_alloc_root (inode))) { 2039 if (!(d = d_alloc_root (inode)))
2039 iput (inode); 2040 goto enomem1;
2040 return -ENOMEM;
2041 }
2042 sb->s_root = d; 2041 sb->s_root = d;
2043 2042
2044 /* the ep0 file is named after the controller we expect; 2043 /* the ep0 file is named after the controller we expect;
@@ -2046,21 +2045,28 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent)
2046 */ 2045 */
2047 dev = dev_new (); 2046 dev = dev_new ();
2048 if (!dev) 2047 if (!dev)
2049 return -ENOMEM; 2048 goto enomem2;
2050 2049
2051 dev->sb = sb; 2050 dev->sb = sb;
2052 if (!(inode = gadgetfs_create_file (sb, CHIP, 2051 if (!gadgetfs_create_file (sb, CHIP,
2053 dev, &dev_init_operations, 2052 dev, &dev_init_operations,
2054 &dev->dentry))) { 2053 &dev->dentry))
2055 put_dev(dev); 2054 goto enomem3;
2056 return -ENOMEM;
2057 }
2058 2055
2059 /* other endpoint files are available after hardware setup, 2056 /* other endpoint files are available after hardware setup,
2060 * from binding to a controller. 2057 * from binding to a controller.
2061 */ 2058 */
2062 the_device = dev; 2059 the_device = dev;
2063 return 0; 2060 return 0;
2061
2062enomem3:
2063 put_dev (dev);
2064enomem2:
2065 dput (d);
2066enomem1:
2067 iput (inode);
2068enomem0:
2069 return -ENOMEM;
2064} 2070}
2065 2071
2066/* "mount -t gadgetfs path /dev/gadget" ends up here */ 2072/* "mount -t gadgetfs path /dev/gadget" ends up here */
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 020d3c42b1af..1facdea56a8a 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -2966,6 +2966,22 @@ done:
2966 return retval; 2966 return retval;
2967} 2967}
2968 2968
2969/* make sure the board is quiescent; otherwise it will continue
2970 * generating IRQs across the upcoming reboot.
2971 */
2972
2973static void net2280_shutdown (struct pci_dev *pdev)
2974{
2975 struct net2280 *dev = pci_get_drvdata (pdev);
2976
2977 /* disable IRQs */
2978 writel (0, &dev->regs->pciirqenb0);
2979 writel (0, &dev->regs->pciirqenb1);
2980
2981 /* disable the pullup so the host will think we're gone */
2982 writel (0, &dev->usb->usbctl);
2983}
2984
2969 2985
2970/*-------------------------------------------------------------------------*/ 2986/*-------------------------------------------------------------------------*/
2971 2987
@@ -2995,6 +3011,7 @@ static struct pci_driver net2280_pci_driver = {
2995 3011
2996 .probe = net2280_probe, 3012 .probe = net2280_probe,
2997 .remove = net2280_remove, 3013 .remove = net2280_remove,
3014 .shutdown = net2280_shutdown,
2998 3015
2999 /* FIXME add power management support */ 3016 /* FIXME add power management support */
3000}; 3017};
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 680f7fc5b171..269ce7f4ad66 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -53,12 +53,14 @@
53#include <asm/mach-types.h> 53#include <asm/mach-types.h>
54#include <asm/unaligned.h> 54#include <asm/unaligned.h>
55#include <asm/hardware.h> 55#include <asm/hardware.h>
56#ifdef CONFIG_ARCH_PXA
56#include <asm/arch/pxa-regs.h> 57#include <asm/arch/pxa-regs.h>
58#endif
57 59
58#include <linux/usb_ch9.h> 60#include <linux/usb_ch9.h>
59#include <linux/usb_gadget.h> 61#include <linux/usb_gadget.h>
60 62
61#include <asm/arch/udc.h> 63#include <asm/arch/hardware/intel_udc.h>
62 64
63 65
64/* 66/*
@@ -545,6 +547,7 @@ write_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req)
545 count = req->req.length; 547 count = req->req.length;
546 done (ep, req, 0); 548 done (ep, req, 0);
547 ep0_idle(ep->dev); 549 ep0_idle(ep->dev);
550#ifndef CONFIG_ARCH_IXP4XX
548#if 1 551#if 1
549 /* This seems to get rid of lost status irqs in some cases: 552 /* This seems to get rid of lost status irqs in some cases:
550 * host responds quickly, or next request involves config 553 * host responds quickly, or next request involves config
@@ -565,6 +568,7 @@ write_ep0_fifo (struct pxa2xx_ep *ep, struct pxa2xx_request *req)
565 } while (count); 568 } while (count);
566 } 569 }
567#endif 570#endif
571#endif
568 } else if (ep->dev->req_pending) 572 } else if (ep->dev->req_pending)
569 ep0start(ep->dev, 0, "IN"); 573 ep0start(ep->dev, 0, "IN");
570 return is_short; 574 return is_short;
@@ -1585,7 +1589,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
1585 int retval; 1589 int retval;
1586 1590
1587 if (!driver 1591 if (!driver
1588 || driver->speed != USB_SPEED_FULL 1592 || driver->speed < USB_SPEED_FULL
1589 || !driver->bind 1593 || !driver->bind
1590 || !driver->unbind 1594 || !driver->unbind
1591 || !driver->disconnect 1595 || !driver->disconnect
@@ -2427,6 +2431,7 @@ static struct pxa2xx_udc memory = {
2427#define PXA210_B1 0x00000123 2431#define PXA210_B1 0x00000123
2428#define PXA210_B0 0x00000122 2432#define PXA210_B0 0x00000122
2429#define IXP425_A0 0x000001c1 2433#define IXP425_A0 0x000001c1
2434#define IXP465_AD 0x00000200
2430 2435
2431/* 2436/*
2432 * probe - binds to the platform device 2437 * probe - binds to the platform device
@@ -2463,6 +2468,8 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
2463 break; 2468 break;
2464#elif defined(CONFIG_ARCH_IXP4XX) 2469#elif defined(CONFIG_ARCH_IXP4XX)
2465 case IXP425_A0: 2470 case IXP425_A0:
2471 case IXP465_AD:
2472 dev->has_cfr = 1;
2466 out_dma = 0; 2473 out_dma = 0;
2467 break; 2474 break;
2468#endif 2475#endif
@@ -2575,10 +2582,12 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
2575 free_irq(IRQ_USB, dev); 2582 free_irq(IRQ_USB, dev);
2576 dev->got_irq = 0; 2583 dev->got_irq = 0;
2577 } 2584 }
2585#ifdef CONFIG_ARCH_LUBBOCK
2578 if (machine_is_lubbock()) { 2586 if (machine_is_lubbock()) {
2579 free_irq(LUBBOCK_USB_DISC_IRQ, dev); 2587 free_irq(LUBBOCK_USB_DISC_IRQ, dev);
2580 free_irq(LUBBOCK_USB_IRQ, dev); 2588 free_irq(LUBBOCK_USB_IRQ, dev);
2581 } 2589 }
2590#endif
2582 platform_set_drvdata(pdev, NULL); 2591 platform_set_drvdata(pdev, NULL);
2583 the_controller = NULL; 2592 the_controller = NULL;
2584 return 0; 2593 return 0;
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 6d6eaad73968..3ff6db7828a0 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -1,23 +1,23 @@
1/* 1/*
2 * RNDIS MSG parser 2 * RNDIS MSG parser
3 * 3 *
4 * Version: $Id: rndis.c,v 1.19 2004/03/25 21:33:46 robert Exp $ 4 * Version: $Id: rndis.c,v 1.19 2004/03/25 21:33:46 robert Exp $
5 * 5 *
6 * Authors: Benedikt Spranger, Pengutronix 6 * Authors: Benedikt Spranger, Pengutronix
7 * Robert Schwebel, Pengutronix 7 * Robert Schwebel, Pengutronix
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
11 * version 2, as published by the Free Software Foundation. 11 * version 2, as published by the Free Software Foundation.
12 * 12 *
13 * This software was originally developed in conformance with 13 * This software was originally developed in conformance with
14 * Microsoft's Remote NDIS Specification License Agreement. 14 * Microsoft's Remote NDIS Specification License Agreement.
15 * 15 *
16 * 03/12/2004 Kai-Uwe Bloem <linux-development@auerswald.de> 16 * 03/12/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
17 * Fixed message length bug in init_response 17 * Fixed message length bug in init_response
18 * 18 *
19 * 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de> 19 * 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
20 * Fixed rndis_rm_hdr length bug. 20 * Fixed rndis_rm_hdr length bug.
21 * 21 *
22 * Copyright (C) 2004 by David Brownell 22 * Copyright (C) 2004 by David Brownell
23 * updates to merge with Linux 2.6, better match RNDIS spec 23 * updates to merge with Linux 2.6, better match RNDIS spec
@@ -82,7 +82,7 @@ static rndis_resp_t *rndis_add_response (int configNr, u32 length);
82 82
83 83
84/* supported OIDs */ 84/* supported OIDs */
85static const u32 oid_supported_list [] = 85static const u32 oid_supported_list [] =
86{ 86{
87 /* the general stuff */ 87 /* the general stuff */
88 OID_GEN_SUPPORTED_LIST, 88 OID_GEN_SUPPORTED_LIST,
@@ -103,7 +103,7 @@ static const u32 oid_supported_list [] =
103#if 0 103#if 0
104 OID_GEN_RNDIS_CONFIG_PARAMETER, 104 OID_GEN_RNDIS_CONFIG_PARAMETER,
105#endif 105#endif
106 106
107 /* the statistical stuff */ 107 /* the statistical stuff */
108 OID_GEN_XMIT_OK, 108 OID_GEN_XMIT_OK,
109 OID_GEN_RCV_OK, 109 OID_GEN_RCV_OK,
@@ -127,14 +127,14 @@ static const u32 oid_supported_list [] =
127 OID_GEN_TRANSMIT_QUEUE_LENGTH, 127 OID_GEN_TRANSMIT_QUEUE_LENGTH,
128#endif /* RNDIS_OPTIONAL_STATS */ 128#endif /* RNDIS_OPTIONAL_STATS */
129 129
130 /* mandatory 802.3 */ 130 /* mandatory 802.3 */
131 /* the general stuff */ 131 /* the general stuff */
132 OID_802_3_PERMANENT_ADDRESS, 132 OID_802_3_PERMANENT_ADDRESS,
133 OID_802_3_CURRENT_ADDRESS, 133 OID_802_3_CURRENT_ADDRESS,
134 OID_802_3_MULTICAST_LIST, 134 OID_802_3_MULTICAST_LIST,
135 OID_802_3_MAC_OPTIONS, 135 OID_802_3_MAC_OPTIONS,
136 OID_802_3_MAXIMUM_LIST_SIZE, 136 OID_802_3_MAXIMUM_LIST_SIZE,
137 137
138 /* the statistical stuff */ 138 /* the statistical stuff */
139 OID_802_3_RCV_ERROR_ALIGNMENT, 139 OID_802_3_RCV_ERROR_ALIGNMENT,
140 OID_802_3_XMIT_ONE_COLLISION, 140 OID_802_3_XMIT_ONE_COLLISION,
@@ -172,8 +172,8 @@ static int
172gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, 172gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
173 rndis_resp_t *r) 173 rndis_resp_t *r)
174{ 174{
175 int retval = -ENOTSUPP; 175 int retval = -ENOTSUPP;
176 u32 length = 4; /* usually */ 176 u32 length = 4; /* usually */
177 __le32 *outbuf; 177 __le32 *outbuf;
178 int i, count; 178 int i, count;
179 rndis_query_cmplt_type *resp; 179 rndis_query_cmplt_type *resp;
@@ -211,27 +211,27 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
211 outbuf[i] = cpu_to_le32 (oid_supported_list[i]); 211 outbuf[i] = cpu_to_le32 (oid_supported_list[i]);
212 retval = 0; 212 retval = 0;
213 break; 213 break;
214 214
215 /* mandatory */ 215 /* mandatory */
216 case OID_GEN_HARDWARE_STATUS: 216 case OID_GEN_HARDWARE_STATUS:
217 DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__); 217 DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__);
218 /* Bogus question! 218 /* Bogus question!
219 * Hardware must be ready to receive high level protocols. 219 * Hardware must be ready to receive high level protocols.
220 * BTW: 220 * BTW:
221 * reddite ergo quae sunt Caesaris Caesari 221 * reddite ergo quae sunt Caesaris Caesari
222 * et quae sunt Dei Deo! 222 * et quae sunt Dei Deo!
223 */ 223 */
224 *outbuf = __constant_cpu_to_le32 (0); 224 *outbuf = __constant_cpu_to_le32 (0);
225 retval = 0; 225 retval = 0;
226 break; 226 break;
227 227
228 /* mandatory */ 228 /* mandatory */
229 case OID_GEN_MEDIA_SUPPORTED: 229 case OID_GEN_MEDIA_SUPPORTED:
230 DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__); 230 DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__);
231 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); 231 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
232 retval = 0; 232 retval = 0;
233 break; 233 break;
234 234
235 /* mandatory */ 235 /* mandatory */
236 case OID_GEN_MEDIA_IN_USE: 236 case OID_GEN_MEDIA_IN_USE:
237 DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__); 237 DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__);
@@ -239,7 +239,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
239 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium); 239 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
240 retval = 0; 240 retval = 0;
241 break; 241 break;
242 242
243 /* mandatory */ 243 /* mandatory */
244 case OID_GEN_MAXIMUM_FRAME_SIZE: 244 case OID_GEN_MAXIMUM_FRAME_SIZE:
245 DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__); 245 DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__);
@@ -249,7 +249,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
249 retval = 0; 249 retval = 0;
250 } 250 }
251 break; 251 break;
252 252
253 /* mandatory */ 253 /* mandatory */
254 case OID_GEN_LINK_SPEED: 254 case OID_GEN_LINK_SPEED:
255 if (rndis_debug > 1) 255 if (rndis_debug > 1)
@@ -272,7 +272,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
272 retval = 0; 272 retval = 0;
273 } 273 }
274 break; 274 break;
275 275
276 /* mandatory */ 276 /* mandatory */
277 case OID_GEN_RECEIVE_BLOCK_SIZE: 277 case OID_GEN_RECEIVE_BLOCK_SIZE:
278 DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__); 278 DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__);
@@ -282,7 +282,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
282 retval = 0; 282 retval = 0;
283 } 283 }
284 break; 284 break;
285 285
286 /* mandatory */ 286 /* mandatory */
287 case OID_GEN_VENDOR_ID: 287 case OID_GEN_VENDOR_ID:
288 DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__); 288 DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__);
@@ -290,7 +290,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
290 rndis_per_dev_params [configNr].vendorID); 290 rndis_per_dev_params [configNr].vendorID);
291 retval = 0; 291 retval = 0;
292 break; 292 break;
293 293
294 /* mandatory */ 294 /* mandatory */
295 case OID_GEN_VENDOR_DESCRIPTION: 295 case OID_GEN_VENDOR_DESCRIPTION:
296 DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__); 296 DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__);
@@ -356,7 +356,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
356 DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__); 356 DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
357 if (rndis_per_dev_params [configNr].stats) { 357 if (rndis_per_dev_params [configNr].stats) {
358 *outbuf = cpu_to_le32 ( 358 *outbuf = cpu_to_le32 (
359 rndis_per_dev_params [configNr].stats->tx_packets - 359 rndis_per_dev_params [configNr].stats->tx_packets -
360 rndis_per_dev_params [configNr].stats->tx_errors - 360 rndis_per_dev_params [configNr].stats->tx_errors -
361 rndis_per_dev_params [configNr].stats->tx_dropped); 361 rndis_per_dev_params [configNr].stats->tx_dropped);
362 retval = 0; 362 retval = 0;
@@ -369,13 +369,13 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
369 DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__); 369 DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
370 if (rndis_per_dev_params [configNr].stats) { 370 if (rndis_per_dev_params [configNr].stats) {
371 *outbuf = cpu_to_le32 ( 371 *outbuf = cpu_to_le32 (
372 rndis_per_dev_params [configNr].stats->rx_packets - 372 rndis_per_dev_params [configNr].stats->rx_packets -
373 rndis_per_dev_params [configNr].stats->rx_errors - 373 rndis_per_dev_params [configNr].stats->rx_errors -
374 rndis_per_dev_params [configNr].stats->rx_dropped); 374 rndis_per_dev_params [configNr].stats->rx_dropped);
375 retval = 0; 375 retval = 0;
376 } 376 }
377 break; 377 break;
378 378
379 /* mandatory */ 379 /* mandatory */
380 case OID_GEN_XMIT_ERROR: 380 case OID_GEN_XMIT_ERROR:
381 if (rndis_debug > 1) 381 if (rndis_debug > 1)
@@ -386,7 +386,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
386 retval = 0; 386 retval = 0;
387 } 387 }
388 break; 388 break;
389 389
390 /* mandatory */ 390 /* mandatory */
391 case OID_GEN_RCV_ERROR: 391 case OID_GEN_RCV_ERROR:
392 if (rndis_debug > 1) 392 if (rndis_debug > 1)
@@ -397,7 +397,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
397 retval = 0; 397 retval = 0;
398 } 398 }
399 break; 399 break;
400 400
401 /* mandatory */ 401 /* mandatory */
402 case OID_GEN_RCV_NO_BUFFER: 402 case OID_GEN_RCV_NO_BUFFER:
403 DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__); 403 DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__);
@@ -411,7 +411,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
411#ifdef RNDIS_OPTIONAL_STATS 411#ifdef RNDIS_OPTIONAL_STATS
412 case OID_GEN_DIRECTED_BYTES_XMIT: 412 case OID_GEN_DIRECTED_BYTES_XMIT:
413 DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__); 413 DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__);
414 /* 414 /*
415 * Aunt Tilly's size of shoes 415 * Aunt Tilly's size of shoes
416 * minus antarctica count of penguins 416 * minus antarctica count of penguins
417 * divided by weight of Alpha Centauri 417 * divided by weight of Alpha Centauri
@@ -419,7 +419,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
419 if (rndis_per_dev_params [configNr].stats) { 419 if (rndis_per_dev_params [configNr].stats) {
420 *outbuf = cpu_to_le32 ( 420 *outbuf = cpu_to_le32 (
421 (rndis_per_dev_params [configNr] 421 (rndis_per_dev_params [configNr]
422 .stats->tx_packets - 422 .stats->tx_packets -
423 rndis_per_dev_params [configNr] 423 rndis_per_dev_params [configNr]
424 .stats->tx_errors - 424 .stats->tx_errors -
425 rndis_per_dev_params [configNr] 425 rndis_per_dev_params [configNr]
@@ -428,14 +428,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
428 retval = 0; 428 retval = 0;
429 } 429 }
430 break; 430 break;
431 431
432 case OID_GEN_DIRECTED_FRAMES_XMIT: 432 case OID_GEN_DIRECTED_FRAMES_XMIT:
433 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__); 433 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__);
434 /* dito */ 434 /* dito */
435 if (rndis_per_dev_params [configNr].stats) { 435 if (rndis_per_dev_params [configNr].stats) {
436 *outbuf = cpu_to_le32 ( 436 *outbuf = cpu_to_le32 (
437 (rndis_per_dev_params [configNr] 437 (rndis_per_dev_params [configNr]
438 .stats->tx_packets - 438 .stats->tx_packets -
439 rndis_per_dev_params [configNr] 439 rndis_per_dev_params [configNr]
440 .stats->tx_errors - 440 .stats->tx_errors -
441 rndis_per_dev_params [configNr] 441 rndis_per_dev_params [configNr]
@@ -444,7 +444,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
444 retval = 0; 444 retval = 0;
445 } 445 }
446 break; 446 break;
447 447
448 case OID_GEN_MULTICAST_BYTES_XMIT: 448 case OID_GEN_MULTICAST_BYTES_XMIT:
449 DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__); 449 DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__);
450 if (rndis_per_dev_params [configNr].stats) { 450 if (rndis_per_dev_params [configNr].stats) {
@@ -453,7 +453,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
453 retval = 0; 453 retval = 0;
454 } 454 }
455 break; 455 break;
456 456
457 case OID_GEN_MULTICAST_FRAMES_XMIT: 457 case OID_GEN_MULTICAST_FRAMES_XMIT:
458 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__); 458 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__);
459 if (rndis_per_dev_params [configNr].stats) { 459 if (rndis_per_dev_params [configNr].stats) {
@@ -462,7 +462,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
462 retval = 0; 462 retval = 0;
463 } 463 }
464 break; 464 break;
465 465
466 case OID_GEN_BROADCAST_BYTES_XMIT: 466 case OID_GEN_BROADCAST_BYTES_XMIT:
467 DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__); 467 DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__);
468 if (rndis_per_dev_params [configNr].stats) { 468 if (rndis_per_dev_params [configNr].stats) {
@@ -471,7 +471,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
471 retval = 0; 471 retval = 0;
472 } 472 }
473 break; 473 break;
474 474
475 case OID_GEN_BROADCAST_FRAMES_XMIT: 475 case OID_GEN_BROADCAST_FRAMES_XMIT:
476 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__); 476 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__);
477 if (rndis_per_dev_params [configNr].stats) { 477 if (rndis_per_dev_params [configNr].stats) {
@@ -480,19 +480,19 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
480 retval = 0; 480 retval = 0;
481 } 481 }
482 break; 482 break;
483 483
484 case OID_GEN_DIRECTED_BYTES_RCV: 484 case OID_GEN_DIRECTED_BYTES_RCV:
485 DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__); 485 DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__);
486 *outbuf = __constant_cpu_to_le32 (0); 486 *outbuf = __constant_cpu_to_le32 (0);
487 retval = 0; 487 retval = 0;
488 break; 488 break;
489 489
490 case OID_GEN_DIRECTED_FRAMES_RCV: 490 case OID_GEN_DIRECTED_FRAMES_RCV:
491 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__); 491 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__);
492 *outbuf = __constant_cpu_to_le32 (0); 492 *outbuf = __constant_cpu_to_le32 (0);
493 retval = 0; 493 retval = 0;
494 break; 494 break;
495 495
496 case OID_GEN_MULTICAST_BYTES_RCV: 496 case OID_GEN_MULTICAST_BYTES_RCV:
497 DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__); 497 DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__);
498 if (rndis_per_dev_params [configNr].stats) { 498 if (rndis_per_dev_params [configNr].stats) {
@@ -501,7 +501,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
501 retval = 0; 501 retval = 0;
502 } 502 }
503 break; 503 break;
504 504
505 case OID_GEN_MULTICAST_FRAMES_RCV: 505 case OID_GEN_MULTICAST_FRAMES_RCV:
506 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__); 506 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__);
507 if (rndis_per_dev_params [configNr].stats) { 507 if (rndis_per_dev_params [configNr].stats) {
@@ -510,7 +510,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
510 retval = 0; 510 retval = 0;
511 } 511 }
512 break; 512 break;
513 513
514 case OID_GEN_BROADCAST_BYTES_RCV: 514 case OID_GEN_BROADCAST_BYTES_RCV:
515 DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__); 515 DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__);
516 if (rndis_per_dev_params [configNr].stats) { 516 if (rndis_per_dev_params [configNr].stats) {
@@ -519,7 +519,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
519 retval = 0; 519 retval = 0;
520 } 520 }
521 break; 521 break;
522 522
523 case OID_GEN_BROADCAST_FRAMES_RCV: 523 case OID_GEN_BROADCAST_FRAMES_RCV:
524 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__); 524 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__);
525 if (rndis_per_dev_params [configNr].stats) { 525 if (rndis_per_dev_params [configNr].stats) {
@@ -528,7 +528,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
528 retval = 0; 528 retval = 0;
529 } 529 }
530 break; 530 break;
531 531
532 case OID_GEN_RCV_CRC_ERROR: 532 case OID_GEN_RCV_CRC_ERROR:
533 DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__); 533 DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__);
534 if (rndis_per_dev_params [configNr].stats) { 534 if (rndis_per_dev_params [configNr].stats) {
@@ -537,7 +537,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
537 retval = 0; 537 retval = 0;
538 } 538 }
539 break; 539 break;
540 540
541 case OID_GEN_TRANSMIT_QUEUE_LENGTH: 541 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
542 DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__); 542 DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__);
543 *outbuf = __constant_cpu_to_le32 (0); 543 *outbuf = __constant_cpu_to_le32 (0);
@@ -558,7 +558,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
558 retval = 0; 558 retval = 0;
559 } 559 }
560 break; 560 break;
561 561
562 /* mandatory */ 562 /* mandatory */
563 case OID_802_3_CURRENT_ADDRESS: 563 case OID_802_3_CURRENT_ADDRESS:
564 DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__); 564 DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__);
@@ -570,7 +570,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
570 retval = 0; 570 retval = 0;
571 } 571 }
572 break; 572 break;
573 573
574 /* mandatory */ 574 /* mandatory */
575 case OID_802_3_MULTICAST_LIST: 575 case OID_802_3_MULTICAST_LIST:
576 DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); 576 DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
@@ -578,7 +578,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
578 *outbuf = __constant_cpu_to_le32 (0xE0000000); 578 *outbuf = __constant_cpu_to_le32 (0xE0000000);
579 retval = 0; 579 retval = 0;
580 break; 580 break;
581 581
582 /* mandatory */ 582 /* mandatory */
583 case OID_802_3_MAXIMUM_LIST_SIZE: 583 case OID_802_3_MAXIMUM_LIST_SIZE:
584 DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__); 584 DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__);
@@ -586,7 +586,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
586 *outbuf = __constant_cpu_to_le32 (1); 586 *outbuf = __constant_cpu_to_le32 (1);
587 retval = 0; 587 retval = 0;
588 break; 588 break;
589 589
590 case OID_802_3_MAC_OPTIONS: 590 case OID_802_3_MAC_OPTIONS:
591 DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__); 591 DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__);
592 break; 592 break;
@@ -602,56 +602,56 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
602 retval = 0; 602 retval = 0;
603 } 603 }
604 break; 604 break;
605 605
606 /* mandatory */ 606 /* mandatory */
607 case OID_802_3_XMIT_ONE_COLLISION: 607 case OID_802_3_XMIT_ONE_COLLISION:
608 DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__); 608 DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__);
609 *outbuf = __constant_cpu_to_le32 (0); 609 *outbuf = __constant_cpu_to_le32 (0);
610 retval = 0; 610 retval = 0;
611 break; 611 break;
612 612
613 /* mandatory */ 613 /* mandatory */
614 case OID_802_3_XMIT_MORE_COLLISIONS: 614 case OID_802_3_XMIT_MORE_COLLISIONS:
615 DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__); 615 DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__);
616 *outbuf = __constant_cpu_to_le32 (0); 616 *outbuf = __constant_cpu_to_le32 (0);
617 retval = 0; 617 retval = 0;
618 break; 618 break;
619 619
620#ifdef RNDIS_OPTIONAL_STATS 620#ifdef RNDIS_OPTIONAL_STATS
621 case OID_802_3_XMIT_DEFERRED: 621 case OID_802_3_XMIT_DEFERRED:
622 DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__); 622 DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__);
623 /* TODO */ 623 /* TODO */
624 break; 624 break;
625 625
626 case OID_802_3_XMIT_MAX_COLLISIONS: 626 case OID_802_3_XMIT_MAX_COLLISIONS:
627 DEBUG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__); 627 DEBUG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__);
628 /* TODO */ 628 /* TODO */
629 break; 629 break;
630 630
631 case OID_802_3_RCV_OVERRUN: 631 case OID_802_3_RCV_OVERRUN:
632 DEBUG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__); 632 DEBUG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__);
633 /* TODO */ 633 /* TODO */
634 break; 634 break;
635 635
636 case OID_802_3_XMIT_UNDERRUN: 636 case OID_802_3_XMIT_UNDERRUN:
637 DEBUG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__); 637 DEBUG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__);
638 /* TODO */ 638 /* TODO */
639 break; 639 break;
640 640
641 case OID_802_3_XMIT_HEARTBEAT_FAILURE: 641 case OID_802_3_XMIT_HEARTBEAT_FAILURE:
642 DEBUG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__); 642 DEBUG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__);
643 /* TODO */ 643 /* TODO */
644 break; 644 break;
645 645
646 case OID_802_3_XMIT_TIMES_CRS_LOST: 646 case OID_802_3_XMIT_TIMES_CRS_LOST:
647 DEBUG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__); 647 DEBUG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__);
648 /* TODO */ 648 /* TODO */
649 break; 649 break;
650 650
651 case OID_802_3_XMIT_LATE_COLLISIONS: 651 case OID_802_3_XMIT_LATE_COLLISIONS:
652 DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__); 652 DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__);
653 /* TODO */ 653 /* TODO */
654 break; 654 break;
655#endif /* RNDIS_OPTIONAL_STATS */ 655#endif /* RNDIS_OPTIONAL_STATS */
656 656
657#ifdef RNDIS_PM 657#ifdef RNDIS_PM
@@ -676,23 +676,23 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
676#endif 676#endif
677 677
678 default: 678 default:
679 printk (KERN_WARNING "%s: query unknown OID 0x%08X\n", 679 printk (KERN_WARNING "%s: query unknown OID 0x%08X\n",
680 __FUNCTION__, OID); 680 __FUNCTION__, OID);
681 } 681 }
682 if (retval < 0) 682 if (retval < 0)
683 length = 0; 683 length = 0;
684 684
685 resp->InformationBufferLength = cpu_to_le32 (length); 685 resp->InformationBufferLength = cpu_to_le32 (length);
686 r->length = length + sizeof *resp; 686 r->length = length + sizeof *resp;
687 resp->MessageLength = cpu_to_le32 (r->length); 687 resp->MessageLength = cpu_to_le32 (r->length);
688 return retval; 688 return retval;
689} 689}
690 690
691static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, 691static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
692 rndis_resp_t *r) 692 rndis_resp_t *r)
693{ 693{
694 rndis_set_cmplt_type *resp; 694 rndis_set_cmplt_type *resp;
695 int i, retval = -ENOTSUPP; 695 int i, retval = -ENOTSUPP;
696 struct rndis_params *params; 696 struct rndis_params *params;
697 697
698 if (!r) 698 if (!r)
@@ -745,9 +745,9 @@ update_linkstate:
745 netif_stop_queue (params->dev); 745 netif_stop_queue (params->dev);
746 } 746 }
747 break; 747 break;
748 748
749 case OID_802_3_MULTICAST_LIST: 749 case OID_802_3_MULTICAST_LIST:
750 /* I think we can ignore this */ 750 /* I think we can ignore this */
751 DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); 751 DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
752 retval = 0; 752 retval = 0;
753 break; 753 break;
@@ -796,29 +796,29 @@ update_linkstate:
796#endif /* RNDIS_PM */ 796#endif /* RNDIS_PM */
797 797
798 default: 798 default:
799 printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n", 799 printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n",
800 __FUNCTION__, OID, buf_len); 800 __FUNCTION__, OID, buf_len);
801 } 801 }
802 802
803 return retval; 803 return retval;
804} 804}
805 805
806/* 806/*
807 * Response Functions 807 * Response Functions
808 */ 808 */
809 809
810static int rndis_init_response (int configNr, rndis_init_msg_type *buf) 810static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
811{ 811{
812 rndis_init_cmplt_type *resp; 812 rndis_init_cmplt_type *resp;
813 rndis_resp_t *r; 813 rndis_resp_t *r;
814 814
815 if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; 815 if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
816 816
817 r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type)); 817 r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type));
818 if (!r) 818 if (!r)
819 return -ENOMEM; 819 return -ENOMEM;
820 resp = (rndis_init_cmplt_type *) r->buf; 820 resp = (rndis_init_cmplt_type *) r->buf;
821 821
822 resp->MessageType = __constant_cpu_to_le32 ( 822 resp->MessageType = __constant_cpu_to_le32 (
823 REMOTE_NDIS_INITIALIZE_CMPLT); 823 REMOTE_NDIS_INITIALIZE_CMPLT);
824 resp->MessageLength = __constant_cpu_to_le32 (52); 824 resp->MessageLength = __constant_cpu_to_le32 (52);
@@ -837,11 +837,11 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
837 resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0); 837 resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0);
838 resp->AFListOffset = __constant_cpu_to_le32 (0); 838 resp->AFListOffset = __constant_cpu_to_le32 (0);
839 resp->AFListSize = __constant_cpu_to_le32 (0); 839 resp->AFListSize = __constant_cpu_to_le32 (0);
840 840
841 if (rndis_per_dev_params [configNr].ack) 841 if (rndis_per_dev_params [configNr].ack)
842 rndis_per_dev_params [configNr].ack ( 842 rndis_per_dev_params [configNr].ack (
843 rndis_per_dev_params [configNr].dev); 843 rndis_per_dev_params [configNr].dev);
844 844
845 return 0; 845 return 0;
846} 846}
847 847
@@ -849,10 +849,10 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
849{ 849{
850 rndis_query_cmplt_type *resp; 850 rndis_query_cmplt_type *resp;
851 rndis_resp_t *r; 851 rndis_resp_t *r;
852 852
853 // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID)); 853 // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID));
854 if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; 854 if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
855 855
856 /* 856 /*
857 * we need more memory: 857 * we need more memory:
858 * gen_ndis_query_resp expects enough space for 858 * gen_ndis_query_resp expects enough space for
@@ -864,10 +864,10 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
864 if (!r) 864 if (!r)
865 return -ENOMEM; 865 return -ENOMEM;
866 resp = (rndis_query_cmplt_type *) r->buf; 866 resp = (rndis_query_cmplt_type *) r->buf;
867 867
868 resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT); 868 resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT);
869 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ 869 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
870 870
871 if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID), 871 if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID),
872 le32_to_cpu(buf->InformationBufferOffset) 872 le32_to_cpu(buf->InformationBufferOffset)
873 + 8 + (u8 *) buf, 873 + 8 + (u8 *) buf,
@@ -881,10 +881,10 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
881 resp->InformationBufferOffset = __constant_cpu_to_le32 (0); 881 resp->InformationBufferOffset = __constant_cpu_to_le32 (0);
882 } else 882 } else
883 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); 883 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
884 884
885 if (rndis_per_dev_params [configNr].ack) 885 if (rndis_per_dev_params [configNr].ack)
886 rndis_per_dev_params [configNr].ack ( 886 rndis_per_dev_params [configNr].ack (
887 rndis_per_dev_params [configNr].dev); 887 rndis_per_dev_params [configNr].dev);
888 return 0; 888 return 0;
889} 889}
890 890
@@ -893,7 +893,7 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
893 u32 BufLength, BufOffset; 893 u32 BufLength, BufOffset;
894 rndis_set_cmplt_type *resp; 894 rndis_set_cmplt_type *resp;
895 rndis_resp_t *r; 895 rndis_resp_t *r;
896 896
897 r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type)); 897 r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
898 if (!r) 898 if (!r)
899 return -ENOMEM; 899 return -ENOMEM;
@@ -906,26 +906,27 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
906 DEBUG("%s: Length: %d\n", __FUNCTION__, BufLength); 906 DEBUG("%s: Length: %d\n", __FUNCTION__, BufLength);
907 DEBUG("%s: Offset: %d\n", __FUNCTION__, BufOffset); 907 DEBUG("%s: Offset: %d\n", __FUNCTION__, BufOffset);
908 DEBUG("%s: InfoBuffer: ", __FUNCTION__); 908 DEBUG("%s: InfoBuffer: ", __FUNCTION__);
909 909
910 for (i = 0; i < BufLength; i++) { 910 for (i = 0; i < BufLength; i++) {
911 DEBUG ("%02x ", *(((u8 *) buf) + i + 8 + BufOffset)); 911 DEBUG ("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
912 } 912 }
913 913
914 DEBUG ("\n"); 914 DEBUG ("\n");
915#endif 915#endif
916 916
917 resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT); 917 resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
918 resp->MessageLength = __constant_cpu_to_le32 (16); 918 resp->MessageLength = __constant_cpu_to_le32 (16);
919 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ 919 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
920 if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID), 920 if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID),
921 ((u8 *) buf) + 8 + BufOffset, BufLength, r)) 921 ((u8 *) buf) + 8 + BufOffset, BufLength, r))
922 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED); 922 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED);
923 else resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); 923 else
924 924 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
925
925 if (rndis_per_dev_params [configNr].ack) 926 if (rndis_per_dev_params [configNr].ack)
926 rndis_per_dev_params [configNr].ack ( 927 rndis_per_dev_params [configNr].ack (
927 rndis_per_dev_params [configNr].dev); 928 rndis_per_dev_params [configNr].dev);
928 929
929 return 0; 930 return 0;
930} 931}
931 932
@@ -933,27 +934,27 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
933{ 934{
934 rndis_reset_cmplt_type *resp; 935 rndis_reset_cmplt_type *resp;
935 rndis_resp_t *r; 936 rndis_resp_t *r;
936 937
937 r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type)); 938 r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type));
938 if (!r) 939 if (!r)
939 return -ENOMEM; 940 return -ENOMEM;
940 resp = (rndis_reset_cmplt_type *) r->buf; 941 resp = (rndis_reset_cmplt_type *) r->buf;
941 942
942 resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT); 943 resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);
943 resp->MessageLength = __constant_cpu_to_le32 (16); 944 resp->MessageLength = __constant_cpu_to_le32 (16);
944 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); 945 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
945 /* resent information */ 946 /* resent information */
946 resp->AddressingReset = __constant_cpu_to_le32 (1); 947 resp->AddressingReset = __constant_cpu_to_le32 (1);
947 948
948 if (rndis_per_dev_params [configNr].ack) 949 if (rndis_per_dev_params [configNr].ack)
949 rndis_per_dev_params [configNr].ack ( 950 rndis_per_dev_params [configNr].ack (
950 rndis_per_dev_params [configNr].dev); 951 rndis_per_dev_params [configNr].dev);
951 952
952 return 0; 953 return 0;
953} 954}
954 955
955static int rndis_keepalive_response (int configNr, 956static int rndis_keepalive_response (int configNr,
956 rndis_keepalive_msg_type *buf) 957 rndis_keepalive_msg_type *buf)
957{ 958{
958 rndis_keepalive_cmplt_type *resp; 959 rndis_keepalive_cmplt_type *resp;
959 rndis_resp_t *r; 960 rndis_resp_t *r;
@@ -964,48 +965,48 @@ static int rndis_keepalive_response (int configNr,
964 if (!r) 965 if (!r)
965 return -ENOMEM; 966 return -ENOMEM;
966 resp = (rndis_keepalive_cmplt_type *) r->buf; 967 resp = (rndis_keepalive_cmplt_type *) r->buf;
967 968
968 resp->MessageType = __constant_cpu_to_le32 ( 969 resp->MessageType = __constant_cpu_to_le32 (
969 REMOTE_NDIS_KEEPALIVE_CMPLT); 970 REMOTE_NDIS_KEEPALIVE_CMPLT);
970 resp->MessageLength = __constant_cpu_to_le32 (16); 971 resp->MessageLength = __constant_cpu_to_le32 (16);
971 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ 972 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
972 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); 973 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
973 974
974 if (rndis_per_dev_params [configNr].ack) 975 if (rndis_per_dev_params [configNr].ack)
975 rndis_per_dev_params [configNr].ack ( 976 rndis_per_dev_params [configNr].ack (
976 rndis_per_dev_params [configNr].dev); 977 rndis_per_dev_params [configNr].dev);
977 978
978 return 0; 979 return 0;
979} 980}
980 981
981 982
982/* 983/*
983 * Device to Host Comunication 984 * Device to Host Comunication
984 */ 985 */
985static int rndis_indicate_status_msg (int configNr, u32 status) 986static int rndis_indicate_status_msg (int configNr, u32 status)
986{ 987{
987 rndis_indicate_status_msg_type *resp; 988 rndis_indicate_status_msg_type *resp;
988 rndis_resp_t *r; 989 rndis_resp_t *r;
989 990
990 if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED) 991 if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED)
991 return -ENOTSUPP; 992 return -ENOTSUPP;
992 993
993 r = rndis_add_response (configNr, 994 r = rndis_add_response (configNr,
994 sizeof (rndis_indicate_status_msg_type)); 995 sizeof (rndis_indicate_status_msg_type));
995 if (!r) 996 if (!r)
996 return -ENOMEM; 997 return -ENOMEM;
997 resp = (rndis_indicate_status_msg_type *) r->buf; 998 resp = (rndis_indicate_status_msg_type *) r->buf;
998 999
999 resp->MessageType = __constant_cpu_to_le32 ( 1000 resp->MessageType = __constant_cpu_to_le32 (
1000 REMOTE_NDIS_INDICATE_STATUS_MSG); 1001 REMOTE_NDIS_INDICATE_STATUS_MSG);
1001 resp->MessageLength = __constant_cpu_to_le32 (20); 1002 resp->MessageLength = __constant_cpu_to_le32 (20);
1002 resp->Status = cpu_to_le32 (status); 1003 resp->Status = cpu_to_le32 (status);
1003 resp->StatusBufferLength = __constant_cpu_to_le32 (0); 1004 resp->StatusBufferLength = __constant_cpu_to_le32 (0);
1004 resp->StatusBufferOffset = __constant_cpu_to_le32 (0); 1005 resp->StatusBufferOffset = __constant_cpu_to_le32 (0);
1005 1006
1006 if (rndis_per_dev_params [configNr].ack) 1007 if (rndis_per_dev_params [configNr].ack)
1007 rndis_per_dev_params [configNr].ack ( 1008 rndis_per_dev_params [configNr].ack (
1008 rndis_per_dev_params [configNr].dev); 1009 rndis_per_dev_params [configNr].dev);
1009 return 0; 1010 return 0;
1010} 1011}
1011 1012
@@ -1013,7 +1014,7 @@ int rndis_signal_connect (int configNr)
1013{ 1014{
1014 rndis_per_dev_params [configNr].media_state 1015 rndis_per_dev_params [configNr].media_state
1015 = NDIS_MEDIA_STATE_CONNECTED; 1016 = NDIS_MEDIA_STATE_CONNECTED;
1016 return rndis_indicate_status_msg (configNr, 1017 return rndis_indicate_status_msg (configNr,
1017 RNDIS_STATUS_MEDIA_CONNECT); 1018 RNDIS_STATUS_MEDIA_CONNECT);
1018} 1019}
1019 1020
@@ -1045,26 +1046,26 @@ void rndis_set_host_mac (int configNr, const u8 *addr)
1045 rndis_per_dev_params [configNr].host_mac = addr; 1046 rndis_per_dev_params [configNr].host_mac = addr;
1046} 1047}
1047 1048
1048/* 1049/*
1049 * Message Parser 1050 * Message Parser
1050 */ 1051 */
1051int rndis_msg_parser (u8 configNr, u8 *buf) 1052int rndis_msg_parser (u8 configNr, u8 *buf)
1052{ 1053{
1053 u32 MsgType, MsgLength; 1054 u32 MsgType, MsgLength;
1054 __le32 *tmp; 1055 __le32 *tmp;
1055 struct rndis_params *params; 1056 struct rndis_params *params;
1056 1057
1057 if (!buf) 1058 if (!buf)
1058 return -ENOMEM; 1059 return -ENOMEM;
1059 1060
1060 tmp = (__le32 *) buf; 1061 tmp = (__le32 *) buf;
1061 MsgType = le32_to_cpup(tmp++); 1062 MsgType = le32_to_cpup(tmp++);
1062 MsgLength = le32_to_cpup(tmp++); 1063 MsgLength = le32_to_cpup(tmp++);
1063 1064
1064 if (configNr >= RNDIS_MAX_CONFIGS) 1065 if (configNr >= RNDIS_MAX_CONFIGS)
1065 return -ENOTSUPP; 1066 return -ENOTSUPP;
1066 params = &rndis_per_dev_params [configNr]; 1067 params = &rndis_per_dev_params [configNr];
1067 1068
1068 /* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for 1069 /* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for
1069 * rx/tx statistics and link status, in addition to KEEPALIVE traffic 1070 * rx/tx statistics and link status, in addition to KEEPALIVE traffic
1070 * and normal HC level polling to see if there's any IN traffic. 1071 * and normal HC level polling to see if there's any IN traffic.
@@ -1073,12 +1074,12 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
1073 /* For USB: responses may take up to 10 seconds */ 1074 /* For USB: responses may take up to 10 seconds */
1074 switch (MsgType) { 1075 switch (MsgType) {
1075 case REMOTE_NDIS_INITIALIZE_MSG: 1076 case REMOTE_NDIS_INITIALIZE_MSG:
1076 DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", 1077 DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
1077 __FUNCTION__ ); 1078 __FUNCTION__ );
1078 params->state = RNDIS_INITIALIZED; 1079 params->state = RNDIS_INITIALIZED;
1079 return rndis_init_response (configNr, 1080 return rndis_init_response (configNr,
1080 (rndis_init_msg_type *) buf); 1081 (rndis_init_msg_type *) buf);
1081 1082
1082 case REMOTE_NDIS_HALT_MSG: 1083 case REMOTE_NDIS_HALT_MSG:
1083 DEBUG("%s: REMOTE_NDIS_HALT_MSG\n", 1084 DEBUG("%s: REMOTE_NDIS_HALT_MSG\n",
1084 __FUNCTION__ ); 1085 __FUNCTION__ );
@@ -1088,37 +1089,37 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
1088 netif_stop_queue (params->dev); 1089 netif_stop_queue (params->dev);
1089 } 1090 }
1090 return 0; 1091 return 0;
1091 1092
1092 case REMOTE_NDIS_QUERY_MSG: 1093 case REMOTE_NDIS_QUERY_MSG:
1093 return rndis_query_response (configNr, 1094 return rndis_query_response (configNr,
1094 (rndis_query_msg_type *) buf); 1095 (rndis_query_msg_type *) buf);
1095 1096
1096 case REMOTE_NDIS_SET_MSG: 1097 case REMOTE_NDIS_SET_MSG:
1097 return rndis_set_response (configNr, 1098 return rndis_set_response (configNr,
1098 (rndis_set_msg_type *) buf); 1099 (rndis_set_msg_type *) buf);
1099 1100
1100 case REMOTE_NDIS_RESET_MSG: 1101 case REMOTE_NDIS_RESET_MSG:
1101 DEBUG("%s: REMOTE_NDIS_RESET_MSG\n", 1102 DEBUG("%s: REMOTE_NDIS_RESET_MSG\n",
1102 __FUNCTION__ ); 1103 __FUNCTION__ );
1103 return rndis_reset_response (configNr, 1104 return rndis_reset_response (configNr,
1104 (rndis_reset_msg_type *) buf); 1105 (rndis_reset_msg_type *) buf);
1105 1106
1106 case REMOTE_NDIS_KEEPALIVE_MSG: 1107 case REMOTE_NDIS_KEEPALIVE_MSG:
1107 /* For USB: host does this every 5 seconds */ 1108 /* For USB: host does this every 5 seconds */
1108 if (rndis_debug > 1) 1109 if (rndis_debug > 1)
1109 DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", 1110 DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
1110 __FUNCTION__ ); 1111 __FUNCTION__ );
1111 return rndis_keepalive_response (configNr, 1112 return rndis_keepalive_response (configNr,
1112 (rndis_keepalive_msg_type *) 1113 (rndis_keepalive_msg_type *)
1113 buf); 1114 buf);
1114 1115
1115 default: 1116 default:
1116 /* At least Windows XP emits some undefined RNDIS messages. 1117 /* At least Windows XP emits some undefined RNDIS messages.
1117 * In one case those messages seemed to relate to the host 1118 * In one case those messages seemed to relate to the host
1118 * suspending itself. 1119 * suspending itself.
1119 */ 1120 */
1120 printk (KERN_WARNING 1121 printk (KERN_WARNING
1121 "%s: unknown RNDIS message 0x%08X len %d\n", 1122 "%s: unknown RNDIS message 0x%08X len %d\n",
1122 __FUNCTION__ , MsgType, MsgLength); 1123 __FUNCTION__ , MsgType, MsgLength);
1123 { 1124 {
1124 unsigned i; 1125 unsigned i;
@@ -1142,14 +1143,14 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
1142 } 1143 }
1143 break; 1144 break;
1144 } 1145 }
1145 1146
1146 return -ENOTSUPP; 1147 return -ENOTSUPP;
1147} 1148}
1148 1149
1149int rndis_register (int (* rndis_control_ack) (struct net_device *)) 1150int rndis_register (int (* rndis_control_ack) (struct net_device *))
1150{ 1151{
1151 u8 i; 1152 u8 i;
1152 1153
1153 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { 1154 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
1154 if (!rndis_per_dev_params [i].used) { 1155 if (!rndis_per_dev_params [i].used) {
1155 rndis_per_dev_params [i].used = 1; 1156 rndis_per_dev_params [i].used = 1;
@@ -1159,32 +1160,32 @@ int rndis_register (int (* rndis_control_ack) (struct net_device *))
1159 } 1160 }
1160 } 1161 }
1161 DEBUG("failed\n"); 1162 DEBUG("failed\n");
1162 1163
1163 return -1; 1164 return -1;
1164} 1165}
1165 1166
1166void rndis_deregister (int configNr) 1167void rndis_deregister (int configNr)
1167{ 1168{
1168 DEBUG("%s: \n", __FUNCTION__ ); 1169 DEBUG("%s: \n", __FUNCTION__ );
1169 1170
1170 if (configNr >= RNDIS_MAX_CONFIGS) return; 1171 if (configNr >= RNDIS_MAX_CONFIGS) return;
1171 rndis_per_dev_params [configNr].used = 0; 1172 rndis_per_dev_params [configNr].used = 0;
1172 1173
1173 return; 1174 return;
1174} 1175}
1175 1176
1176int rndis_set_param_dev (u8 configNr, struct net_device *dev, 1177int rndis_set_param_dev (u8 configNr, struct net_device *dev,
1177 struct net_device_stats *stats, 1178 struct net_device_stats *stats,
1178 u16 *cdc_filter) 1179 u16 *cdc_filter)
1179{ 1180{
1180 DEBUG("%s:\n", __FUNCTION__ ); 1181 DEBUG("%s:\n", __FUNCTION__ );
1181 if (!dev || !stats) return -1; 1182 if (!dev || !stats) return -1;
1182 if (configNr >= RNDIS_MAX_CONFIGS) return -1; 1183 if (configNr >= RNDIS_MAX_CONFIGS) return -1;
1183 1184
1184 rndis_per_dev_params [configNr].dev = dev; 1185 rndis_per_dev_params [configNr].dev = dev;
1185 rndis_per_dev_params [configNr].stats = stats; 1186 rndis_per_dev_params [configNr].stats = stats;
1186 rndis_per_dev_params [configNr].filter = cdc_filter; 1187 rndis_per_dev_params [configNr].filter = cdc_filter;
1187 1188
1188 return 0; 1189 return 0;
1189} 1190}
1190 1191
@@ -1193,10 +1194,10 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
1193 DEBUG("%s:\n", __FUNCTION__ ); 1194 DEBUG("%s:\n", __FUNCTION__ );
1194 if (!vendorDescr) return -1; 1195 if (!vendorDescr) return -1;
1195 if (configNr >= RNDIS_MAX_CONFIGS) return -1; 1196 if (configNr >= RNDIS_MAX_CONFIGS) return -1;
1196 1197
1197 rndis_per_dev_params [configNr].vendorID = vendorID; 1198 rndis_per_dev_params [configNr].vendorID = vendorID;
1198 rndis_per_dev_params [configNr].vendorDescr = vendorDescr; 1199 rndis_per_dev_params [configNr].vendorDescr = vendorDescr;
1199 1200
1200 return 0; 1201 return 0;
1201} 1202}
1202 1203
@@ -1204,10 +1205,10 @@ int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
1204{ 1205{
1205 DEBUG("%s: %u %u\n", __FUNCTION__, medium, speed); 1206 DEBUG("%s: %u %u\n", __FUNCTION__, medium, speed);
1206 if (configNr >= RNDIS_MAX_CONFIGS) return -1; 1207 if (configNr >= RNDIS_MAX_CONFIGS) return -1;
1207 1208
1208 rndis_per_dev_params [configNr].medium = medium; 1209 rndis_per_dev_params [configNr].medium = medium;
1209 rndis_per_dev_params [configNr].speed = speed; 1210 rndis_per_dev_params [configNr].speed = speed;
1210 1211
1211 return 0; 1212 return 0;
1212} 1213}
1213 1214
@@ -1229,9 +1230,9 @@ void rndis_free_response (int configNr, u8 *buf)
1229{ 1230{
1230 rndis_resp_t *r; 1231 rndis_resp_t *r;
1231 struct list_head *act, *tmp; 1232 struct list_head *act, *tmp;
1232 1233
1233 list_for_each_safe (act, tmp, 1234 list_for_each_safe (act, tmp,
1234 &(rndis_per_dev_params [configNr].resp_queue)) 1235 &(rndis_per_dev_params [configNr].resp_queue))
1235 { 1236 {
1236 r = list_entry (act, rndis_resp_t, list); 1237 r = list_entry (act, rndis_resp_t, list);
1237 if (r && r->buf == buf) { 1238 if (r && r->buf == buf) {
@@ -1244,12 +1245,12 @@ void rndis_free_response (int configNr, u8 *buf)
1244u8 *rndis_get_next_response (int configNr, u32 *length) 1245u8 *rndis_get_next_response (int configNr, u32 *length)
1245{ 1246{
1246 rndis_resp_t *r; 1247 rndis_resp_t *r;
1247 struct list_head *act, *tmp; 1248 struct list_head *act, *tmp;
1248 1249
1249 if (!length) return NULL; 1250 if (!length) return NULL;
1250 1251
1251 list_for_each_safe (act, tmp, 1252 list_for_each_safe (act, tmp,
1252 &(rndis_per_dev_params [configNr].resp_queue)) 1253 &(rndis_per_dev_params [configNr].resp_queue))
1253 { 1254 {
1254 r = list_entry (act, rndis_resp_t, list); 1255 r = list_entry (act, rndis_resp_t, list);
1255 if (!r->send) { 1256 if (!r->send) {
@@ -1258,24 +1259,24 @@ u8 *rndis_get_next_response (int configNr, u32 *length)
1258 return r->buf; 1259 return r->buf;
1259 } 1260 }
1260 } 1261 }
1261 1262
1262 return NULL; 1263 return NULL;
1263} 1264}
1264 1265
1265static rndis_resp_t *rndis_add_response (int configNr, u32 length) 1266static rndis_resp_t *rndis_add_response (int configNr, u32 length)
1266{ 1267{
1267 rndis_resp_t *r; 1268 rndis_resp_t *r;
1268 1269
1269 /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */ 1270 /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */
1270 r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC); 1271 r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC);
1271 if (!r) return NULL; 1272 if (!r) return NULL;
1272 1273
1273 r->buf = (u8 *) (r + 1); 1274 r->buf = (u8 *) (r + 1);
1274 r->length = length; 1275 r->length = length;
1275 r->send = 0; 1276 r->send = 0;
1276 1277
1277 list_add_tail (&r->list, 1278 list_add_tail (&r->list,
1278 &(rndis_per_dev_params [configNr].resp_queue)); 1279 &(rndis_per_dev_params [configNr].resp_queue));
1279 return r; 1280 return r;
1280} 1281}
1281 1282
@@ -1301,14 +1302,14 @@ int rndis_rm_hdr(struct sk_buff *skb)
1301 1302
1302#ifdef CONFIG_USB_GADGET_DEBUG_FILES 1303#ifdef CONFIG_USB_GADGET_DEBUG_FILES
1303 1304
1304static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof, 1305static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof,
1305 void *data) 1306 void *data)
1306{ 1307{
1307 char *out = page; 1308 char *out = page;
1308 int len; 1309 int len;
1309 rndis_params *param = (rndis_params *) data; 1310 rndis_params *param = (rndis_params *) data;
1310 1311
1311 out += snprintf (out, count, 1312 out += snprintf (out, count,
1312 "Config Nr. %d\n" 1313 "Config Nr. %d\n"
1313 "used : %s\n" 1314 "used : %s\n"
1314 "state : %s\n" 1315 "state : %s\n"
@@ -1316,8 +1317,8 @@ static int rndis_proc_read (char *page, char **start, off_t off, int count, int
1316 "speed : %d\n" 1317 "speed : %d\n"
1317 "cable : %s\n" 1318 "cable : %s\n"
1318 "vendor ID : 0x%08X\n" 1319 "vendor ID : 0x%08X\n"
1319 "vendor : %s\n", 1320 "vendor : %s\n",
1320 param->confignr, (param->used) ? "y" : "n", 1321 param->confignr, (param->used) ? "y" : "n",
1321 ({ char *s = "?"; 1322 ({ char *s = "?";
1322 switch (param->state) { 1323 switch (param->state) {
1323 case RNDIS_UNINITIALIZED: 1324 case RNDIS_UNINITIALIZED:
@@ -1327,32 +1328,32 @@ static int rndis_proc_read (char *page, char **start, off_t off, int count, int
1327 case RNDIS_DATA_INITIALIZED: 1328 case RNDIS_DATA_INITIALIZED:
1328 s = "RNDIS_DATA_INITIALIZED"; break; 1329 s = "RNDIS_DATA_INITIALIZED"; break;
1329 }; s; }), 1330 }; s; }),
1330 param->medium, 1331 param->medium,
1331 (param->media_state) ? 0 : param->speed*100, 1332 (param->media_state) ? 0 : param->speed*100,
1332 (param->media_state) ? "disconnected" : "connected", 1333 (param->media_state) ? "disconnected" : "connected",
1333 param->vendorID, param->vendorDescr); 1334 param->vendorID, param->vendorDescr);
1334 1335
1335 len = out - page; 1336 len = out - page;
1336 len -= off; 1337 len -= off;
1337 1338
1338 if (len < count) { 1339 if (len < count) {
1339 *eof = 1; 1340 *eof = 1;
1340 if (len <= 0) 1341 if (len <= 0)
1341 return 0; 1342 return 0;
1342 } else 1343 } else
1343 len = count; 1344 len = count;
1344 1345
1345 *start = page + off; 1346 *start = page + off;
1346 return len; 1347 return len;
1347} 1348}
1348 1349
1349static int rndis_proc_write (struct file *file, const char __user *buffer, 1350static int rndis_proc_write (struct file *file, const char __user *buffer,
1350 unsigned long count, void *data) 1351 unsigned long count, void *data)
1351{ 1352{
1352 rndis_params *p = data; 1353 rndis_params *p = data;
1353 u32 speed = 0; 1354 u32 speed = 0;
1354 int i, fl_speed = 0; 1355 int i, fl_speed = 0;
1355 1356
1356 for (i = 0; i < count; i++) { 1357 for (i = 0; i < count; i++) {
1357 char c; 1358 char c;
1358 if (get_user(c, buffer)) 1359 if (get_user(c, buffer))
@@ -1379,15 +1380,15 @@ static int rndis_proc_write (struct file *file, const char __user *buffer,
1379 case 'd': 1380 case 'd':
1380 rndis_signal_disconnect(p->confignr); 1381 rndis_signal_disconnect(p->confignr);
1381 break; 1382 break;
1382 default: 1383 default:
1383 if (fl_speed) p->speed = speed; 1384 if (fl_speed) p->speed = speed;
1384 else DEBUG ("%c is not valid\n", c); 1385 else DEBUG ("%c is not valid\n", c);
1385 break; 1386 break;
1386 } 1387 }
1387 1388
1388 buffer++; 1389 buffer++;
1389 } 1390 }
1390 1391
1391 return count; 1392 return count;
1392} 1393}
1393 1394
@@ -1408,7 +1409,7 @@ int __init rndis_init (void)
1408 1409
1409 sprintf (name, NAME_TEMPLATE, i); 1410 sprintf (name, NAME_TEMPLATE, i);
1410 if (!(rndis_connect_state [i] 1411 if (!(rndis_connect_state [i]
1411 = create_proc_entry (name, 0660, NULL))) 1412 = create_proc_entry (name, 0660, NULL)))
1412 { 1413 {
1413 DEBUG ("%s :remove entries", __FUNCTION__); 1414 DEBUG ("%s :remove entries", __FUNCTION__);
1414 while (i) { 1415 while (i) {
@@ -1432,7 +1433,7 @@ int __init rndis_init (void)
1432 = NDIS_MEDIA_STATE_DISCONNECTED; 1433 = NDIS_MEDIA_STATE_DISCONNECTED;
1433 INIT_LIST_HEAD (&(rndis_per_dev_params [i].resp_queue)); 1434 INIT_LIST_HEAD (&(rndis_per_dev_params [i].resp_queue));
1434 } 1435 }
1435 1436
1436 return 0; 1437 return 0;
1437} 1438}
1438 1439
@@ -1441,7 +1442,7 @@ void rndis_exit (void)
1441#ifdef CONFIG_USB_GADGET_DEBUG_FILES 1442#ifdef CONFIG_USB_GADGET_DEBUG_FILES
1442 u8 i; 1443 u8 i;
1443 char name [20]; 1444 char name [20];
1444 1445
1445 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { 1446 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
1446 sprintf (name, NAME_TEMPLATE, i); 1447 sprintf (name, NAME_TEMPLATE, i);
1447 remove_proc_entry (name, NULL); 1448 remove_proc_entry (name, NULL);
diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h
index 95b4c6326100..2956608be751 100644
--- a/drivers/usb/gadget/rndis.h
+++ b/drivers/usb/gadget/rndis.h
@@ -1,15 +1,15 @@
1/* 1/*
2 * RNDIS Definitions for Remote NDIS 2 * RNDIS Definitions for Remote NDIS
3 * 3 *
4 * Version: $Id: rndis.h,v 1.15 2004/03/25 21:33:46 robert Exp $ 4 * Version: $Id: rndis.h,v 1.15 2004/03/25 21:33:46 robert Exp $
5 * 5 *
6 * Authors: Benedikt Spranger, Pengutronix 6 * Authors: Benedikt Spranger, Pengutronix
7 * Robert Schwebel, Pengutronix 7 * Robert Schwebel, Pengutronix
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
11 * version 2, as published by the Free Software Foundation. 11 * version 2, as published by the Free Software Foundation.
12 * 12 *
13 * This software was originally developed in conformance with 13 * This software was originally developed in conformance with
14 * Microsoft's Remote NDIS Specification License Agreement. 14 * Microsoft's Remote NDIS Specification License Agreement.
15 */ 15 */
@@ -34,7 +34,7 @@
34#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BU /* Device connected */ 34#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BU /* Device connected */
35#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CU /* Device disconnected */ 35#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CU /* Device disconnected */
36/* For all not specified status messages: 36/* For all not specified status messages:
37 * RNDIS_STATUS_Xxx -> NDIS_STATUS_Xxx 37 * RNDIS_STATUS_Xxx -> NDIS_STATUS_Xxx
38 */ 38 */
39 39
40/* Message Set for Connectionless (802.3) Devices */ 40/* Message Set for Connectionless (802.3) Devices */
@@ -69,7 +69,7 @@
69#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 69#define OID_PNP_ENABLE_WAKE_UP 0xFD010106
70 70
71 71
72typedef struct rndis_init_msg_type 72typedef struct rndis_init_msg_type
73{ 73{
74 __le32 MessageType; 74 __le32 MessageType;
75 __le32 MessageLength; 75 __le32 MessageLength;
@@ -234,12 +234,12 @@ typedef struct rndis_params
234 234
235 const u8 *host_mac; 235 const u8 *host_mac;
236 u16 *filter; 236 u16 *filter;
237 struct net_device *dev; 237 struct net_device *dev;
238 struct net_device_stats *stats; 238 struct net_device_stats *stats;
239 239
240 u32 vendorID; 240 u32 vendorID;
241 const char *vendorDescr; 241 const char *vendorDescr;
242 int (*ack) (struct net_device *); 242 int (*ack) (struct net_device *);
243 struct list_head resp_queue; 243 struct list_head resp_queue;
244} rndis_params; 244} rndis_params;
245 245
@@ -250,7 +250,7 @@ void rndis_deregister (int configNr);
250int rndis_set_param_dev (u8 configNr, struct net_device *dev, 250int rndis_set_param_dev (u8 configNr, struct net_device *dev,
251 struct net_device_stats *stats, 251 struct net_device_stats *stats,
252 u16 *cdc_filter); 252 u16 *cdc_filter);
253int rndis_set_param_vendor (u8 configNr, u32 vendorID, 253int rndis_set_param_vendor (u8 configNr, u32 vendorID,
254 const char *vendorDescr); 254 const char *vendorDescr);
255int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed); 255int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed);
256void rndis_add_hdr (struct sk_buff *skb); 256void rndis_add_hdr (struct sk_buff *skb);
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index b992546c394d..9d6e1d295528 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -45,88 +45,16 @@
45#include <asm/uaccess.h> 45#include <asm/uaccess.h>
46 46
47#include <linux/usb_ch9.h> 47#include <linux/usb_ch9.h>
48#include <linux/usb_cdc.h> 48#include <linux/usb/cdc.h>
49#include <linux/usb_gadget.h> 49#include <linux/usb_gadget.h>
50 50
51#include "gadget_chips.h" 51#include "gadget_chips.h"
52 52
53 53
54/* Wait Cond */
55
56#define __wait_cond_interruptible(wq, condition, lock, flags, ret) \
57do { \
58 wait_queue_t __wait; \
59 init_waitqueue_entry(&__wait, current); \
60 \
61 add_wait_queue(&wq, &__wait); \
62 for (;;) { \
63 set_current_state(TASK_INTERRUPTIBLE); \
64 if (condition) \
65 break; \
66 if (!signal_pending(current)) { \
67 spin_unlock_irqrestore(lock, flags); \
68 schedule(); \
69 spin_lock_irqsave(lock, flags); \
70 continue; \
71 } \
72 ret = -ERESTARTSYS; \
73 break; \
74 } \
75 current->state = TASK_RUNNING; \
76 remove_wait_queue(&wq, &__wait); \
77} while (0)
78
79#define wait_cond_interruptible(wq, condition, lock, flags) \
80({ \
81 int __ret = 0; \
82 if (!(condition)) \
83 __wait_cond_interruptible(wq, condition, lock, flags, \
84 __ret); \
85 __ret; \
86})
87
88#define __wait_cond_interruptible_timeout(wq, condition, lock, flags, \
89 timeout, ret) \
90do { \
91 signed long __timeout = timeout; \
92 wait_queue_t __wait; \
93 init_waitqueue_entry(&__wait, current); \
94 \
95 add_wait_queue(&wq, &__wait); \
96 for (;;) { \
97 set_current_state(TASK_INTERRUPTIBLE); \
98 if (__timeout == 0) \
99 break; \
100 if (condition) \
101 break; \
102 if (!signal_pending(current)) { \
103 spin_unlock_irqrestore(lock, flags); \
104 __timeout = schedule_timeout(__timeout); \
105 spin_lock_irqsave(lock, flags); \
106 continue; \
107 } \
108 ret = -ERESTARTSYS; \
109 break; \
110 } \
111 current->state = TASK_RUNNING; \
112 remove_wait_queue(&wq, &__wait); \
113} while (0)
114
115#define wait_cond_interruptible_timeout(wq, condition, lock, flags, \
116 timeout) \
117({ \
118 int __ret = 0; \
119 if (!(condition)) \
120 __wait_cond_interruptible_timeout(wq, condition, lock, \
121 flags, timeout, __ret); \
122 __ret; \
123})
124
125
126/* Defines */ 54/* Defines */
127 55
128#define GS_VERSION_STR "v2.0" 56#define GS_VERSION_STR "v2.2"
129#define GS_VERSION_NUM 0x0200 57#define GS_VERSION_NUM 0x0202
130 58
131#define GS_LONG_NAME "Gadget Serial" 59#define GS_LONG_NAME "Gadget Serial"
132#define GS_SHORT_NAME "g_serial" 60#define GS_SHORT_NAME "g_serial"
@@ -843,9 +771,19 @@ exit_unlock_dev:
843/* 771/*
844 * gs_close 772 * gs_close
845 */ 773 */
774
775#define GS_WRITE_FINISHED_EVENT_SAFELY(p) \
776({ \
777 int cond; \
778 \
779 spin_lock_irq(&(p)->port_lock); \
780 cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf); \
781 spin_unlock_irq(&(p)->port_lock); \
782 cond; \
783})
784
846static void gs_close(struct tty_struct *tty, struct file *file) 785static void gs_close(struct tty_struct *tty, struct file *file)
847{ 786{
848 unsigned long flags;
849 struct gs_port *port = tty->driver_data; 787 struct gs_port *port = tty->driver_data;
850 struct semaphore *sem; 788 struct semaphore *sem;
851 789
@@ -859,7 +797,7 @@ static void gs_close(struct tty_struct *tty, struct file *file)
859 sem = &gs_open_close_sem[port->port_num]; 797 sem = &gs_open_close_sem[port->port_num];
860 down(sem); 798 down(sem);
861 799
862 spin_lock_irqsave(&port->port_lock, flags); 800 spin_lock_irq(&port->port_lock);
863 801
864 if (port->port_open_count == 0) { 802 if (port->port_open_count == 0) {
865 printk(KERN_ERR 803 printk(KERN_ERR
@@ -887,12 +825,11 @@ static void gs_close(struct tty_struct *tty, struct file *file)
887 /* wait for write buffer to drain, or */ 825 /* wait for write buffer to drain, or */
888 /* at most GS_CLOSE_TIMEOUT seconds */ 826 /* at most GS_CLOSE_TIMEOUT seconds */
889 if (gs_buf_data_avail(port->port_write_buf) > 0) { 827 if (gs_buf_data_avail(port->port_write_buf) > 0) {
890 spin_unlock_irqrestore(&port->port_lock, flags); 828 spin_unlock_irq(&port->port_lock);
891 wait_cond_interruptible_timeout(port->port_write_wait, 829 wait_event_interruptible_timeout(port->port_write_wait,
892 port->port_dev == NULL 830 GS_WRITE_FINISHED_EVENT_SAFELY(port),
893 || gs_buf_data_avail(port->port_write_buf) == 0, 831 GS_CLOSE_TIMEOUT * HZ);
894 &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ); 832 spin_lock_irq(&port->port_lock);
895 spin_lock_irqsave(&port->port_lock, flags);
896 } 833 }
897 834
898 /* free disconnected port on final close */ 835 /* free disconnected port on final close */
@@ -912,7 +849,7 @@ static void gs_close(struct tty_struct *tty, struct file *file)
912 port->port_num, tty, file); 849 port->port_num, tty, file);
913 850
914exit: 851exit:
915 spin_unlock_irqrestore(&port->port_lock, flags); 852 spin_unlock_irq(&port->port_lock);
916 up(sem); 853 up(sem);
917} 854}
918 855
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index e27b79a3c05f..c060eb9b3b19 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -47,7 +47,25 @@ config USB_EHCI_ROOT_HUB_TT
47 controller is needed. It's safe to say "y" even if your 47 controller is needed. It's safe to say "y" even if your
48 controller doesn't support this feature. 48 controller doesn't support this feature.
49 49
50 This supports the EHCI implementation from TransDimension Inc. 50 This supports the EHCI implementation that's originally
51 from ARC, and has since changed hands a few times.
52
53config USB_EHCI_TT_NEWSCHED
54 bool "Improved Transaction Translator scheduling (EXPERIMENTAL)"
55 depends on USB_EHCI_HCD && EXPERIMENTAL
56 ---help---
57 This changes the periodic scheduling code to fill more of the low
58 and full speed bandwidth available from the Transaction Translator
59 (TT) in USB 2.0 hubs. Without this, only one transfer will be
60 issued in each microframe, significantly reducing the number of
61 periodic low/fullspeed transfers possible.
62
63 If you have multiple periodic low/fullspeed devices connected to a
64 highspeed USB hub which is connected to a highspeed USB Host
65 Controller, and some of those devices will not work correctly
66 (possibly due to "ENOSPC" or "-28" errors), say Y.
67
68 If unsure, say N.
51 69
52config USB_ISP116X_HCD 70config USB_ISP116X_HCD
53 tristate "ISP116X HCD support" 71 tristate "ISP116X HCD support"
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c
index 63eadeec1324..9b4697add313 100644
--- a/drivers/usb/host/ehci-au1xxx.c
+++ b/drivers/usb/host/ehci-au1xxx.c
@@ -16,10 +16,6 @@
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <asm/mach-au1x00/au1000.h> 17#include <asm/mach-au1x00/au1000.h>
18 18
19#ifndef CONFIG_SOC_AU1200
20#error "this Alchemy chip doesn't have EHCI"
21#else /* Au1200 */
22
23#define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG) 19#define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG)
24#define USB_MCFG_PFEN (1<<31) 20#define USB_MCFG_PFEN (1<<31)
25#define USB_MCFG_RDCOMB (1<<30) 21#define USB_MCFG_RDCOMB (1<<30)
@@ -272,6 +268,8 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
272 return 0; 268 return 0;
273} 269}
274*/ 270*/
271MODULE_ALIAS("au1xxx-ehci");
272/* FIXME use "struct platform_driver" */
275static struct device_driver ehci_hcd_au1xxx_driver = { 273static struct device_driver ehci_hcd_au1xxx_driver = {
276 .name = "au1xxx-ehci", 274 .name = "au1xxx-ehci",
277 .bus = &platform_bus_type, 275 .bus = &platform_bus_type,
@@ -280,18 +278,3 @@ static struct device_driver ehci_hcd_au1xxx_driver = {
280 /*.suspend = ehci_hcd_au1xxx_drv_suspend, */ 278 /*.suspend = ehci_hcd_au1xxx_drv_suspend, */
281 /*.resume = ehci_hcd_au1xxx_drv_resume, */ 279 /*.resume = ehci_hcd_au1xxx_drv_resume, */
282}; 280};
283
284static int __init ehci_hcd_au1xxx_init(void)
285{
286 pr_debug(DRIVER_INFO " (Au1xxx)\n");
287
288 return driver_register(&ehci_hcd_au1xxx_driver);
289}
290
291static void __exit ehci_hcd_au1xxx_cleanup(void)
292{
293 driver_unregister(&ehci_hcd_au1xxx_driver);
294}
295
296module_init(ehci_hcd_au1xxx_init);
297module_exit(ehci_hcd_au1xxx_cleanup);
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index f985f121a245..a49a689bf423 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -324,43 +324,12 @@ static int ehci_fsl_drv_remove(struct platform_device *pdev)
324 return 0; 324 return 0;
325} 325}
326 326
327static struct platform_driver ehci_fsl_dr_driver = { 327MODULE_ALIAS("fsl-ehci");
328 .probe = ehci_fsl_drv_probe,
329 .remove = ehci_fsl_drv_remove,
330 .driver = {
331 .name = "fsl-usb2-dr",
332 },
333};
334 328
335static struct platform_driver ehci_fsl_mph_driver = { 329static struct platform_driver ehci_fsl_driver = {
336 .probe = ehci_fsl_drv_probe, 330 .probe = ehci_fsl_drv_probe,
337 .remove = ehci_fsl_drv_remove, 331 .remove = ehci_fsl_drv_remove,
338 .driver = { 332 .driver = {
339 .name = "fsl-usb2-mph", 333 .name = "fsl-ehci",
340 }, 334 },
341}; 335};
342
343static int __init ehci_fsl_init(void)
344{
345 int retval;
346
347 pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
348 hcd_name,
349 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
350 sizeof(struct ehci_itd), sizeof(struct ehci_sitd));
351
352 retval = platform_driver_register(&ehci_fsl_dr_driver);
353 if (retval)
354 return retval;
355
356 return platform_driver_register(&ehci_fsl_mph_driver);
357}
358
359static void __exit ehci_fsl_cleanup(void)
360{
361 platform_driver_unregister(&ehci_fsl_mph_driver);
362 platform_driver_unregister(&ehci_fsl_dr_driver);
363}
364
365module_init(ehci_fsl_init);
366module_exit(ehci_fsl_cleanup);
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 79f2d8b9bfb6..9b37e508ada3 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -889,19 +889,59 @@ MODULE_LICENSE ("GPL");
889 889
890#ifdef CONFIG_PCI 890#ifdef CONFIG_PCI
891#include "ehci-pci.c" 891#include "ehci-pci.c"
892#define EHCI_BUS_GLUED 892#define PCI_DRIVER ehci_pci_driver
893#endif 893#endif
894 894
895#ifdef CONFIG_PPC_83xx 895#ifdef CONFIG_PPC_83xx
896#include "ehci-fsl.c" 896#include "ehci-fsl.c"
897#define EHCI_BUS_GLUED 897#define PLATFORM_DRIVER ehci_fsl_driver
898#endif 898#endif
899 899
900#ifdef CONFIG_SOC_AU1X00 900#ifdef CONFIG_SOC_AU1200
901#include "ehci-au1xxx.c" 901#include "ehci-au1xxx.c"
902#define EHCI_BUS_GLUED 902#define PLATFORM_DRIVER ehci_hcd_au1xxx_driver
903#endif 903#endif
904 904
905#ifndef EHCI_BUS_GLUED 905#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER)
906#error "missing bus glue for ehci-hcd" 906#error "missing bus glue for ehci-hcd"
907#endif 907#endif
908
909static int __init ehci_hcd_init(void)
910{
911 int retval = 0;
912
913 pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
914 hcd_name,
915 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
916 sizeof(struct ehci_itd), sizeof(struct ehci_sitd));
917
918#ifdef PLATFORM_DRIVER
919 retval = platform_driver_register(&PLATFORM_DRIVER);
920 if (retval < 0)
921 return retval;
922#endif
923
924#ifdef PCI_DRIVER
925 retval = pci_register_driver(&PCI_DRIVER);
926 if (retval < 0) {
927#ifdef PLATFORM_DRIVER
928 platform_driver_unregister(&PLATFORM_DRIVER);
929#endif
930 }
931#endif
932
933 return retval;
934}
935module_init(ehci_hcd_init);
936
937static void __exit ehci_hcd_cleanup(void)
938{
939#ifdef PLATFORM_DRIVER
940 platform_driver_unregister(&PLATFORM_DRIVER);
941#endif
942#ifdef PCI_DRIVER
943 pci_unregister_driver(&PCI_DRIVER);
944#endif
945}
946module_exit(ehci_hcd_cleanup);
947
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index a1bd2bea6deb..cadffacd945b 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -76,6 +76,30 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
76 dbg_hcs_params(ehci, "reset"); 76 dbg_hcs_params(ehci, "reset");
77 dbg_hcc_params(ehci, "reset"); 77 dbg_hcc_params(ehci, "reset");
78 78
79 /* ehci_init() causes memory for DMA transfers to be
80 * allocated. Thus, any vendor-specific workarounds based on
81 * limiting the type of memory used for DMA transfers must
82 * happen before ehci_init() is called. */
83 switch (pdev->vendor) {
84 case PCI_VENDOR_ID_NVIDIA:
85 /* NVidia reports that certain chips don't handle
86 * QH, ITD, or SITD addresses above 2GB. (But TD,
87 * data buffer, and periodic schedule are normal.)
88 */
89 switch (pdev->device) {
90 case 0x003c: /* MCP04 */
91 case 0x005b: /* CK804 */
92 case 0x00d8: /* CK8 */
93 case 0x00e8: /* CK8S */
94 if (pci_set_consistent_dma_mask(pdev,
95 DMA_31BIT_MASK) < 0)
96 ehci_warn(ehci, "can't enable NVidia "
97 "workaround for >2GB RAM\n");
98 break;
99 }
100 break;
101 }
102
79 /* cache this readonly data; minimize chip reads */ 103 /* cache this readonly data; minimize chip reads */
80 ehci->hcs_params = readl(&ehci->caps->hcs_params); 104 ehci->hcs_params = readl(&ehci->caps->hcs_params);
81 105
@@ -88,8 +112,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
88 if (retval) 112 if (retval)
89 return retval; 113 return retval;
90 114
91 /* NOTE: only the parts below this line are PCI-specific */
92
93 switch (pdev->vendor) { 115 switch (pdev->vendor) {
94 case PCI_VENDOR_ID_TDI: 116 case PCI_VENDOR_ID_TDI:
95 if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { 117 if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
@@ -107,19 +129,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
107 break; 129 break;
108 case PCI_VENDOR_ID_NVIDIA: 130 case PCI_VENDOR_ID_NVIDIA:
109 switch (pdev->device) { 131 switch (pdev->device) {
110 /* NVidia reports that certain chips don't handle
111 * QH, ITD, or SITD addresses above 2GB. (But TD,
112 * data buffer, and periodic schedule are normal.)
113 */
114 case 0x003c: /* MCP04 */
115 case 0x005b: /* CK804 */
116 case 0x00d8: /* CK8 */
117 case 0x00e8: /* CK8S */
118 if (pci_set_consistent_dma_mask(pdev,
119 DMA_31BIT_MASK) < 0)
120 ehci_warn(ehci, "can't enable NVidia "
121 "workaround for >2GB RAM\n");
122 break;
123 /* Some NForce2 chips have problems with selective suspend; 132 /* Some NForce2 chips have problems with selective suspend;
124 * fixed in newer silicon. 133 * fixed in newer silicon.
125 */ 134 */
@@ -370,23 +379,3 @@ static struct pci_driver ehci_pci_driver = {
370 .resume = usb_hcd_pci_resume, 379 .resume = usb_hcd_pci_resume,
371#endif 380#endif
372}; 381};
373
374static int __init ehci_hcd_pci_init(void)
375{
376 if (usb_disabled())
377 return -ENODEV;
378
379 pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
380 hcd_name,
381 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
382 sizeof(struct ehci_itd), sizeof(struct ehci_sitd));
383
384 return pci_register_driver(&ehci_pci_driver);
385}
386module_init(ehci_hcd_pci_init);
387
388static void __exit ehci_hcd_pci_cleanup(void)
389{
390 pci_unregister_driver(&ehci_pci_driver);
391}
392module_exit(ehci_hcd_pci_cleanup);
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 5871944e6145..4859900bd135 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -163,6 +163,190 @@ static int same_tt (struct usb_device *dev1, struct usb_device *dev2)
163 return 1; 163 return 1;
164} 164}
165 165
166#ifdef CONFIG_USB_EHCI_TT_NEWSCHED
167
168/* Which uframe does the low/fullspeed transfer start in?
169 *
170 * The parameter is the mask of ssplits in "H-frame" terms
171 * and this returns the transfer start uframe in "B-frame" terms,
172 * which allows both to match, e.g. a ssplit in "H-frame" uframe 0
173 * will cause a transfer in "B-frame" uframe 0. "B-frames" lag
174 * "H-frames" by 1 uframe. See the EHCI spec sec 4.5 and figure 4.7.
175 */
176static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __le32 mask)
177{
178 unsigned char smask = QH_SMASK & le32_to_cpu(mask);
179 if (!smask) {
180 ehci_err(ehci, "invalid empty smask!\n");
181 /* uframe 7 can't have bw so this will indicate failure */
182 return 7;
183 }
184 return ffs(smask) - 1;
185}
186
187static const unsigned char
188max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };
189
190/* carryover low/fullspeed bandwidth that crosses uframe boundries */
191static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
192{
193 int i;
194 for (i=0; i<7; i++) {
195 if (max_tt_usecs[i] < tt_usecs[i]) {
196 tt_usecs[i+1] += tt_usecs[i] - max_tt_usecs[i];
197 tt_usecs[i] = max_tt_usecs[i];
198 }
199 }
200}
201
202/* How many of the tt's periodic downstream 1000 usecs are allocated?
203 *
204 * While this measures the bandwidth in terms of usecs/uframe,
205 * the low/fullspeed bus has no notion of uframes, so any particular
206 * low/fullspeed transfer can "carry over" from one uframe to the next,
207 * since the TT just performs downstream transfers in sequence.
208 *
209 * For example two seperate 100 usec transfers can start in the same uframe,
210 * and the second one would "carry over" 75 usecs into the next uframe.
211 */
212static void
213periodic_tt_usecs (
214 struct ehci_hcd *ehci,
215 struct usb_device *dev,
216 unsigned frame,
217 unsigned short tt_usecs[8]
218)
219{
220 __le32 *hw_p = &ehci->periodic [frame];
221 union ehci_shadow *q = &ehci->pshadow [frame];
222 unsigned char uf;
223
224 memset(tt_usecs, 0, 16);
225
226 while (q->ptr) {
227 switch (Q_NEXT_TYPE(*hw_p)) {
228 case Q_TYPE_ITD:
229 hw_p = &q->itd->hw_next;
230 q = &q->itd->itd_next;
231 continue;
232 case Q_TYPE_QH:
233 if (same_tt(dev, q->qh->dev)) {
234 uf = tt_start_uframe(ehci, q->qh->hw_info2);
235 tt_usecs[uf] += q->qh->tt_usecs;
236 }
237 hw_p = &q->qh->hw_next;
238 q = &q->qh->qh_next;
239 continue;
240 case Q_TYPE_SITD:
241 if (same_tt(dev, q->sitd->urb->dev)) {
242 uf = tt_start_uframe(ehci, q->sitd->hw_uframe);
243 tt_usecs[uf] += q->sitd->stream->tt_usecs;
244 }
245 hw_p = &q->sitd->hw_next;
246 q = &q->sitd->sitd_next;
247 continue;
248 // case Q_TYPE_FSTN:
249 default:
250 ehci_dbg(ehci,
251 "ignoring periodic frame %d FSTN\n", frame);
252 hw_p = &q->fstn->hw_next;
253 q = &q->fstn->fstn_next;
254 }
255 }
256
257 carryover_tt_bandwidth(tt_usecs);
258
259 if (max_tt_usecs[7] < tt_usecs[7])
260 ehci_err(ehci, "frame %d tt sched overrun: %d usecs\n",
261 frame, tt_usecs[7] - max_tt_usecs[7]);
262}
263
264/*
265 * Return true if the device's tt's downstream bus is available for a
266 * periodic transfer of the specified length (usecs), starting at the
267 * specified frame/uframe. Note that (as summarized in section 11.19
268 * of the usb 2.0 spec) TTs can buffer multiple transactions for each
269 * uframe.
270 *
271 * The uframe parameter is when the fullspeed/lowspeed transfer
272 * should be executed in "B-frame" terms, which is the same as the
273 * highspeed ssplit's uframe (which is in "H-frame" terms). For example
274 * a ssplit in "H-frame" 0 causes a transfer in "B-frame" 0.
275 * See the EHCI spec sec 4.5 and fig 4.7.
276 *
277 * This checks if the full/lowspeed bus, at the specified starting uframe,
278 * has the specified bandwidth available, according to rules listed
279 * in USB 2.0 spec section 11.18.1 fig 11-60.
280 *
281 * This does not check if the transfer would exceed the max ssplit
282 * limit of 16, specified in USB 2.0 spec section 11.18.4 requirement #4,
283 * since proper scheduling limits ssplits to less than 16 per uframe.
284 */
285static int tt_available (
286 struct ehci_hcd *ehci,
287 unsigned period,
288 struct usb_device *dev,
289 unsigned frame,
290 unsigned uframe,
291 u16 usecs
292)
293{
294 if ((period == 0) || (uframe >= 7)) /* error */
295 return 0;
296
297 for (; frame < ehci->periodic_size; frame += period) {
298 unsigned short tt_usecs[8];
299
300 periodic_tt_usecs (ehci, dev, frame, tt_usecs);
301
302 ehci_vdbg(ehci, "tt frame %d check %d usecs start uframe %d in"
303 " schedule %d/%d/%d/%d/%d/%d/%d/%d\n",
304 frame, usecs, uframe,
305 tt_usecs[0], tt_usecs[1], tt_usecs[2], tt_usecs[3],
306 tt_usecs[4], tt_usecs[5], tt_usecs[6], tt_usecs[7]);
307
308 if (max_tt_usecs[uframe] <= tt_usecs[uframe]) {
309 ehci_vdbg(ehci, "frame %d uframe %d fully scheduled\n",
310 frame, uframe);
311 return 0;
312 }
313
314 /* special case for isoc transfers larger than 125us:
315 * the first and each subsequent fully used uframe
316 * must be empty, so as to not illegally delay
317 * already scheduled transactions
318 */
319 if (125 < usecs) {
320 int ufs = (usecs / 125) - 1;
321 int i;
322 for (i = uframe; i < (uframe + ufs) && i < 8; i++)
323 if (0 < tt_usecs[i]) {
324 ehci_vdbg(ehci,
325 "multi-uframe xfer can't fit "
326 "in frame %d uframe %d\n",
327 frame, i);
328 return 0;
329 }
330 }
331
332 tt_usecs[uframe] += usecs;
333
334 carryover_tt_bandwidth(tt_usecs);
335
336 /* fail if the carryover pushed bw past the last uframe's limit */
337 if (max_tt_usecs[7] < tt_usecs[7]) {
338 ehci_vdbg(ehci,
339 "tt unavailable usecs %d frame %d uframe %d\n",
340 usecs, frame, uframe);
341 return 0;
342 }
343 }
344
345 return 1;
346}
347
348#else
349
166/* return true iff the device's transaction translator is available 350/* return true iff the device's transaction translator is available
167 * for a periodic transfer starting at the specified frame, using 351 * for a periodic transfer starting at the specified frame, using
168 * all the uframes in the mask. 352 * all the uframes in the mask.
@@ -237,6 +421,8 @@ static int tt_no_collision (
237 return 1; 421 return 1;
238} 422}
239 423
424#endif /* CONFIG_USB_EHCI_TT_NEWSCHED */
425
240/*-------------------------------------------------------------------------*/ 426/*-------------------------------------------------------------------------*/
241 427
242static int enable_periodic (struct ehci_hcd *ehci) 428static int enable_periodic (struct ehci_hcd *ehci)
@@ -481,7 +667,7 @@ static int check_intr_schedule (
481) 667)
482{ 668{
483 int retval = -ENOSPC; 669 int retval = -ENOSPC;
484 u8 mask; 670 u8 mask = 0;
485 671
486 if (qh->c_usecs && uframe >= 6) /* FSTN territory? */ 672 if (qh->c_usecs && uframe >= 6) /* FSTN territory? */
487 goto done; 673 goto done;
@@ -494,6 +680,24 @@ static int check_intr_schedule (
494 goto done; 680 goto done;
495 } 681 }
496 682
683#ifdef CONFIG_USB_EHCI_TT_NEWSCHED
684 if (tt_available (ehci, qh->period, qh->dev, frame, uframe,
685 qh->tt_usecs)) {
686 unsigned i;
687
688 /* TODO : this may need FSTN for SSPLIT in uframe 5. */
689 for (i=uframe+1; i<8 && i<uframe+4; i++)
690 if (!check_period (ehci, frame, i,
691 qh->period, qh->c_usecs))
692 goto done;
693 else
694 mask |= 1 << i;
695
696 retval = 0;
697
698 *c_maskp = cpu_to_le32 (mask << 8);
699 }
700#else
497 /* Make sure this tt's buffer is also available for CSPLITs. 701 /* Make sure this tt's buffer is also available for CSPLITs.
498 * We pessimize a bit; probably the typical full speed case 702 * We pessimize a bit; probably the typical full speed case
499 * doesn't need the second CSPLIT. 703 * doesn't need the second CSPLIT.
@@ -514,6 +718,7 @@ static int check_intr_schedule (
514 goto done; 718 goto done;
515 retval = 0; 719 retval = 0;
516 } 720 }
721#endif
517done: 722done:
518 return retval; 723 return retval;
519} 724}
@@ -1047,12 +1252,21 @@ sitd_slot_ok (
1047 frame = uframe >> 3; 1252 frame = uframe >> 3;
1048 uf = uframe & 7; 1253 uf = uframe & 7;
1049 1254
1255#ifdef CONFIG_USB_EHCI_TT_NEWSCHED
1256 /* The tt's fullspeed bus bandwidth must be available.
1257 * tt_available scheduling guarantees 10+% for control/bulk.
1258 */
1259 if (!tt_available (ehci, period_uframes << 3,
1260 stream->udev, frame, uf, stream->tt_usecs))
1261 return 0;
1262#else
1050 /* tt must be idle for start(s), any gap, and csplit. 1263 /* tt must be idle for start(s), any gap, and csplit.
1051 * assume scheduling slop leaves 10+% for control/bulk. 1264 * assume scheduling slop leaves 10+% for control/bulk.
1052 */ 1265 */
1053 if (!tt_no_collision (ehci, period_uframes << 3, 1266 if (!tt_no_collision (ehci, period_uframes << 3,
1054 stream->udev, frame, mask)) 1267 stream->udev, frame, mask))
1055 return 0; 1268 return 0;
1269#endif
1056 1270
1057 /* check starts (OUT uses more than one) */ 1271 /* check starts (OUT uses more than one) */
1058 max_used = 100 - stream->usecs; 1272 max_used = 100 - stream->usecs;
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index e99210b7909b..14386254c870 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -63,7 +63,7 @@
63#include <linux/init.h> 63#include <linux/init.h>
64#include <linux/list.h> 64#include <linux/list.h>
65#include <linux/usb.h> 65#include <linux/usb.h>
66#include <linux/usb_isp116x.h> 66#include <linux/usb/isp116x.h>
67#include <linux/platform_device.h> 67#include <linux/platform_device.h>
68 68
69#include <asm/io.h> 69#include <asm/io.h>
@@ -781,7 +781,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
781 if (ep->branch < PERIODIC_SIZE) 781 if (ep->branch < PERIODIC_SIZE)
782 break; 782 break;
783 783
784 ret = ep->branch = balance(isp116x, ep->period, ep->load); 784 ep->branch = ret = balance(isp116x, ep->period, ep->load);
785 if (ret < 0) 785 if (ret < 0)
786 goto fail; 786 goto fail;
787 ret = 0; 787 ret = 0;
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index a92343052751..6b4bc3f2bd86 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -46,7 +46,7 @@
46#include <linux/list.h> 46#include <linux/list.h>
47#include <linux/interrupt.h> 47#include <linux/interrupt.h>
48#include <linux/usb.h> 48#include <linux/usb.h>
49#include <linux/usb_sl811.h> 49#include <linux/usb/sl811.h>
50#include <linux/platform_device.h> 50#include <linux/platform_device.h>
51 51
52#include <asm/io.h> 52#include <asm/io.h>
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 302aa1ec312f..54f554e0f0ad 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -27,7 +27,7 @@
27#include <pcmcia/cisreg.h> 27#include <pcmcia/cisreg.h>
28#include <pcmcia/ds.h> 28#include <pcmcia/ds.h>
29 29
30#include <linux/usb_sl811.h> 30#include <linux/usb/sl811.h>
31 31
32MODULE_AUTHOR("Botond Botyanszki"); 32MODULE_AUTHOR("Botond Botyanszki");
33MODULE_DESCRIPTION("REX-CFU1U PCMCIA driver for 2.6"); 33MODULE_DESCRIPTION("REX-CFU1U PCMCIA driver for 2.6");
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index e1239319655c..6637a0e49978 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -98,6 +98,7 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space)
98 char *out = buf; 98 char *out = buf;
99 struct uhci_td *td; 99 struct uhci_td *td;
100 int i, nactive, ninactive; 100 int i, nactive, ninactive;
101 char *ptype;
101 102
102 if (len < 200) 103 if (len < 200)
103 return 0; 104 return 0;
@@ -110,13 +111,15 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space)
110 (usb_pipein(urbp->urb->pipe) ? "IN" : "OUT")); 111 (usb_pipein(urbp->urb->pipe) ? "IN" : "OUT"));
111 112
112 switch (usb_pipetype(urbp->urb->pipe)) { 113 switch (usb_pipetype(urbp->urb->pipe)) {
113 case PIPE_ISOCHRONOUS: out += sprintf(out, "ISO"); break; 114 case PIPE_ISOCHRONOUS: ptype = "ISO"; break;
114 case PIPE_INTERRUPT: out += sprintf(out, "INT"); break; 115 case PIPE_INTERRUPT: ptype = "INT"; break;
115 case PIPE_BULK: out += sprintf(out, "BLK"); break; 116 case PIPE_BULK: ptype = "BLK"; break;
116 case PIPE_CONTROL: out += sprintf(out, "CTL"); break; 117 default:
118 case PIPE_CONTROL: ptype = "CTL"; break;
117 } 119 }
118 120
119 out += sprintf(out, "%s", (urbp->fsbr ? " FSBR" : "")); 121 out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : ""));
122 out += sprintf(out, " Actlen=%d", urbp->urb->actual_length);
120 123
121 if (urbp->urb->status != -EINPROGRESS) 124 if (urbp->urb->status != -EINPROGRESS)
122 out += sprintf(out, " Status=%d", urbp->urb->status); 125 out += sprintf(out, " Status=%d", urbp->urb->status);
@@ -124,7 +127,8 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space)
124 127
125 i = nactive = ninactive = 0; 128 i = nactive = ninactive = 0;
126 list_for_each_entry(td, &urbp->td_list, list) { 129 list_for_each_entry(td, &urbp->td_list, list) {
127 if (++i <= 10 || debug > 2) { 130 if (urbp->qh->type != USB_ENDPOINT_XFER_ISOC &&
131 (++i <= 10 || debug > 2)) {
128 out += sprintf(out, "%*s%d: ", space + 2, "", i); 132 out += sprintf(out, "%*s%d: ", space + 2, "", i);
129 out += uhci_show_td(td, out, len - (out - buf), 0); 133 out += uhci_show_td(td, out, len - (out - buf), 0);
130 } else { 134 } else {
@@ -147,13 +151,27 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
147 char *out = buf; 151 char *out = buf;
148 int i, nurbs; 152 int i, nurbs;
149 __le32 element = qh_element(qh); 153 __le32 element = qh_element(qh);
154 char *qtype;
150 155
151 /* Try to make sure there's enough memory */ 156 /* Try to make sure there's enough memory */
152 if (len < 80 * 6) 157 if (len < 80 * 7)
153 return 0; 158 return 0;
154 159
155 out += sprintf(out, "%*s[%p] link (%08x) element (%08x)\n", space, "", 160 switch (qh->type) {
156 qh, le32_to_cpu(qh->link), le32_to_cpu(element)); 161 case USB_ENDPOINT_XFER_ISOC: qtype = "ISO"; break;
162 case USB_ENDPOINT_XFER_INT: qtype = "INT"; break;
163 case USB_ENDPOINT_XFER_BULK: qtype = "BLK"; break;
164 case USB_ENDPOINT_XFER_CONTROL: qtype = "CTL"; break;
165 default: qtype = "Skel" ; break;
166 }
167
168 out += sprintf(out, "%*s[%p] %s QH link (%08x) element (%08x)\n",
169 space, "", qh, qtype,
170 le32_to_cpu(qh->link), le32_to_cpu(element));
171 if (qh->type == USB_ENDPOINT_XFER_ISOC)
172 out += sprintf(out, "%*s period %d frame %x desc [%p]\n",
173 space, "", qh->period, qh->iso_frame,
174 qh->iso_packet_desc);
157 175
158 if (element & UHCI_PTR_QH) 176 if (element & UHCI_PTR_QH)
159 out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); 177 out += sprintf(out, "%*s Element points to QH (bug?)\n", space, "");
@@ -261,7 +279,8 @@ static int uhci_show_root_hub_state(struct uhci_hcd *uhci, char *buf, int len)
261 default: 279 default:
262 rh_state = "?"; break; 280 rh_state = "?"; break;
263 } 281 }
264 out += sprintf(out, "Root-hub state: %s\n", rh_state); 282 out += sprintf(out, "Root-hub state: %s FSBR: %d\n",
283 rh_state, uhci->fsbr_is_on);
265 return out - buf; 284 return out - buf;
266} 285}
267 286
@@ -275,7 +294,7 @@ static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len)
275 unsigned short portsc1, portsc2; 294 unsigned short portsc1, portsc2;
276 295
277 /* Try to make sure there's enough memory */ 296 /* Try to make sure there's enough memory */
278 if (len < 80 * 6) 297 if (len < 80 * 9)
279 return 0; 298 return 0;
280 299
281 usbcmd = inw(io_addr + 0); 300 usbcmd = inw(io_addr + 0);
@@ -314,6 +333,10 @@ static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len)
314 out += sprintf(out, " sof = %02x\n", sof); 333 out += sprintf(out, " sof = %02x\n", sof);
315 out += uhci_show_sc(1, portsc1, out, len - (out - buf)); 334 out += uhci_show_sc(1, portsc1, out, len - (out - buf));
316 out += uhci_show_sc(2, portsc2, out, len - (out - buf)); 335 out += uhci_show_sc(2, portsc2, out, len - (out - buf));
336 out += sprintf(out, "Most recent frame: %x (%d) "
337 "Last ISO frame: %x (%d)\n",
338 uhci->frame_number, uhci->frame_number & 1023,
339 uhci->last_iso_frame, uhci->last_iso_frame & 1023);
317 340
318 return out - buf; 341 return out - buf;
319} 342}
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index d225e11f4055..7b48567622ef 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -13,7 +13,7 @@
13 * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface 13 * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
14 * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). 14 * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
15 * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) 15 * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
16 * (C) Copyright 2004-2005 Alan Stern, stern@rowland.harvard.edu 16 * (C) Copyright 2004-2006 Alan Stern, stern@rowland.harvard.edu
17 * 17 *
18 * Intel documents this fairly well, and as far as I know there 18 * Intel documents this fairly well, and as far as I know there
19 * are no royalties or anything like that, but even so there are 19 * are no royalties or anything like that, but even so there are
@@ -31,7 +31,6 @@
31#include <linux/ioport.h> 31#include <linux/ioport.h>
32#include <linux/sched.h> 32#include <linux/sched.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/smp_lock.h>
35#include <linux/errno.h> 34#include <linux/errno.h>
36#include <linux/unistd.h> 35#include <linux/unistd.h>
37#include <linux/interrupt.h> 36#include <linux/interrupt.h>
@@ -88,15 +87,6 @@ static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state);
88static void wakeup_rh(struct uhci_hcd *uhci); 87static void wakeup_rh(struct uhci_hcd *uhci);
89static void uhci_get_current_frame_number(struct uhci_hcd *uhci); 88static void uhci_get_current_frame_number(struct uhci_hcd *uhci);
90 89
91/* If a transfer is still active after this much time, turn off FSBR */
92#define IDLE_TIMEOUT msecs_to_jiffies(50)
93#define FSBR_DELAY msecs_to_jiffies(50)
94
95/* When we timeout an idle transfer for FSBR, we'll switch it over to */
96/* depth first traversal. We'll do it in groups of this number of TDs */
97/* to make sure it doesn't hog all of the bandwidth */
98#define DEPTH_INTERVAL 5
99
100#include "uhci-debug.c" 90#include "uhci-debug.c"
101#include "uhci-q.c" 91#include "uhci-q.c"
102#include "uhci-hub.c" 92#include "uhci-hub.c"
@@ -120,22 +110,29 @@ static void finish_reset(struct uhci_hcd *uhci)
120 uhci->is_stopped = UHCI_IS_STOPPED; 110 uhci->is_stopped = UHCI_IS_STOPPED;
121 uhci_to_hcd(uhci)->state = HC_STATE_HALT; 111 uhci_to_hcd(uhci)->state = HC_STATE_HALT;
122 uhci_to_hcd(uhci)->poll_rh = 0; 112 uhci_to_hcd(uhci)->poll_rh = 0;
113
114 uhci->dead = 0; /* Full reset resurrects the controller */
123} 115}
124 116
125/* 117/*
126 * Last rites for a defunct/nonfunctional controller 118 * Last rites for a defunct/nonfunctional controller
127 * or one we don't want to use any more. 119 * or one we don't want to use any more.
128 */ 120 */
129static void hc_died(struct uhci_hcd *uhci) 121static void uhci_hc_died(struct uhci_hcd *uhci)
130{ 122{
123 uhci_get_current_frame_number(uhci);
131 uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr); 124 uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr);
132 finish_reset(uhci); 125 finish_reset(uhci);
133 uhci->hc_inaccessible = 1; 126 uhci->dead = 1;
127
128 /* The current frame may already be partway finished */
129 ++uhci->frame_number;
134} 130}
135 131
136/* 132/*
137 * Initialize a controller that was newly discovered or has just been 133 * Initialize a controller that was newly discovered or has lost power
138 * resumed. In either case we can't be sure of its previous state. 134 * or otherwise been reset while it was suspended. In none of these cases
135 * can we be sure of its previous state.
139 */ 136 */
140static void check_and_reset_hc(struct uhci_hcd *uhci) 137static void check_and_reset_hc(struct uhci_hcd *uhci)
141{ 138{
@@ -155,7 +152,8 @@ static void configure_hc(struct uhci_hcd *uhci)
155 outl(uhci->frame_dma_handle, uhci->io_addr + USBFLBASEADD); 152 outl(uhci->frame_dma_handle, uhci->io_addr + USBFLBASEADD);
156 153
157 /* Set the current frame number */ 154 /* Set the current frame number */
158 outw(uhci->frame_number, uhci->io_addr + USBFRNUM); 155 outw(uhci->frame_number & UHCI_MAX_SOF_NUMBER,
156 uhci->io_addr + USBFRNUM);
159 157
160 /* Mark controller as not halted before we enable interrupts */ 158 /* Mark controller as not halted before we enable interrupts */
161 uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED; 159 uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED;
@@ -207,7 +205,8 @@ __acquires(uhci->lock)
207 int int_enable; 205 int int_enable;
208 206
209 auto_stop = (new_state == UHCI_RH_AUTO_STOPPED); 207 auto_stop = (new_state == UHCI_RH_AUTO_STOPPED);
210 dev_dbg(uhci_dev(uhci), "%s%s\n", __FUNCTION__, 208 dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev,
209 "%s%s\n", __FUNCTION__,
211 (auto_stop ? " (auto-stop)" : "")); 210 (auto_stop ? " (auto-stop)" : ""));
212 211
213 /* If we get a suspend request when we're already auto-stopped 212 /* If we get a suspend request when we're already auto-stopped
@@ -241,27 +240,27 @@ __acquires(uhci->lock)
241 spin_unlock_irq(&uhci->lock); 240 spin_unlock_irq(&uhci->lock);
242 msleep(1); 241 msleep(1);
243 spin_lock_irq(&uhci->lock); 242 spin_lock_irq(&uhci->lock);
244 if (uhci->hc_inaccessible) /* Died */ 243 if (uhci->dead)
245 return; 244 return;
246 } 245 }
247 if (!(inw(uhci->io_addr + USBSTS) & USBSTS_HCH)) 246 if (!(inw(uhci->io_addr + USBSTS) & USBSTS_HCH))
248 dev_warn(uhci_dev(uhci), "Controller not stopped yet!\n"); 247 dev_warn(&uhci_to_hcd(uhci)->self.root_hub->dev,
248 "Controller not stopped yet!\n");
249 249
250 uhci_get_current_frame_number(uhci); 250 uhci_get_current_frame_number(uhci);
251 smp_wmb();
252 251
253 uhci->rh_state = new_state; 252 uhci->rh_state = new_state;
254 uhci->is_stopped = UHCI_IS_STOPPED; 253 uhci->is_stopped = UHCI_IS_STOPPED;
255 uhci_to_hcd(uhci)->poll_rh = !int_enable; 254 uhci_to_hcd(uhci)->poll_rh = !int_enable;
256 255
257 uhci_scan_schedule(uhci, NULL); 256 uhci_scan_schedule(uhci, NULL);
257 uhci_fsbr_off(uhci);
258} 258}
259 259
260static void start_rh(struct uhci_hcd *uhci) 260static void start_rh(struct uhci_hcd *uhci)
261{ 261{
262 uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; 262 uhci_to_hcd(uhci)->state = HC_STATE_RUNNING;
263 uhci->is_stopped = 0; 263 uhci->is_stopped = 0;
264 smp_wmb();
265 264
266 /* Mark it configured and running with a 64-byte max packet. 265 /* Mark it configured and running with a 64-byte max packet.
267 * All interrupts are enabled, even though RESUME won't do anything. 266 * All interrupts are enabled, even though RESUME won't do anything.
@@ -278,7 +277,8 @@ static void wakeup_rh(struct uhci_hcd *uhci)
278__releases(uhci->lock) 277__releases(uhci->lock)
279__acquires(uhci->lock) 278__acquires(uhci->lock)
280{ 279{
281 dev_dbg(uhci_dev(uhci), "%s%s\n", __FUNCTION__, 280 dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev,
281 "%s%s\n", __FUNCTION__,
282 uhci->rh_state == UHCI_RH_AUTO_STOPPED ? 282 uhci->rh_state == UHCI_RH_AUTO_STOPPED ?
283 " (auto-start)" : ""); 283 " (auto-start)" : "");
284 284
@@ -293,7 +293,7 @@ __acquires(uhci->lock)
293 spin_unlock_irq(&uhci->lock); 293 spin_unlock_irq(&uhci->lock);
294 msleep(20); 294 msleep(20);
295 spin_lock_irq(&uhci->lock); 295 spin_lock_irq(&uhci->lock);
296 if (uhci->hc_inaccessible) /* Died */ 296 if (uhci->dead)
297 return; 297 return;
298 298
299 /* End Global Resume and wait for EOP to be sent */ 299 /* End Global Resume and wait for EOP to be sent */
@@ -345,7 +345,7 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
345 errbuf, ERRBUF_LEN); 345 errbuf, ERRBUF_LEN);
346 lprintk(errbuf); 346 lprintk(errbuf);
347 } 347 }
348 hc_died(uhci); 348 uhci_hc_died(uhci);
349 349
350 /* Force a callback in case there are 350 /* Force a callback in case there are
351 * pending unlinks */ 351 * pending unlinks */
@@ -368,12 +368,21 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
368 368
369/* 369/*
370 * Store the current frame number in uhci->frame_number if the controller 370 * Store the current frame number in uhci->frame_number if the controller
371 * is runnning 371 * is runnning. Expand from 11 bits (of which we use only 10) to a
372 * full-sized integer.
373 *
374 * Like many other parts of the driver, this code relies on being polled
375 * more than once per second as long as the controller is running.
372 */ 376 */
373static void uhci_get_current_frame_number(struct uhci_hcd *uhci) 377static void uhci_get_current_frame_number(struct uhci_hcd *uhci)
374{ 378{
375 if (!uhci->is_stopped) 379 if (!uhci->is_stopped) {
376 uhci->frame_number = inw(uhci->io_addr + USBFRNUM); 380 unsigned delta;
381
382 delta = (inw(uhci->io_addr + USBFRNUM) - uhci->frame_number) &
383 (UHCI_NUMFRAMES - 1);
384 uhci->frame_number += delta;
385 }
377} 386}
378 387
379/* 388/*
@@ -407,7 +416,7 @@ static void release_uhci(struct uhci_hcd *uhci)
407 uhci->frame, uhci->frame_dma_handle); 416 uhci->frame, uhci->frame_dma_handle);
408} 417}
409 418
410static int uhci_reset(struct usb_hcd *hcd) 419static int uhci_init(struct usb_hcd *hcd)
411{ 420{
412 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 421 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
413 unsigned io_size = (unsigned) hcd->rsrc_len; 422 unsigned io_size = (unsigned) hcd->rsrc_len;
@@ -459,7 +468,7 @@ static void uhci_shutdown(struct pci_dev *pdev)
459{ 468{
460 struct usb_hcd *hcd = (struct usb_hcd *) pci_get_drvdata(pdev); 469 struct usb_hcd *hcd = (struct usb_hcd *) pci_get_drvdata(pdev);
461 470
462 hc_died(hcd_to_uhci(hcd)); 471 uhci_hc_died(hcd_to_uhci(hcd));
463} 472}
464 473
465/* 474/*
@@ -487,14 +496,10 @@ static int uhci_start(struct usb_hcd *hcd)
487 496
488 hcd->uses_new_polling = 1; 497 hcd->uses_new_polling = 1;
489 498
490 uhci->fsbr = 0;
491 uhci->fsbrtimeout = 0;
492
493 spin_lock_init(&uhci->lock); 499 spin_lock_init(&uhci->lock);
494 500 setup_timer(&uhci->fsbr_timer, uhci_fsbr_timeout,
495 INIT_LIST_HEAD(&uhci->td_remove_list); 501 (unsigned long) uhci);
496 INIT_LIST_HEAD(&uhci->idle_qh_list); 502 INIT_LIST_HEAD(&uhci->idle_qh_list);
497
498 init_waitqueue_head(&uhci->waitqh); 503 init_waitqueue_head(&uhci->waitqh);
499 504
500 if (DEBUG_CONFIGURED) { 505 if (DEBUG_CONFIGURED) {
@@ -665,11 +670,12 @@ static void uhci_stop(struct usb_hcd *hcd)
665 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 670 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
666 671
667 spin_lock_irq(&uhci->lock); 672 spin_lock_irq(&uhci->lock);
668 if (!uhci->hc_inaccessible) 673 if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) && !uhci->dead)
669 hc_died(uhci); 674 uhci_hc_died(uhci);
670 uhci_scan_schedule(uhci, NULL); 675 uhci_scan_schedule(uhci, NULL);
671 spin_unlock_irq(&uhci->lock); 676 spin_unlock_irq(&uhci->lock);
672 677
678 del_timer_sync(&uhci->fsbr_timer);
673 release_uhci(uhci); 679 release_uhci(uhci);
674} 680}
675 681
@@ -677,12 +683,15 @@ static void uhci_stop(struct usb_hcd *hcd)
677static int uhci_rh_suspend(struct usb_hcd *hcd) 683static int uhci_rh_suspend(struct usb_hcd *hcd)
678{ 684{
679 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 685 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
686 int rc = 0;
680 687
681 spin_lock_irq(&uhci->lock); 688 spin_lock_irq(&uhci->lock);
682 if (!uhci->hc_inaccessible) /* Not dead */ 689 if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
690 rc = -ESHUTDOWN;
691 else if (!uhci->dead)
683 suspend_rh(uhci, UHCI_RH_SUSPENDED); 692 suspend_rh(uhci, UHCI_RH_SUSPENDED);
684 spin_unlock_irq(&uhci->lock); 693 spin_unlock_irq(&uhci->lock);
685 return 0; 694 return rc;
686} 695}
687 696
688static int uhci_rh_resume(struct usb_hcd *hcd) 697static int uhci_rh_resume(struct usb_hcd *hcd)
@@ -691,13 +700,10 @@ static int uhci_rh_resume(struct usb_hcd *hcd)
691 int rc = 0; 700 int rc = 0;
692 701
693 spin_lock_irq(&uhci->lock); 702 spin_lock_irq(&uhci->lock);
694 if (uhci->hc_inaccessible) { 703 if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
695 if (uhci->rh_state == UHCI_RH_SUSPENDED) { 704 dev_warn(&hcd->self.root_hub->dev, "HC isn't running!\n");
696 dev_warn(uhci_dev(uhci), "HC isn't running!\n"); 705 rc = -ESHUTDOWN;
697 rc = -ENODEV; 706 } else if (!uhci->dead)
698 }
699 /* Otherwise the HC is dead */
700 } else
701 wakeup_rh(uhci); 707 wakeup_rh(uhci);
702 spin_unlock_irq(&uhci->lock); 708 spin_unlock_irq(&uhci->lock);
703 return rc; 709 return rc;
@@ -711,8 +717,8 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
711 dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); 717 dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
712 718
713 spin_lock_irq(&uhci->lock); 719 spin_lock_irq(&uhci->lock);
714 if (uhci->hc_inaccessible) /* Dead or already suspended */ 720 if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead)
715 goto done; 721 goto done_okay; /* Already suspended or dead */
716 722
717 if (uhci->rh_state > UHCI_RH_SUSPENDED) { 723 if (uhci->rh_state > UHCI_RH_SUSPENDED) {
718 dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n"); 724 dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n");
@@ -725,12 +731,12 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
725 */ 731 */
726 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0); 732 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
727 mb(); 733 mb();
728 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
729 uhci->hc_inaccessible = 1;
730 hcd->poll_rh = 0; 734 hcd->poll_rh = 0;
731 735
732 /* FIXME: Enable non-PME# remote wakeup? */ 736 /* FIXME: Enable non-PME# remote wakeup? */
733 737
738done_okay:
739 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
734done: 740done:
735 spin_unlock_irq(&uhci->lock); 741 spin_unlock_irq(&uhci->lock);
736 return rc; 742 return rc;
@@ -743,24 +749,22 @@ static int uhci_resume(struct usb_hcd *hcd)
743 dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); 749 dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
744 750
745 /* Since we aren't in D3 any more, it's safe to set this flag 751 /* Since we aren't in D3 any more, it's safe to set this flag
746 * even if the controller was dead. It might not even be dead 752 * even if the controller was dead.
747 * any more, if the firmware or quirks code has reset it.
748 */ 753 */
749 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 754 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
750 mb(); 755 mb();
751 756
752 if (uhci->rh_state == UHCI_RH_RESET) /* Dead */
753 return 0;
754 spin_lock_irq(&uhci->lock); 757 spin_lock_irq(&uhci->lock);
755 758
756 /* FIXME: Disable non-PME# remote wakeup? */ 759 /* FIXME: Disable non-PME# remote wakeup? */
757 760
758 uhci->hc_inaccessible = 0; 761 /* The firmware or a boot kernel may have changed the controller
759 762 * settings during a system wakeup. Check it and reconfigure
760 /* The BIOS may have changed the controller settings during a 763 * to avoid problems.
761 * system wakeup. Check it and reconfigure to avoid problems.
762 */ 764 */
763 check_and_reset_hc(uhci); 765 check_and_reset_hc(uhci);
766
767 /* If the controller was dead before, it's back alive now */
764 configure_hc(uhci); 768 configure_hc(uhci);
765 769
766 if (uhci->rh_state == UHCI_RH_RESET) { 770 if (uhci->rh_state == UHCI_RH_RESET) {
@@ -810,18 +814,15 @@ done:
810static int uhci_hcd_get_frame_number(struct usb_hcd *hcd) 814static int uhci_hcd_get_frame_number(struct usb_hcd *hcd)
811{ 815{
812 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 816 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
813 unsigned long flags; 817 unsigned frame_number;
814 int is_stopped; 818 unsigned delta;
815 int frame_number;
816 819
817 /* Minimize latency by avoiding the spinlock */ 820 /* Minimize latency by avoiding the spinlock */
818 local_irq_save(flags); 821 frame_number = uhci->frame_number;
819 is_stopped = uhci->is_stopped; 822 barrier();
820 smp_rmb(); 823 delta = (inw(uhci->io_addr + USBFRNUM) - frame_number) &
821 frame_number = (is_stopped ? uhci->frame_number : 824 (UHCI_NUMFRAMES - 1);
822 inw(uhci->io_addr + USBFRNUM)); 825 return frame_number + delta;
823 local_irq_restore(flags);
824 return frame_number;
825} 826}
826 827
827static const char hcd_name[] = "uhci_hcd"; 828static const char hcd_name[] = "uhci_hcd";
@@ -836,7 +837,7 @@ static const struct hc_driver uhci_driver = {
836 .flags = HCD_USB11, 837 .flags = HCD_USB11,
837 838
838 /* Basic lifecycle operations */ 839 /* Basic lifecycle operations */
839 .reset = uhci_reset, 840 .reset = uhci_init,
840 .start = uhci_start, 841 .start = uhci_start,
841#ifdef CONFIG_PM 842#ifdef CONFIG_PM
842 .suspend = uhci_suspend, 843 .suspend = uhci_suspend,
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index d5c8f4d92823..108e3de2dc26 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -84,6 +84,13 @@
84#define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames 84#define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames
85 * can be scheduled */ 85 * can be scheduled */
86 86
87/* When no queues need Full-Speed Bandwidth Reclamation,
88 * delay this long before turning FSBR off */
89#define FSBR_OFF_DELAY msecs_to_jiffies(10)
90
91/* If a queue hasn't advanced after this much time, assume it is stuck */
92#define QH_WAIT_TIMEOUT msecs_to_jiffies(200)
93
87 94
88/* 95/*
89 * Queue Headers 96 * Queue Headers
@@ -121,21 +128,31 @@ struct uhci_qh {
121 __le32 element; /* Queue element (TD) pointer */ 128 __le32 element; /* Queue element (TD) pointer */
122 129
123 /* Software fields */ 130 /* Software fields */
124 dma_addr_t dma_handle;
125
126 struct list_head node; /* Node in the list of QHs */ 131 struct list_head node; /* Node in the list of QHs */
127 struct usb_host_endpoint *hep; /* Endpoint information */ 132 struct usb_host_endpoint *hep; /* Endpoint information */
128 struct usb_device *udev; 133 struct usb_device *udev;
129 struct list_head queue; /* Queue of urbps for this QH */ 134 struct list_head queue; /* Queue of urbps for this QH */
130 struct uhci_qh *skel; /* Skeleton for this QH */ 135 struct uhci_qh *skel; /* Skeleton for this QH */
131 struct uhci_td *dummy_td; /* Dummy TD to end the queue */ 136 struct uhci_td *dummy_td; /* Dummy TD to end the queue */
137 struct uhci_td *post_td; /* Last TD completed */
132 138
139 struct usb_iso_packet_descriptor *iso_packet_desc;
140 /* Next urb->iso_frame_desc entry */
141 unsigned long advance_jiffies; /* Time of last queue advance */
133 unsigned int unlink_frame; /* When the QH was unlinked */ 142 unsigned int unlink_frame; /* When the QH was unlinked */
143 unsigned int period; /* For Interrupt and Isochronous QHs */
144 unsigned int iso_frame; /* Frame # for iso_packet_desc */
145 int iso_status; /* Status for Isochronous URBs */
146
134 int state; /* QH_STATE_xxx; see above */ 147 int state; /* QH_STATE_xxx; see above */
148 int type; /* Queue type (control, bulk, etc) */
149
150 dma_addr_t dma_handle;
135 151
136 unsigned int initial_toggle:1; /* Endpoint's current toggle value */ 152 unsigned int initial_toggle:1; /* Endpoint's current toggle value */
137 unsigned int needs_fixup:1; /* Must fix the TD toggle values */ 153 unsigned int needs_fixup:1; /* Must fix the TD toggle values */
138 unsigned int is_stopped:1; /* Queue was stopped by an error */ 154 unsigned int is_stopped:1; /* Queue was stopped by error/unlink */
155 unsigned int wait_expired:1; /* QH_WAIT_TIMEOUT has expired */
139} __attribute__((aligned(16))); 156} __attribute__((aligned(16)));
140 157
141/* 158/*
@@ -226,7 +243,6 @@ struct uhci_td {
226 dma_addr_t dma_handle; 243 dma_addr_t dma_handle;
227 244
228 struct list_head list; 245 struct list_head list;
229 struct list_head remove_list;
230 246
231 int frame; /* for iso: what frame? */ 247 int frame; /* for iso: what frame? */
232 struct list_head fl_list; 248 struct list_head fl_list;
@@ -305,38 +321,8 @@ static inline u32 td_status(struct uhci_td *td) {
305#define skel_bulk_qh skelqh[12] 321#define skel_bulk_qh skelqh[12]
306#define skel_term_qh skelqh[13] 322#define skel_term_qh skelqh[13]
307 323
308/* 324/* Find the skelqh entry corresponding to an interval exponent */
309 * Search tree for determining where <interval> fits in the skelqh[] 325#define UHCI_SKEL_INDEX(exponent) (9 - exponent)
310 * skeleton.
311 *
312 * An interrupt request should be placed into the slowest skelqh[]
313 * which meets the interval/period/frequency requirement.
314 * An interrupt request is allowed to be faster than <interval> but not slower.
315 *
316 * For a given <interval>, this function returns the appropriate/matching
317 * skelqh[] index value.
318 */
319static inline int __interval_to_skel(int interval)
320{
321 if (interval < 16) {
322 if (interval < 4) {
323 if (interval < 2)
324 return 9; /* int1 for 0-1 ms */
325 return 8; /* int2 for 2-3 ms */
326 }
327 if (interval < 8)
328 return 7; /* int4 for 4-7 ms */
329 return 6; /* int8 for 8-15 ms */
330 }
331 if (interval < 64) {
332 if (interval < 32)
333 return 5; /* int16 for 16-31 ms */
334 return 4; /* int32 for 32-63 ms */
335 }
336 if (interval < 128)
337 return 3; /* int64 for 64-127 ms */
338 return 2; /* int128 for 128-255 ms (Max.) */
339}
340 326
341 327
342/* 328/*
@@ -396,32 +382,32 @@ struct uhci_hcd {
396 __le32 *frame; 382 __le32 *frame;
397 void **frame_cpu; /* CPU's frame list */ 383 void **frame_cpu; /* CPU's frame list */
398 384
399 int fsbr; /* Full-speed bandwidth reclamation */
400 unsigned long fsbrtimeout; /* FSBR delay */
401
402 enum uhci_rh_state rh_state; 385 enum uhci_rh_state rh_state;
403 unsigned long auto_stop_time; /* When to AUTO_STOP */ 386 unsigned long auto_stop_time; /* When to AUTO_STOP */
404 387
405 unsigned int frame_number; /* As of last check */ 388 unsigned int frame_number; /* As of last check */
406 unsigned int is_stopped; 389 unsigned int is_stopped;
407#define UHCI_IS_STOPPED 9999 /* Larger than a frame # */ 390#define UHCI_IS_STOPPED 9999 /* Larger than a frame # */
391 unsigned int last_iso_frame; /* Frame of last scan */
392 unsigned int cur_iso_frame; /* Frame for current scan */
408 393
409 unsigned int scan_in_progress:1; /* Schedule scan is running */ 394 unsigned int scan_in_progress:1; /* Schedule scan is running */
410 unsigned int need_rescan:1; /* Redo the schedule scan */ 395 unsigned int need_rescan:1; /* Redo the schedule scan */
411 unsigned int hc_inaccessible:1; /* HC is suspended or dead */ 396 unsigned int dead:1; /* Controller has died */
412 unsigned int working_RD:1; /* Suspended root hub doesn't 397 unsigned int working_RD:1; /* Suspended root hub doesn't
413 need to be polled */ 398 need to be polled */
414 unsigned int is_initialized:1; /* Data structure is usable */ 399 unsigned int is_initialized:1; /* Data structure is usable */
400 unsigned int fsbr_is_on:1; /* FSBR is turned on */
401 unsigned int fsbr_is_wanted:1; /* Does any URB want FSBR? */
402 unsigned int fsbr_expiring:1; /* FSBR is timing out */
403
404 struct timer_list fsbr_timer; /* For turning off FBSR */
415 405
416 /* Support for port suspend/resume/reset */ 406 /* Support for port suspend/resume/reset */
417 unsigned long port_c_suspend; /* Bit-arrays of ports */ 407 unsigned long port_c_suspend; /* Bit-arrays of ports */
418 unsigned long resuming_ports; 408 unsigned long resuming_ports;
419 unsigned long ports_timeout; /* Time to stop signalling */ 409 unsigned long ports_timeout; /* Time to stop signalling */
420 410
421 /* List of TDs that are done, but waiting to be freed (race) */
422 struct list_head td_remove_list;
423 unsigned int td_remove_age; /* Age in frames */
424
425 struct list_head idle_qh_list; /* Where the idle QHs live */ 411 struct list_head idle_qh_list; /* Where the idle QHs live */
426 412
427 int rh_numports; /* Number of root-hub ports */ 413 int rh_numports; /* Number of root-hub ports */
@@ -442,6 +428,9 @@ static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci)
442 428
443#define uhci_dev(u) (uhci_to_hcd(u)->self.controller) 429#define uhci_dev(u) (uhci_to_hcd(u)->self.controller)
444 430
431/* Utility macro for comparing frame numbers */
432#define uhci_frame_before_eq(f1, f2) (0 <= (int) ((f2) - (f1)))
433
445 434
446/* 435/*
447 * Private per-URB data 436 * Private per-URB data
@@ -454,9 +443,7 @@ struct urb_priv {
454 struct uhci_qh *qh; /* QH for this URB */ 443 struct uhci_qh *qh; /* QH for this URB */
455 struct list_head td_list; 444 struct list_head td_list;
456 445
457 unsigned fsbr : 1; /* URB turned on FSBR */ 446 unsigned fsbr:1; /* URB wants FSBR */
458 unsigned short_transfer : 1; /* URB got a short transfer, no
459 * need to rescan */
460}; 447};
461 448
462 449
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
index c8451d9578f1..c545ef92fe29 100644
--- a/drivers/usb/host/uhci-hub.c
+++ b/drivers/usb/host/uhci-hub.c
@@ -171,9 +171,8 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
171 spin_lock_irqsave(&uhci->lock, flags); 171 spin_lock_irqsave(&uhci->lock, flags);
172 172
173 uhci_scan_schedule(uhci, NULL); 173 uhci_scan_schedule(uhci, NULL);
174 if (uhci->hc_inaccessible) 174 if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead)
175 goto done; 175 goto done;
176 check_fsbr(uhci);
177 uhci_check_ports(uhci); 176 uhci_check_ports(uhci);
178 177
179 status = get_hub_status_data(uhci, buf); 178 status = get_hub_status_data(uhci, buf);
@@ -228,7 +227,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
228 u16 wPortChange, wPortStatus; 227 u16 wPortChange, wPortStatus;
229 unsigned long flags; 228 unsigned long flags;
230 229
231 if (uhci->hc_inaccessible) 230 if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead)
232 return -ETIMEDOUT; 231 return -ETIMEDOUT;
233 232
234 spin_lock_irqsave(&uhci->lock, flags); 233 spin_lock_irqsave(&uhci->lock, flags);
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index a06d84c19e13..c9d72ac0a1d7 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -13,10 +13,9 @@
13 * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface 13 * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
14 * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). 14 * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
15 * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) 15 * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
16 * (C) Copyright 2004-2005 Alan Stern, stern@rowland.harvard.edu 16 * (C) Copyright 2004-2006 Alan Stern, stern@rowland.harvard.edu
17 */ 17 */
18 18
19static void uhci_free_pending_tds(struct uhci_hcd *uhci);
20 19
21/* 20/*
22 * Technically, updating td->status here is a race, but it's not really a 21 * Technically, updating td->status here is a race, but it's not really a
@@ -38,6 +37,60 @@ static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci)
38 uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC); 37 uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC);
39} 38}
40 39
40
41/*
42 * Full-Speed Bandwidth Reclamation (FSBR).
43 * We turn on FSBR whenever a queue that wants it is advancing,
44 * and leave it on for a short time thereafter.
45 */
46static void uhci_fsbr_on(struct uhci_hcd *uhci)
47{
48 uhci->fsbr_is_on = 1;
49 uhci->skel_term_qh->link = cpu_to_le32(
50 uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH;
51}
52
53static void uhci_fsbr_off(struct uhci_hcd *uhci)
54{
55 uhci->fsbr_is_on = 0;
56 uhci->skel_term_qh->link = UHCI_PTR_TERM;
57}
58
59static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb)
60{
61 struct urb_priv *urbp = urb->hcpriv;
62
63 if (!(urb->transfer_flags & URB_NO_FSBR))
64 urbp->fsbr = 1;
65}
66
67static void uhci_urbp_wants_fsbr(struct uhci_hcd *uhci, struct urb_priv *urbp)
68{
69 if (urbp->fsbr) {
70 uhci->fsbr_is_wanted = 1;
71 if (!uhci->fsbr_is_on)
72 uhci_fsbr_on(uhci);
73 else if (uhci->fsbr_expiring) {
74 uhci->fsbr_expiring = 0;
75 del_timer(&uhci->fsbr_timer);
76 }
77 }
78}
79
80static void uhci_fsbr_timeout(unsigned long _uhci)
81{
82 struct uhci_hcd *uhci = (struct uhci_hcd *) _uhci;
83 unsigned long flags;
84
85 spin_lock_irqsave(&uhci->lock, flags);
86 if (uhci->fsbr_expiring) {
87 uhci->fsbr_expiring = 0;
88 uhci_fsbr_off(uhci);
89 }
90 spin_unlock_irqrestore(&uhci->lock, flags);
91}
92
93
41static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci) 94static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
42{ 95{
43 dma_addr_t dma_handle; 96 dma_addr_t dma_handle;
@@ -51,7 +104,6 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
51 td->frame = -1; 104 td->frame = -1;
52 105
53 INIT_LIST_HEAD(&td->list); 106 INIT_LIST_HEAD(&td->list);
54 INIT_LIST_HEAD(&td->remove_list);
55 INIT_LIST_HEAD(&td->fl_list); 107 INIT_LIST_HEAD(&td->fl_list);
56 108
57 return td; 109 return td;
@@ -61,8 +113,6 @@ static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
61{ 113{
62 if (!list_empty(&td->list)) 114 if (!list_empty(&td->list))
63 dev_warn(uhci_dev(uhci), "td %p still in list!\n", td); 115 dev_warn(uhci_dev(uhci), "td %p still in list!\n", td);
64 if (!list_empty(&td->remove_list))
65 dev_warn(uhci_dev(uhci), "td %p still in remove_list!\n", td);
66 if (!list_empty(&td->fl_list)) 116 if (!list_empty(&td->fl_list))
67 dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td); 117 dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td);
68 118
@@ -77,6 +127,16 @@ static inline void uhci_fill_td(struct uhci_td *td, u32 status,
77 td->buffer = cpu_to_le32(buffer); 127 td->buffer = cpu_to_le32(buffer);
78} 128}
79 129
130static void uhci_add_td_to_urbp(struct uhci_td *td, struct urb_priv *urbp)
131{
132 list_add_tail(&td->list, &urbp->td_list);
133}
134
135static void uhci_remove_td_from_urbp(struct uhci_td *td)
136{
137 list_del_init(&td->list);
138}
139
80/* 140/*
81 * We insert Isochronous URBs directly into the frame list at the beginning 141 * We insert Isochronous URBs directly into the frame list at the beginning
82 */ 142 */
@@ -138,6 +198,24 @@ static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci,
138 td->frame = -1; 198 td->frame = -1;
139} 199}
140 200
201static inline void uhci_remove_tds_from_frame(struct uhci_hcd *uhci,
202 unsigned int framenum)
203{
204 struct uhci_td *ftd, *ltd;
205
206 framenum &= (UHCI_NUMFRAMES - 1);
207
208 ftd = uhci->frame_cpu[framenum];
209 if (ftd) {
210 ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list);
211 uhci->frame[framenum] = ltd->link;
212 uhci->frame_cpu[framenum] = NULL;
213
214 while (!list_empty(&ftd->fl_list))
215 list_del_init(ftd->fl_list.prev);
216 }
217}
218
141/* 219/*
142 * Remove all the TDs for an Isochronous URB from the frame list 220 * Remove all the TDs for an Isochronous URB from the frame list
143 */ 221 */
@@ -148,7 +226,6 @@ static void uhci_unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb)
148 226
149 list_for_each_entry(td, &urbp->td_list, list) 227 list_for_each_entry(td, &urbp->td_list, list)
150 uhci_remove_td_from_frame_list(uhci, td); 228 uhci_remove_td_from_frame_list(uhci, td);
151 wmb();
152} 229}
153 230
154static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, 231static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
@@ -161,6 +238,7 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
161 if (!qh) 238 if (!qh)
162 return NULL; 239 return NULL;
163 240
241 memset(qh, 0, sizeof(*qh));
164 qh->dma_handle = dma_handle; 242 qh->dma_handle = dma_handle;
165 243
166 qh->element = UHCI_PTR_TERM; 244 qh->element = UHCI_PTR_TERM;
@@ -179,10 +257,11 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
179 qh->hep = hep; 257 qh->hep = hep;
180 qh->udev = udev; 258 qh->udev = udev;
181 hep->hcpriv = qh; 259 hep->hcpriv = qh;
260 qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
182 261
183 } else { /* Skeleton QH */ 262 } else { /* Skeleton QH */
184 qh->state = QH_STATE_ACTIVE; 263 qh->state = QH_STATE_ACTIVE;
185 qh->udev = NULL; 264 qh->type = -1;
186 } 265 }
187 return qh; 266 return qh;
188} 267}
@@ -202,35 +281,64 @@ static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
202} 281}
203 282
204/* 283/*
205 * When the currently executing URB is dequeued, save its current toggle value 284 * When a queue is stopped and a dequeued URB is given back, adjust
285 * the previous TD link (if the URB isn't first on the queue) or
286 * save its toggle value (if it is first and is currently executing).
287 *
288 * Returns 0 if the URB should not yet be given back, 1 otherwise.
206 */ 289 */
207static void uhci_save_toggle(struct uhci_qh *qh, struct urb *urb) 290static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh,
291 struct urb *urb)
208{ 292{
209 struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; 293 struct urb_priv *urbp = urb->hcpriv;
210 struct uhci_td *td; 294 struct uhci_td *td;
295 int ret = 1;
296
297 /* Isochronous pipes don't use toggles and their TD link pointers
298 * get adjusted during uhci_urb_dequeue(). But since their queues
299 * cannot truly be stopped, we have to watch out for dequeues
300 * occurring after the nominal unlink frame. */
301 if (qh->type == USB_ENDPOINT_XFER_ISOC) {
302 ret = (uhci->frame_number + uhci->is_stopped !=
303 qh->unlink_frame);
304 goto done;
305 }
306
307 /* If the URB isn't first on its queue, adjust the link pointer
308 * of the last TD in the previous URB. The toggle doesn't need
309 * to be saved since this URB can't be executing yet. */
310 if (qh->queue.next != &urbp->node) {
311 struct urb_priv *purbp;
312 struct uhci_td *ptd;
313
314 purbp = list_entry(urbp->node.prev, struct urb_priv, node);
315 WARN_ON(list_empty(&purbp->td_list));
316 ptd = list_entry(purbp->td_list.prev, struct uhci_td,
317 list);
318 td = list_entry(urbp->td_list.prev, struct uhci_td,
319 list);
320 ptd->link = td->link;
321 goto done;
322 }
211 323
212 /* If the QH element pointer is UHCI_PTR_TERM then then currently 324 /* If the QH element pointer is UHCI_PTR_TERM then then currently
213 * executing URB has already been unlinked, so this one isn't it. */ 325 * executing URB has already been unlinked, so this one isn't it. */
214 if (qh_element(qh) == UHCI_PTR_TERM || 326 if (qh_element(qh) == UHCI_PTR_TERM)
215 qh->queue.next != &urbp->node) 327 goto done;
216 return;
217 qh->element = UHCI_PTR_TERM; 328 qh->element = UHCI_PTR_TERM;
218 329
219 /* Only bulk and interrupt pipes have to worry about toggles */ 330 /* Control pipes have to worry about toggles */
220 if (!(usb_pipetype(urb->pipe) == PIPE_BULK || 331 if (qh->type == USB_ENDPOINT_XFER_CONTROL)
221 usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) 332 goto done;
222 return;
223 333
224 /* Find the first active TD; that's the device's toggle state */ 334 /* Save the next toggle value */
225 list_for_each_entry(td, &urbp->td_list, list) { 335 WARN_ON(list_empty(&urbp->td_list));
226 if (td_status(td) & TD_CTRL_ACTIVE) { 336 td = list_entry(urbp->td_list.next, struct uhci_td, list);
227 qh->needs_fixup = 1; 337 qh->needs_fixup = 1;
228 qh->initial_toggle = uhci_toggle(td_token(td)); 338 qh->initial_toggle = uhci_toggle(td_token(td));
229 return;
230 }
231 }
232 339
233 WARN_ON(1); 340done:
341 return ret;
234} 342}
235 343
236/* 344/*
@@ -305,6 +413,10 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
305 qh->element = cpu_to_le32(td->dma_handle); 413 qh->element = cpu_to_le32(td->dma_handle);
306 } 414 }
307 415
416 /* Treat the queue as if it has just advanced */
417 qh->wait_expired = 0;
418 qh->advance_jiffies = jiffies;
419
308 if (qh->state == QH_STATE_ACTIVE) 420 if (qh->state == QH_STATE_ACTIVE)
309 return; 421 return;
310 qh->state = QH_STATE_ACTIVE; 422 qh->state = QH_STATE_ACTIVE;
@@ -370,6 +482,12 @@ static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh)
370 list_move(&qh->node, &uhci->idle_qh_list); 482 list_move(&qh->node, &uhci->idle_qh_list);
371 qh->state = QH_STATE_IDLE; 483 qh->state = QH_STATE_IDLE;
372 484
485 /* Now that the QH is idle, its post_td isn't being used */
486 if (qh->post_td) {
487 uhci_free_td(uhci, qh->post_td);
488 qh->post_td = NULL;
489 }
490
373 /* If anyone is waiting for a QH to become idle, wake them up */ 491 /* If anyone is waiting for a QH to become idle, wake them up */
374 if (uhci->num_waiting) 492 if (uhci->num_waiting)
375 wake_up_all(&uhci->waitqh); 493 wake_up_all(&uhci->waitqh);
@@ -395,21 +513,6 @@ static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci,
395 return urbp; 513 return urbp;
396} 514}
397 515
398static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td)
399{
400 struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
401
402 list_add_tail(&td->list, &urbp->td_list);
403}
404
405static void uhci_remove_td_from_urb(struct uhci_td *td)
406{
407 if (list_empty(&td->list))
408 return;
409
410 list_del_init(&td->list);
411}
412
413static void uhci_free_urb_priv(struct uhci_hcd *uhci, 516static void uhci_free_urb_priv(struct uhci_hcd *uhci,
414 struct urb_priv *urbp) 517 struct urb_priv *urbp)
415{ 518{
@@ -419,48 +522,15 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci,
419 dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n", 522 dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n",
420 urbp->urb); 523 urbp->urb);
421 524
422 uhci_get_current_frame_number(uhci);
423 if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age) {
424 uhci_free_pending_tds(uhci);
425 uhci->td_remove_age = uhci->frame_number;
426 }
427
428 /* Check to see if the remove list is empty. Set the IOC bit */
429 /* to force an interrupt so we can remove the TDs. */
430 if (list_empty(&uhci->td_remove_list))
431 uhci_set_next_interrupt(uhci);
432
433 list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { 525 list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
434 uhci_remove_td_from_urb(td); 526 uhci_remove_td_from_urbp(td);
435 list_add(&td->remove_list, &uhci->td_remove_list); 527 uhci_free_td(uhci, td);
436 } 528 }
437 529
438 urbp->urb->hcpriv = NULL; 530 urbp->urb->hcpriv = NULL;
439 kmem_cache_free(uhci_up_cachep, urbp); 531 kmem_cache_free(uhci_up_cachep, urbp);
440} 532}
441 533
442static void uhci_inc_fsbr(struct uhci_hcd *uhci, struct urb *urb)
443{
444 struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
445
446 if ((!(urb->transfer_flags & URB_NO_FSBR)) && !urbp->fsbr) {
447 urbp->fsbr = 1;
448 if (!uhci->fsbr++ && !uhci->fsbrtimeout)
449 uhci->skel_term_qh->link = cpu_to_le32(uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH;
450 }
451}
452
453static void uhci_dec_fsbr(struct uhci_hcd *uhci, struct urb *urb)
454{
455 struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
456
457 if ((!(urb->transfer_flags & URB_NO_FSBR)) && urbp->fsbr) {
458 urbp->fsbr = 0;
459 if (!--uhci->fsbr)
460 uhci->fsbrtimeout = jiffies + FSBR_DELAY;
461 }
462}
463
464/* 534/*
465 * Map status to standard result codes 535 * Map status to standard result codes
466 * 536 *
@@ -487,7 +557,6 @@ static int uhci_map_status(int status, int dir_out)
487 return -ENOSR; 557 return -ENOSR;
488 if (status & TD_CTRL_STALLED) /* Stalled */ 558 if (status & TD_CTRL_STALLED) /* Stalled */
489 return -EPIPE; 559 return -EPIPE;
490 WARN_ON(status & TD_CTRL_ACTIVE); /* Active */
491 return 0; 560 return 0;
492} 561}
493 562
@@ -503,6 +572,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
503 int len = urb->transfer_buffer_length; 572 int len = urb->transfer_buffer_length;
504 dma_addr_t data = urb->transfer_dma; 573 dma_addr_t data = urb->transfer_dma;
505 __le32 *plink; 574 __le32 *plink;
575 struct urb_priv *urbp = urb->hcpriv;
506 576
507 /* The "pipe" thing contains the destination in bits 8--18 */ 577 /* The "pipe" thing contains the destination in bits 8--18 */
508 destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; 578 destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
@@ -516,7 +586,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
516 * Build the TD for the control request setup packet 586 * Build the TD for the control request setup packet
517 */ 587 */
518 td = qh->dummy_td; 588 td = qh->dummy_td;
519 uhci_add_td_to_urb(urb, td); 589 uhci_add_td_to_urbp(td, urbp);
520 uhci_fill_td(td, status, destination | uhci_explen(8), 590 uhci_fill_td(td, status, destination | uhci_explen(8),
521 urb->setup_dma); 591 urb->setup_dma);
522 plink = &td->link; 592 plink = &td->link;
@@ -548,7 +618,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
548 /* Alternate Data0/1 (start with Data1) */ 618 /* Alternate Data0/1 (start with Data1) */
549 destination ^= TD_TOKEN_TOGGLE; 619 destination ^= TD_TOKEN_TOGGLE;
550 620
551 uhci_add_td_to_urb(urb, td); 621 uhci_add_td_to_urbp(td, urbp);
552 uhci_fill_td(td, status, destination | uhci_explen(pktsze), 622 uhci_fill_td(td, status, destination | uhci_explen(pktsze),
553 data); 623 data);
554 plink = &td->link; 624 plink = &td->link;
@@ -579,7 +649,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
579 649
580 status &= ~TD_CTRL_SPD; 650 status &= ~TD_CTRL_SPD;
581 651
582 uhci_add_td_to_urb(urb, td); 652 uhci_add_td_to_urbp(td, urbp);
583 uhci_fill_td(td, status | TD_CTRL_IOC, 653 uhci_fill_td(td, status | TD_CTRL_IOC,
584 destination | uhci_explen(0), 0); 654 destination | uhci_explen(0), 0);
585 plink = &td->link; 655 plink = &td->link;
@@ -606,145 +676,19 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
606 qh->skel = uhci->skel_ls_control_qh; 676 qh->skel = uhci->skel_ls_control_qh;
607 else { 677 else {
608 qh->skel = uhci->skel_fs_control_qh; 678 qh->skel = uhci->skel_fs_control_qh;
609 uhci_inc_fsbr(uhci, urb); 679 uhci_add_fsbr(uhci, urb);
610 } 680 }
681
682 urb->actual_length = -8; /* Account for the SETUP packet */
611 return 0; 683 return 0;
612 684
613nomem: 685nomem:
614 /* Remove the dummy TD from the td_list so it doesn't get freed */ 686 /* Remove the dummy TD from the td_list so it doesn't get freed */
615 uhci_remove_td_from_urb(qh->dummy_td); 687 uhci_remove_td_from_urbp(qh->dummy_td);
616 return -ENOMEM; 688 return -ENOMEM;
617} 689}
618 690
619/* 691/*
620 * If control-IN transfer was short, the status packet wasn't sent.
621 * This routine changes the element pointer in the QH to point at the
622 * status TD. It's safe to do this even while the QH is live, because
623 * the hardware only updates the element pointer following a successful
624 * transfer. The inactive TD for the short packet won't cause an update,
625 * so the pointer won't get overwritten. The next time the controller
626 * sees this QH, it will send the status packet.
627 */
628static int usb_control_retrigger_status(struct uhci_hcd *uhci, struct urb *urb)
629{
630 struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
631 struct uhci_td *td;
632
633 urbp->short_transfer = 1;
634
635 td = list_entry(urbp->td_list.prev, struct uhci_td, list);
636 urbp->qh->element = cpu_to_le32(td->dma_handle);
637
638 return -EINPROGRESS;
639}
640
641
642static int uhci_result_control(struct uhci_hcd *uhci, struct urb *urb)
643{
644 struct list_head *tmp, *head;
645 struct urb_priv *urbp = urb->hcpriv;
646 struct uhci_td *td;
647 unsigned int status;
648 int ret = 0;
649
650 head = &urbp->td_list;
651 if (urbp->short_transfer) {
652 tmp = head->prev;
653 goto status_stage;
654 }
655
656 urb->actual_length = 0;
657
658 tmp = head->next;
659 td = list_entry(tmp, struct uhci_td, list);
660
661 /* The first TD is the SETUP stage, check the status, but skip */
662 /* the count */
663 status = uhci_status_bits(td_status(td));
664 if (status & TD_CTRL_ACTIVE)
665 return -EINPROGRESS;
666
667 if (status)
668 goto td_error;
669
670 /* The rest of the TDs (but the last) are data */
671 tmp = tmp->next;
672 while (tmp != head && tmp->next != head) {
673 unsigned int ctrlstat;
674
675 td = list_entry(tmp, struct uhci_td, list);
676 tmp = tmp->next;
677
678 ctrlstat = td_status(td);
679 status = uhci_status_bits(ctrlstat);
680 if (status & TD_CTRL_ACTIVE)
681 return -EINPROGRESS;
682
683 urb->actual_length += uhci_actual_length(ctrlstat);
684
685 if (status)
686 goto td_error;
687
688 /* Check to see if we received a short packet */
689 if (uhci_actual_length(ctrlstat) <
690 uhci_expected_length(td_token(td))) {
691 if (urb->transfer_flags & URB_SHORT_NOT_OK) {
692 ret = -EREMOTEIO;
693 goto err;
694 }
695
696 return usb_control_retrigger_status(uhci, urb);
697 }
698 }
699
700status_stage:
701 td = list_entry(tmp, struct uhci_td, list);
702
703 /* Control status stage */
704 status = td_status(td);
705
706#ifdef I_HAVE_BUGGY_APC_BACKUPS
707 /* APC BackUPS Pro kludge */
708 /* It tries to send all of the descriptor instead of the amount */
709 /* we requested */
710 if (status & TD_CTRL_IOC && /* IOC is masked out by uhci_status_bits */
711 status & TD_CTRL_ACTIVE &&
712 status & TD_CTRL_NAK)
713 return 0;
714#endif
715
716 status = uhci_status_bits(status);
717 if (status & TD_CTRL_ACTIVE)
718 return -EINPROGRESS;
719
720 if (status)
721 goto td_error;
722
723 return 0;
724
725td_error:
726 ret = uhci_map_status(status, uhci_packetout(td_token(td)));
727
728err:
729 if ((debug == 1 && ret != -EPIPE) || debug > 1) {
730 /* Some debugging code */
731 dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n",
732 __FUNCTION__, status);
733
734 if (errbuf) {
735 /* Print the chain for debugging purposes */
736 uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0);
737 lprintk(errbuf);
738 }
739 }
740
741 /* Note that the queue has stopped */
742 urbp->qh->element = UHCI_PTR_TERM;
743 urbp->qh->is_stopped = 1;
744 return ret;
745}
746
747/*
748 * Common submit for bulk and interrupt 692 * Common submit for bulk and interrupt
749 */ 693 */
750static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, 694static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
@@ -756,6 +700,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
756 int len = urb->transfer_buffer_length; 700 int len = urb->transfer_buffer_length;
757 dma_addr_t data = urb->transfer_dma; 701 dma_addr_t data = urb->transfer_dma;
758 __le32 *plink; 702 __le32 *plink;
703 struct urb_priv *urbp = urb->hcpriv;
759 unsigned int toggle; 704 unsigned int toggle;
760 705
761 if (len < 0) 706 if (len < 0)
@@ -793,7 +738,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
793 goto nomem; 738 goto nomem;
794 *plink = cpu_to_le32(td->dma_handle); 739 *plink = cpu_to_le32(td->dma_handle);
795 } 740 }
796 uhci_add_td_to_urb(urb, td); 741 uhci_add_td_to_urbp(td, urbp);
797 uhci_fill_td(td, status, 742 uhci_fill_td(td, status,
798 destination | uhci_explen(pktsze) | 743 destination | uhci_explen(pktsze) |
799 (toggle << TD_TOKEN_TOGGLE_SHIFT), 744 (toggle << TD_TOKEN_TOGGLE_SHIFT),
@@ -821,7 +766,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
821 goto nomem; 766 goto nomem;
822 *plink = cpu_to_le32(td->dma_handle); 767 *plink = cpu_to_le32(td->dma_handle);
823 768
824 uhci_add_td_to_urb(urb, td); 769 uhci_add_td_to_urbp(td, urbp);
825 uhci_fill_td(td, status, 770 uhci_fill_td(td, status,
826 destination | uhci_explen(0) | 771 destination | uhci_explen(0) |
827 (toggle << TD_TOKEN_TOGGLE_SHIFT), 772 (toggle << TD_TOKEN_TOGGLE_SHIFT),
@@ -851,6 +796,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
851 wmb(); 796 wmb();
852 qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); 797 qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
853 qh->dummy_td = td; 798 qh->dummy_td = td;
799 qh->period = urb->interval;
854 800
855 usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), 801 usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
856 usb_pipeout(urb->pipe), toggle); 802 usb_pipeout(urb->pipe), toggle);
@@ -858,90 +804,10 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
858 804
859nomem: 805nomem:
860 /* Remove the dummy TD from the td_list so it doesn't get freed */ 806 /* Remove the dummy TD from the td_list so it doesn't get freed */
861 uhci_remove_td_from_urb(qh->dummy_td); 807 uhci_remove_td_from_urbp(qh->dummy_td);
862 return -ENOMEM; 808 return -ENOMEM;
863} 809}
864 810
865/*
866 * Common result for bulk and interrupt
867 */
868static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb)
869{
870 struct urb_priv *urbp = urb->hcpriv;
871 struct uhci_td *td;
872 unsigned int status = 0;
873 int ret = 0;
874
875 urb->actual_length = 0;
876
877 list_for_each_entry(td, &urbp->td_list, list) {
878 unsigned int ctrlstat = td_status(td);
879
880 status = uhci_status_bits(ctrlstat);
881 if (status & TD_CTRL_ACTIVE)
882 return -EINPROGRESS;
883
884 urb->actual_length += uhci_actual_length(ctrlstat);
885
886 if (status)
887 goto td_error;
888
889 if (uhci_actual_length(ctrlstat) <
890 uhci_expected_length(td_token(td))) {
891 if (urb->transfer_flags & URB_SHORT_NOT_OK) {
892 ret = -EREMOTEIO;
893 goto err;
894 }
895
896 /*
897 * This URB stopped short of its end. We have to
898 * fix up the toggles of the following URBs on the
899 * queue and restart the queue.
900 *
901 * Do this only the first time we encounter the
902 * short URB.
903 */
904 if (!urbp->short_transfer) {
905 urbp->short_transfer = 1;
906 urbp->qh->initial_toggle =
907 uhci_toggle(td_token(td)) ^ 1;
908 uhci_fixup_toggles(urbp->qh, 1);
909
910 td = list_entry(urbp->td_list.prev,
911 struct uhci_td, list);
912 urbp->qh->element = td->link;
913 }
914 break;
915 }
916 }
917
918 return 0;
919
920td_error:
921 ret = uhci_map_status(status, uhci_packetout(td_token(td)));
922
923 if ((debug == 1 && ret != -EPIPE) || debug > 1) {
924 /* Some debugging code */
925 dev_dbg(uhci_dev(uhci), "%s: failed with status %x\n",
926 __FUNCTION__, status);
927
928 if (debug > 1 && errbuf) {
929 /* Print the chain for debugging purposes */
930 uhci_show_qh(urbp->qh, errbuf, ERRBUF_LEN, 0);
931 lprintk(errbuf);
932 }
933 }
934err:
935
936 /* Note that the queue has stopped and save the next toggle value */
937 urbp->qh->element = UHCI_PTR_TERM;
938 urbp->qh->is_stopped = 1;
939 urbp->qh->needs_fixup = 1;
940 urbp->qh->initial_toggle = uhci_toggle(td_token(td)) ^
941 (ret == -EREMOTEIO);
942 return ret;
943}
944
945static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, 811static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
946 struct uhci_qh *qh) 812 struct uhci_qh *qh)
947{ 813{
@@ -954,22 +820,163 @@ static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
954 qh->skel = uhci->skel_bulk_qh; 820 qh->skel = uhci->skel_bulk_qh;
955 ret = uhci_submit_common(uhci, urb, qh); 821 ret = uhci_submit_common(uhci, urb, qh);
956 if (ret == 0) 822 if (ret == 0)
957 uhci_inc_fsbr(uhci, urb); 823 uhci_add_fsbr(uhci, urb);
958 return ret; 824 return ret;
959} 825}
960 826
961static inline int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, 827static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb,
962 struct uhci_qh *qh) 828 struct uhci_qh *qh)
963{ 829{
830 int exponent;
831
964 /* USB 1.1 interrupt transfers only involve one packet per interval. 832 /* USB 1.1 interrupt transfers only involve one packet per interval.
965 * Drivers can submit URBs of any length, but longer ones will need 833 * Drivers can submit URBs of any length, but longer ones will need
966 * multiple intervals to complete. 834 * multiple intervals to complete.
967 */ 835 */
968 qh->skel = uhci->skelqh[__interval_to_skel(urb->interval)]; 836
837 /* Figure out which power-of-two queue to use */
838 for (exponent = 7; exponent >= 0; --exponent) {
839 if ((1 << exponent) <= urb->interval)
840 break;
841 }
842 if (exponent < 0)
843 return -EINVAL;
844 urb->interval = 1 << exponent;
845
846 if (qh->period == 0)
847 qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)];
848 else if (qh->period != urb->interval)
849 return -EINVAL; /* Can't change the period */
850
969 return uhci_submit_common(uhci, urb, qh); 851 return uhci_submit_common(uhci, urb, qh);
970} 852}
971 853
972/* 854/*
855 * Fix up the data structures following a short transfer
856 */
857static int uhci_fixup_short_transfer(struct uhci_hcd *uhci,
858 struct uhci_qh *qh, struct urb_priv *urbp)
859{
860 struct uhci_td *td;
861 struct list_head *tmp;
862 int ret;
863
864 td = list_entry(urbp->td_list.prev, struct uhci_td, list);
865 if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
866
867 /* When a control transfer is short, we have to restart
868 * the queue at the status stage transaction, which is
869 * the last TD. */
870 WARN_ON(list_empty(&urbp->td_list));
871 qh->element = cpu_to_le32(td->dma_handle);
872 tmp = td->list.prev;
873 ret = -EINPROGRESS;
874
875 } else {
876
877 /* When a bulk/interrupt transfer is short, we have to
878 * fix up the toggles of the following URBs on the queue
879 * before restarting the queue at the next URB. */
880 qh->initial_toggle = uhci_toggle(td_token(qh->post_td)) ^ 1;
881 uhci_fixup_toggles(qh, 1);
882
883 if (list_empty(&urbp->td_list))
884 td = qh->post_td;
885 qh->element = td->link;
886 tmp = urbp->td_list.prev;
887 ret = 0;
888 }
889
890 /* Remove all the TDs we skipped over, from tmp back to the start */
891 while (tmp != &urbp->td_list) {
892 td = list_entry(tmp, struct uhci_td, list);
893 tmp = tmp->prev;
894
895 uhci_remove_td_from_urbp(td);
896 uhci_free_td(uhci, td);
897 }
898 return ret;
899}
900
901/*
902 * Common result for control, bulk, and interrupt
903 */
904static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb)
905{
906 struct urb_priv *urbp = urb->hcpriv;
907 struct uhci_qh *qh = urbp->qh;
908 struct uhci_td *td, *tmp;
909 unsigned status;
910 int ret = 0;
911
912 list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
913 unsigned int ctrlstat;
914 int len;
915
916 ctrlstat = td_status(td);
917 status = uhci_status_bits(ctrlstat);
918 if (status & TD_CTRL_ACTIVE)
919 return -EINPROGRESS;
920
921 len = uhci_actual_length(ctrlstat);
922 urb->actual_length += len;
923
924 if (status) {
925 ret = uhci_map_status(status,
926 uhci_packetout(td_token(td)));
927 if ((debug == 1 && ret != -EPIPE) || debug > 1) {
928 /* Some debugging code */
929 dev_dbg(&urb->dev->dev,
930 "%s: failed with status %x\n",
931 __FUNCTION__, status);
932
933 if (debug > 1 && errbuf) {
934 /* Print the chain for debugging */
935 uhci_show_qh(urbp->qh, errbuf,
936 ERRBUF_LEN, 0);
937 lprintk(errbuf);
938 }
939 }
940
941 } else if (len < uhci_expected_length(td_token(td))) {
942
943 /* We received a short packet */
944 if (urb->transfer_flags & URB_SHORT_NOT_OK)
945 ret = -EREMOTEIO;
946 else if (ctrlstat & TD_CTRL_SPD)
947 ret = 1;
948 }
949
950 uhci_remove_td_from_urbp(td);
951 if (qh->post_td)
952 uhci_free_td(uhci, qh->post_td);
953 qh->post_td = td;
954
955 if (ret != 0)
956 goto err;
957 }
958 return ret;
959
960err:
961 if (ret < 0) {
962 /* In case a control transfer gets an error
963 * during the setup stage */
964 urb->actual_length = max(urb->actual_length, 0);
965
966 /* Note that the queue has stopped and save
967 * the next toggle value */
968 qh->element = UHCI_PTR_TERM;
969 qh->is_stopped = 1;
970 qh->needs_fixup = (qh->type != USB_ENDPOINT_XFER_CONTROL);
971 qh->initial_toggle = uhci_toggle(td_token(td)) ^
972 (ret == -EREMOTEIO);
973
974 } else /* Short packet received */
975 ret = uhci_fixup_short_transfer(uhci, qh, urbp);
976 return ret;
977}
978
979/*
973 * Isochronous transfers 980 * Isochronous transfers
974 */ 981 */
975static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, 982static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
@@ -980,38 +987,57 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
980 unsigned long destination, status; 987 unsigned long destination, status;
981 struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; 988 struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
982 989
983 if (urb->number_of_packets > 900) /* 900? Why? */ 990 /* Values must not be too big (could overflow below) */
991 if (urb->interval >= UHCI_NUMFRAMES ||
992 urb->number_of_packets >= UHCI_NUMFRAMES)
984 return -EFBIG; 993 return -EFBIG;
985 994
986 status = TD_CTRL_ACTIVE | TD_CTRL_IOS; 995 /* Check the period and figure out the starting frame number */
987 destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); 996 if (qh->period == 0) {
988 997 if (urb->transfer_flags & URB_ISO_ASAP) {
989 /* Figure out the starting frame number */
990 if (urb->transfer_flags & URB_ISO_ASAP) {
991 if (list_empty(&qh->queue)) {
992 uhci_get_current_frame_number(uhci); 998 uhci_get_current_frame_number(uhci);
993 urb->start_frame = (uhci->frame_number + 10); 999 urb->start_frame = uhci->frame_number + 10;
1000 } else {
1001 i = urb->start_frame - uhci->last_iso_frame;
1002 if (i <= 0 || i >= UHCI_NUMFRAMES)
1003 return -EINVAL;
1004 }
1005 } else if (qh->period != urb->interval) {
1006 return -EINVAL; /* Can't change the period */
994 1007
995 } else { /* Go right after the last one */ 1008 } else { /* Pick up where the last URB leaves off */
996 struct urb *last_urb; 1009 if (list_empty(&qh->queue)) {
1010 frame = qh->iso_frame;
1011 } else {
1012 struct urb *lurb;
997 1013
998 last_urb = list_entry(qh->queue.prev, 1014 lurb = list_entry(qh->queue.prev,
999 struct urb_priv, node)->urb; 1015 struct urb_priv, node)->urb;
1000 urb->start_frame = (last_urb->start_frame + 1016 frame = lurb->start_frame +
1001 last_urb->number_of_packets * 1017 lurb->number_of_packets *
1002 last_urb->interval); 1018 lurb->interval;
1003 } 1019 }
1004 } else { 1020 if (urb->transfer_flags & URB_ISO_ASAP)
1005 /* FIXME: Sanity check */ 1021 urb->start_frame = frame;
1022 else if (urb->start_frame != frame)
1023 return -EINVAL;
1006 } 1024 }
1007 urb->start_frame &= (UHCI_NUMFRAMES - 1); 1025
1026 /* Make sure we won't have to go too far into the future */
1027 if (uhci_frame_before_eq(uhci->last_iso_frame + UHCI_NUMFRAMES,
1028 urb->start_frame + urb->number_of_packets *
1029 urb->interval))
1030 return -EFBIG;
1031
1032 status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
1033 destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
1008 1034
1009 for (i = 0; i < urb->number_of_packets; i++) { 1035 for (i = 0; i < urb->number_of_packets; i++) {
1010 td = uhci_alloc_td(uhci); 1036 td = uhci_alloc_td(uhci);
1011 if (!td) 1037 if (!td)
1012 return -ENOMEM; 1038 return -ENOMEM;
1013 1039
1014 uhci_add_td_to_urb(urb, td); 1040 uhci_add_td_to_urbp(td, urbp);
1015 uhci_fill_td(td, status, destination | 1041 uhci_fill_td(td, status, destination |
1016 uhci_explen(urb->iso_frame_desc[i].length), 1042 uhci_explen(urb->iso_frame_desc[i].length),
1017 urb->transfer_dma + 1043 urb->transfer_dma +
@@ -1022,12 +1048,19 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
1022 td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); 1048 td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
1023 1049
1024 qh->skel = uhci->skel_iso_qh; 1050 qh->skel = uhci->skel_iso_qh;
1051 qh->period = urb->interval;
1025 1052
1026 /* Add the TDs to the frame list */ 1053 /* Add the TDs to the frame list */
1027 frame = urb->start_frame; 1054 frame = urb->start_frame;
1028 list_for_each_entry(td, &urbp->td_list, list) { 1055 list_for_each_entry(td, &urbp->td_list, list) {
1029 uhci_insert_td_in_frame_list(uhci, td, frame); 1056 uhci_insert_td_in_frame_list(uhci, td, frame);
1030 frame += urb->interval; 1057 frame += qh->period;
1058 }
1059
1060 if (list_empty(&qh->queue)) {
1061 qh->iso_packet_desc = &urb->iso_frame_desc[0];
1062 qh->iso_frame = urb->start_frame;
1063 qh->iso_status = 0;
1031 } 1064 }
1032 1065
1033 return 0; 1066 return 0;
@@ -1035,37 +1068,44 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
1035 1068
1036static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) 1069static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb)
1037{ 1070{
1038 struct uhci_td *td; 1071 struct uhci_td *td, *tmp;
1039 struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; 1072 struct urb_priv *urbp = urb->hcpriv;
1040 int status; 1073 struct uhci_qh *qh = urbp->qh;
1041 int i, ret = 0;
1042
1043 urb->actual_length = urb->error_count = 0;
1044 1074
1045 i = 0; 1075 list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
1046 list_for_each_entry(td, &urbp->td_list, list) { 1076 unsigned int ctrlstat;
1077 int status;
1047 int actlength; 1078 int actlength;
1048 unsigned int ctrlstat = td_status(td);
1049 1079
1050 if (ctrlstat & TD_CTRL_ACTIVE) 1080 if (uhci_frame_before_eq(uhci->cur_iso_frame, qh->iso_frame))
1051 return -EINPROGRESS; 1081 return -EINPROGRESS;
1052 1082
1053 actlength = uhci_actual_length(ctrlstat); 1083 uhci_remove_tds_from_frame(uhci, qh->iso_frame);
1054 urb->iso_frame_desc[i].actual_length = actlength; 1084
1055 urb->actual_length += actlength; 1085 ctrlstat = td_status(td);
1086 if (ctrlstat & TD_CTRL_ACTIVE) {
1087 status = -EXDEV; /* TD was added too late? */
1088 } else {
1089 status = uhci_map_status(uhci_status_bits(ctrlstat),
1090 usb_pipeout(urb->pipe));
1091 actlength = uhci_actual_length(ctrlstat);
1092
1093 urb->actual_length += actlength;
1094 qh->iso_packet_desc->actual_length = actlength;
1095 qh->iso_packet_desc->status = status;
1096 }
1056 1097
1057 status = uhci_map_status(uhci_status_bits(ctrlstat),
1058 usb_pipeout(urb->pipe));
1059 urb->iso_frame_desc[i].status = status;
1060 if (status) { 1098 if (status) {
1061 urb->error_count++; 1099 urb->error_count++;
1062 ret = status; 1100 qh->iso_status = status;
1063 } 1101 }
1064 1102
1065 i++; 1103 uhci_remove_td_from_urbp(td);
1104 uhci_free_td(uhci, td);
1105 qh->iso_frame += qh->period;
1106 ++qh->iso_packet_desc;
1066 } 1107 }
1067 1108 return qh->iso_status;
1068 return ret;
1069} 1109}
1070 1110
1071static int uhci_urb_enqueue(struct usb_hcd *hcd, 1111static int uhci_urb_enqueue(struct usb_hcd *hcd,
@@ -1099,14 +1139,14 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd,
1099 } 1139 }
1100 urbp->qh = qh; 1140 urbp->qh = qh;
1101 1141
1102 switch (usb_pipetype(urb->pipe)) { 1142 switch (qh->type) {
1103 case PIPE_CONTROL: 1143 case USB_ENDPOINT_XFER_CONTROL:
1104 ret = uhci_submit_control(uhci, urb, qh); 1144 ret = uhci_submit_control(uhci, urb, qh);
1105 break; 1145 break;
1106 case PIPE_BULK: 1146 case USB_ENDPOINT_XFER_BULK:
1107 ret = uhci_submit_bulk(uhci, urb, qh); 1147 ret = uhci_submit_bulk(uhci, urb, qh);
1108 break; 1148 break;
1109 case PIPE_INTERRUPT: 1149 case USB_ENDPOINT_XFER_INT:
1110 if (list_empty(&qh->queue)) { 1150 if (list_empty(&qh->queue)) {
1111 bustime = usb_check_bandwidth(urb->dev, urb); 1151 bustime = usb_check_bandwidth(urb->dev, urb);
1112 if (bustime < 0) 1152 if (bustime < 0)
@@ -1125,7 +1165,8 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd,
1125 ret = uhci_submit_interrupt(uhci, urb, qh); 1165 ret = uhci_submit_interrupt(uhci, urb, qh);
1126 } 1166 }
1127 break; 1167 break;
1128 case PIPE_ISOCHRONOUS: 1168 case USB_ENDPOINT_XFER_ISOC:
1169 urb->error_count = 0;
1129 bustime = usb_check_bandwidth(urb->dev, urb); 1170 bustime = usb_check_bandwidth(urb->dev, urb);
1130 if (bustime < 0) { 1171 if (bustime < 0) {
1131 ret = bustime; 1172 ret = bustime;
@@ -1146,9 +1187,12 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd,
1146 1187
1147 /* If the new URB is the first and only one on this QH then either 1188 /* If the new URB is the first and only one on this QH then either
1148 * the QH is new and idle or else it's unlinked and waiting to 1189 * the QH is new and idle or else it's unlinked and waiting to
1149 * become idle, so we can activate it right away. */ 1190 * become idle, so we can activate it right away. But only if the
1150 if (qh->queue.next == &urbp->node) 1191 * queue isn't stopped. */
1192 if (qh->queue.next == &urbp->node && !qh->is_stopped) {
1151 uhci_activate_qh(uhci, qh); 1193 uhci_activate_qh(uhci, qh);
1194 uhci_urbp_wants_fsbr(uhci, urbp);
1195 }
1152 goto done; 1196 goto done;
1153 1197
1154err_submit_failed: 1198err_submit_failed:
@@ -1168,16 +1212,26 @@ static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
1168 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 1212 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
1169 unsigned long flags; 1213 unsigned long flags;
1170 struct urb_priv *urbp; 1214 struct urb_priv *urbp;
1215 struct uhci_qh *qh;
1171 1216
1172 spin_lock_irqsave(&uhci->lock, flags); 1217 spin_lock_irqsave(&uhci->lock, flags);
1173 urbp = urb->hcpriv; 1218 urbp = urb->hcpriv;
1174 if (!urbp) /* URB was never linked! */ 1219 if (!urbp) /* URB was never linked! */
1175 goto done; 1220 goto done;
1221 qh = urbp->qh;
1176 1222
1177 /* Remove Isochronous TDs from the frame list ASAP */ 1223 /* Remove Isochronous TDs from the frame list ASAP */
1178 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) 1224 if (qh->type == USB_ENDPOINT_XFER_ISOC) {
1179 uhci_unlink_isochronous_tds(uhci, urb); 1225 uhci_unlink_isochronous_tds(uhci, urb);
1180 uhci_unlink_qh(uhci, urbp->qh); 1226 mb();
1227
1228 /* If the URB has already started, update the QH unlink time */
1229 uhci_get_current_frame_number(uhci);
1230 if (uhci_frame_before_eq(urb->start_frame, uhci->frame_number))
1231 qh->unlink_frame = uhci->frame_number;
1232 }
1233
1234 uhci_unlink_qh(uhci, qh);
1181 1235
1182done: 1236done:
1183 spin_unlock_irqrestore(&uhci->lock, flags); 1237 spin_unlock_irqrestore(&uhci->lock, flags);
@@ -1194,22 +1248,17 @@ __acquires(uhci->lock)
1194{ 1248{
1195 struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; 1249 struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
1196 1250
1197 /* Isochronous TDs get unlinked directly from the frame list */ 1251 /* When giving back the first URB in an Isochronous queue,
1198 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) 1252 * reinitialize the QH's iso-related members for the next URB. */
1199 uhci_unlink_isochronous_tds(uhci, urb); 1253 if (qh->type == USB_ENDPOINT_XFER_ISOC &&
1200 1254 urbp->node.prev == &qh->queue &&
1201 /* If the URB isn't first on its queue, adjust the link pointer 1255 urbp->node.next != &qh->queue) {
1202 * of the last TD in the previous URB. */ 1256 struct urb *nurb = list_entry(urbp->node.next,
1203 else if (qh->queue.next != &urbp->node) { 1257 struct urb_priv, node)->urb;
1204 struct urb_priv *purbp; 1258
1205 struct uhci_td *ptd, *ltd; 1259 qh->iso_packet_desc = &nurb->iso_frame_desc[0];
1206 1260 qh->iso_frame = nurb->start_frame;
1207 purbp = list_entry(urbp->node.prev, struct urb_priv, node); 1261 qh->iso_status = 0;
1208 ptd = list_entry(purbp->td_list.prev, struct uhci_td,
1209 list);
1210 ltd = list_entry(urbp->td_list.prev, struct uhci_td,
1211 list);
1212 ptd->link = ltd->link;
1213 } 1262 }
1214 1263
1215 /* Take the URB off the QH's queue. If the queue is now empty, 1264 /* Take the URB off the QH's queue. If the queue is now empty,
@@ -1221,16 +1270,15 @@ __acquires(uhci->lock)
1221 qh->needs_fixup = 0; 1270 qh->needs_fixup = 0;
1222 } 1271 }
1223 1272
1224 uhci_dec_fsbr(uhci, urb); /* Safe since it checks */
1225 uhci_free_urb_priv(uhci, urbp); 1273 uhci_free_urb_priv(uhci, urbp);
1226 1274
1227 switch (usb_pipetype(urb->pipe)) { 1275 switch (qh->type) {
1228 case PIPE_ISOCHRONOUS: 1276 case USB_ENDPOINT_XFER_ISOC:
1229 /* Release bandwidth for Interrupt or Isoc. transfers */ 1277 /* Release bandwidth for Interrupt or Isoc. transfers */
1230 if (urb->bandwidth) 1278 if (urb->bandwidth)
1231 usb_release_bandwidth(urb->dev, urb, 1); 1279 usb_release_bandwidth(urb->dev, urb, 1);
1232 break; 1280 break;
1233 case PIPE_INTERRUPT: 1281 case USB_ENDPOINT_XFER_INT:
1234 /* Release bandwidth for Interrupt or Isoc. transfers */ 1282 /* Release bandwidth for Interrupt or Isoc. transfers */
1235 /* Make sure we don't release if we have a queued URB */ 1283 /* Make sure we don't release if we have a queued URB */
1236 if (list_empty(&qh->queue) && urb->bandwidth) 1284 if (list_empty(&qh->queue) && urb->bandwidth)
@@ -1252,6 +1300,7 @@ __acquires(uhci->lock)
1252 uhci_unlink_qh(uhci, qh); 1300 uhci_unlink_qh(uhci, qh);
1253 1301
1254 /* Bandwidth stuff not yet implemented */ 1302 /* Bandwidth stuff not yet implemented */
1303 qh->period = 0;
1255 } 1304 }
1256} 1305}
1257 1306
@@ -1273,17 +1322,10 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh,
1273 urbp = list_entry(qh->queue.next, struct urb_priv, node); 1322 urbp = list_entry(qh->queue.next, struct urb_priv, node);
1274 urb = urbp->urb; 1323 urb = urbp->urb;
1275 1324
1276 switch (usb_pipetype(urb->pipe)) { 1325 if (qh->type == USB_ENDPOINT_XFER_ISOC)
1277 case PIPE_CONTROL:
1278 status = uhci_result_control(uhci, urb);
1279 break;
1280 case PIPE_ISOCHRONOUS:
1281 status = uhci_result_isochronous(uhci, urb); 1326 status = uhci_result_isochronous(uhci, urb);
1282 break; 1327 else
1283 default: /* PIPE_BULK or PIPE_INTERRUPT */
1284 status = uhci_result_common(uhci, urb); 1328 status = uhci_result_common(uhci, urb);
1285 break;
1286 }
1287 if (status == -EINPROGRESS) 1329 if (status == -EINPROGRESS)
1288 break; 1330 break;
1289 1331
@@ -1291,31 +1333,43 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh,
1291 if (urb->status == -EINPROGRESS) /* Not dequeued */ 1333 if (urb->status == -EINPROGRESS) /* Not dequeued */
1292 urb->status = status; 1334 urb->status = status;
1293 else 1335 else
1294 status = -ECONNRESET; 1336 status = ECONNRESET; /* Not -ECONNRESET */
1295 spin_unlock(&urb->lock); 1337 spin_unlock(&urb->lock);
1296 1338
1297 /* Dequeued but completed URBs can't be given back unless 1339 /* Dequeued but completed URBs can't be given back unless
1298 * the QH is stopped or has finished unlinking. */ 1340 * the QH is stopped or has finished unlinking. */
1299 if (status == -ECONNRESET && 1341 if (status == ECONNRESET) {
1300 !(qh->is_stopped || QH_FINISHED_UNLINKING(qh))) 1342 if (QH_FINISHED_UNLINKING(qh))
1301 return; 1343 qh->is_stopped = 1;
1344 else if (!qh->is_stopped)
1345 return;
1346 }
1302 1347
1303 uhci_giveback_urb(uhci, qh, urb, regs); 1348 uhci_giveback_urb(uhci, qh, urb, regs);
1304 if (qh->is_stopped) 1349 if (status < 0)
1305 break; 1350 break;
1306 } 1351 }
1307 1352
1308 /* If the QH is neither stopped nor finished unlinking (normal case), 1353 /* If the QH is neither stopped nor finished unlinking (normal case),
1309 * our work here is done. */ 1354 * our work here is done. */
1310 restart: 1355 if (QH_FINISHED_UNLINKING(qh))
1311 if (!(qh->is_stopped || QH_FINISHED_UNLINKING(qh))) 1356 qh->is_stopped = 1;
1357 else if (!qh->is_stopped)
1312 return; 1358 return;
1313 1359
1314 /* Otherwise give back each of the dequeued URBs */ 1360 /* Otherwise give back each of the dequeued URBs */
1361restart:
1315 list_for_each_entry(urbp, &qh->queue, node) { 1362 list_for_each_entry(urbp, &qh->queue, node) {
1316 urb = urbp->urb; 1363 urb = urbp->urb;
1317 if (urb->status != -EINPROGRESS) { 1364 if (urb->status != -EINPROGRESS) {
1318 uhci_save_toggle(qh, urb); 1365
1366 /* Fix up the TD links and save the toggles for
1367 * non-Isochronous queues. For Isochronous queues,
1368 * test for too-recent dequeues. */
1369 if (!uhci_cleanup_queue(uhci, qh, urb)) {
1370 qh->is_stopped = 0;
1371 return;
1372 }
1319 uhci_giveback_urb(uhci, qh, urb, regs); 1373 uhci_giveback_urb(uhci, qh, urb, regs);
1320 goto restart; 1374 goto restart;
1321 } 1375 }
@@ -1327,6 +1381,18 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh,
1327 if (!list_empty(&qh->queue)) { 1381 if (!list_empty(&qh->queue)) {
1328 if (qh->needs_fixup) 1382 if (qh->needs_fixup)
1329 uhci_fixup_toggles(qh, 0); 1383 uhci_fixup_toggles(qh, 0);
1384
1385 /* If the first URB on the queue wants FSBR but its time
1386 * limit has expired, set the next TD to interrupt on
1387 * completion before reactivating the QH. */
1388 urbp = list_entry(qh->queue.next, struct urb_priv, node);
1389 if (urbp->fsbr && qh->wait_expired) {
1390 struct uhci_td *td = list_entry(urbp->td_list.next,
1391 struct uhci_td, list);
1392
1393 td->status |= __cpu_to_le32(TD_CTRL_IOC);
1394 }
1395
1330 uhci_activate_qh(uhci, qh); 1396 uhci_activate_qh(uhci, qh);
1331 } 1397 }
1332 1398
@@ -1336,15 +1402,84 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh,
1336 uhci_make_qh_idle(uhci, qh); 1402 uhci_make_qh_idle(uhci, qh);
1337} 1403}
1338 1404
1339static void uhci_free_pending_tds(struct uhci_hcd *uhci) 1405/*
1406 * Check for queues that have made some forward progress.
1407 * Returns 0 if the queue is not Isochronous, is ACTIVE, and
1408 * has not advanced since last examined; 1 otherwise.
1409 *
1410 * Early Intel controllers have a bug which causes qh->element sometimes
1411 * not to advance when a TD completes successfully. The queue remains
1412 * stuck on the inactive completed TD. We detect such cases and advance
1413 * the element pointer by hand.
1414 */
1415static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh)
1340{ 1416{
1341 struct uhci_td *td, *tmp; 1417 struct urb_priv *urbp = NULL;
1418 struct uhci_td *td;
1419 int ret = 1;
1420 unsigned status;
1342 1421
1343 list_for_each_entry_safe(td, tmp, &uhci->td_remove_list, remove_list) { 1422 if (qh->type == USB_ENDPOINT_XFER_ISOC)
1344 list_del_init(&td->remove_list); 1423 goto done;
1345 1424
1346 uhci_free_td(uhci, td); 1425 /* Treat an UNLINKING queue as though it hasn't advanced.
1426 * This is okay because reactivation will treat it as though
1427 * it has advanced, and if it is going to become IDLE then
1428 * this doesn't matter anyway. Furthermore it's possible
1429 * for an UNLINKING queue not to have any URBs at all, or
1430 * for its first URB not to have any TDs (if it was dequeued
1431 * just as it completed). So it's not easy in any case to
1432 * test whether such queues have advanced. */
1433 if (qh->state != QH_STATE_ACTIVE) {
1434 urbp = NULL;
1435 status = 0;
1436
1437 } else {
1438 urbp = list_entry(qh->queue.next, struct urb_priv, node);
1439 td = list_entry(urbp->td_list.next, struct uhci_td, list);
1440 status = td_status(td);
1441 if (!(status & TD_CTRL_ACTIVE)) {
1442
1443 /* We're okay, the queue has advanced */
1444 qh->wait_expired = 0;
1445 qh->advance_jiffies = jiffies;
1446 goto done;
1447 }
1448 ret = 0;
1449 }
1450
1451 /* The queue hasn't advanced; check for timeout */
1452 if (qh->wait_expired)
1453 goto done;
1454
1455 if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) {
1456
1457 /* Detect the Intel bug and work around it */
1458 if (qh->post_td && qh_element(qh) ==
1459 cpu_to_le32(qh->post_td->dma_handle)) {
1460 qh->element = qh->post_td->link;
1461 qh->advance_jiffies = jiffies;
1462 ret = 1;
1463 goto done;
1464 }
1465
1466 qh->wait_expired = 1;
1467
1468 /* If the current URB wants FSBR, unlink it temporarily
1469 * so that we can safely set the next TD to interrupt on
1470 * completion. That way we'll know as soon as the queue
1471 * starts moving again. */
1472 if (urbp && urbp->fsbr && !(status & TD_CTRL_IOC))
1473 uhci_unlink_qh(uhci, qh);
1474
1475 } else {
1476 /* Unmoving but not-yet-expired queues keep FSBR alive */
1477 if (urbp)
1478 uhci_urbp_wants_fsbr(uhci, urbp);
1347 } 1479 }
1480
1481done:
1482 return ret;
1348} 1483}
1349 1484
1350/* 1485/*
@@ -1361,14 +1496,13 @@ static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs)
1361 return; 1496 return;
1362 } 1497 }
1363 uhci->scan_in_progress = 1; 1498 uhci->scan_in_progress = 1;
1364 rescan: 1499rescan:
1365 uhci->need_rescan = 0; 1500 uhci->need_rescan = 0;
1501 uhci->fsbr_is_wanted = 0;
1366 1502
1367 uhci_clear_next_interrupt(uhci); 1503 uhci_clear_next_interrupt(uhci);
1368 uhci_get_current_frame_number(uhci); 1504 uhci_get_current_frame_number(uhci);
1369 1505 uhci->cur_iso_frame = uhci->frame_number;
1370 if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age)
1371 uhci_free_pending_tds(uhci);
1372 1506
1373 /* Go through all the QH queues and process the URBs in each one */ 1507 /* Go through all the QH queues and process the URBs in each one */
1374 for (i = 0; i < UHCI_NUM_SKELQH - 1; ++i) { 1508 for (i = 0; i < UHCI_NUM_SKELQH - 1; ++i) {
@@ -1377,33 +1511,30 @@ static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs)
1377 while ((qh = uhci->next_qh) != uhci->skelqh[i]) { 1511 while ((qh = uhci->next_qh) != uhci->skelqh[i]) {
1378 uhci->next_qh = list_entry(qh->node.next, 1512 uhci->next_qh = list_entry(qh->node.next,
1379 struct uhci_qh, node); 1513 struct uhci_qh, node);
1380 uhci_scan_qh(uhci, qh, regs); 1514
1515 if (uhci_advance_check(uhci, qh)) {
1516 uhci_scan_qh(uhci, qh, regs);
1517 if (qh->state == QH_STATE_ACTIVE) {
1518 uhci_urbp_wants_fsbr(uhci,
1519 list_entry(qh->queue.next, struct urb_priv, node));
1520 }
1521 }
1381 } 1522 }
1382 } 1523 }
1383 1524
1525 uhci->last_iso_frame = uhci->cur_iso_frame;
1384 if (uhci->need_rescan) 1526 if (uhci->need_rescan)
1385 goto rescan; 1527 goto rescan;
1386 uhci->scan_in_progress = 0; 1528 uhci->scan_in_progress = 0;
1387 1529
1388 /* If the controller is stopped, we can finish these off right now */ 1530 if (uhci->fsbr_is_on && !uhci->fsbr_is_wanted &&
1389 if (uhci->is_stopped) 1531 !uhci->fsbr_expiring) {
1390 uhci_free_pending_tds(uhci); 1532 uhci->fsbr_expiring = 1;
1533 mod_timer(&uhci->fsbr_timer, jiffies + FSBR_OFF_DELAY);
1534 }
1391 1535
1392 if (list_empty(&uhci->td_remove_list) && 1536 if (list_empty(&uhci->skel_unlink_qh->node))
1393 list_empty(&uhci->skel_unlink_qh->node))
1394 uhci_clear_next_interrupt(uhci); 1537 uhci_clear_next_interrupt(uhci);
1395 else 1538 else
1396 uhci_set_next_interrupt(uhci); 1539 uhci_set_next_interrupt(uhci);
1397} 1540}
1398
1399static void check_fsbr(struct uhci_hcd *uhci)
1400{
1401 /* For now, don't scan URBs for FSBR timeouts.
1402 * Add it back in later... */
1403
1404 /* Really disable FSBR */
1405 if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) {
1406 uhci->fsbrtimeout = 0;
1407 uhci->skel_term_qh->link = UHCI_PTR_TERM;
1408 }
1409}
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c
index df29b8078b54..18c10e150ef3 100644
--- a/drivers/usb/input/acecad.c
+++ b/drivers/usb/input/acecad.c
@@ -27,11 +27,9 @@
27 27
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/input.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/init.h> 31#include <linux/init.h>
33#include <linux/usb.h> 32#include <linux/usb/input.h>
34#include <linux/usb_input.h>
35 33
36/* 34/*
37 * Version Information 35 * Version Information
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
index a6693b0d1c4c..b138dae2b055 100644
--- a/drivers/usb/input/aiptek.c
+++ b/drivers/usb/input/aiptek.c
@@ -73,11 +73,9 @@
73#include <linux/jiffies.h> 73#include <linux/jiffies.h>
74#include <linux/kernel.h> 74#include <linux/kernel.h>
75#include <linux/slab.h> 75#include <linux/slab.h>
76#include <linux/input.h>
77#include <linux/module.h> 76#include <linux/module.h>
78#include <linux/init.h> 77#include <linux/init.h>
79#include <linux/usb.h> 78#include <linux/usb/input.h>
80#include <linux/usb_input.h>
81#include <linux/sched.h> 79#include <linux/sched.h>
82#include <asm/uaccess.h> 80#include <asm/uaccess.h>
83#include <asm/unaligned.h> 81#include <asm/unaligned.h>
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c
index c222ed13deab..36855062eacc 100644
--- a/drivers/usb/input/appletouch.c
+++ b/drivers/usb/input/appletouch.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Apple USB Touchpad (for post-February 2005 PowerBooks) driver 2 * Apple USB Touchpad (for post-February 2005 PowerBooks and MacBooks) driver
3 * 3 *
4 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) 4 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
5 * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net) 5 * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net)
@@ -7,6 +7,7 @@
7 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) 7 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
8 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) 8 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
9 * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch) 9 * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch)
10 * Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch)
10 * 11 *
11 * Thanks to Alex Harper <basilisk@foobox.net> for his inputs. 12 * Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
12 * 13 *
@@ -32,9 +33,7 @@
32#include <linux/init.h> 33#include <linux/init.h>
33#include <linux/slab.h> 34#include <linux/slab.h>
34#include <linux/module.h> 35#include <linux/module.h>
35#include <linux/usb.h> 36#include <linux/usb/input.h>
36#include <linux/input.h>
37#include <linux/usb_input.h>
38 37
39/* Apple has powerbooks which have the keyboard with different Product IDs */ 38/* Apple has powerbooks which have the keyboard with different Product IDs */
40#define APPLE_VENDOR_ID 0x05AC 39#define APPLE_VENDOR_ID 0x05AC
@@ -44,6 +43,11 @@
44#define GEYSER_ISO_PRODUCT_ID 0x0215 43#define GEYSER_ISO_PRODUCT_ID 0x0215
45#define GEYSER_JIS_PRODUCT_ID 0x0216 44#define GEYSER_JIS_PRODUCT_ID 0x0216
46 45
46/* MacBook devices */
47#define GEYSER3_ANSI_PRODUCT_ID 0x0217
48#define GEYSER3_ISO_PRODUCT_ID 0x0218
49#define GEYSER3_JIS_PRODUCT_ID 0x0219
50
47#define ATP_DEVICE(prod) \ 51#define ATP_DEVICE(prod) \
48 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ 52 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
49 USB_DEVICE_ID_MATCH_INT_CLASS | \ 53 USB_DEVICE_ID_MATCH_INT_CLASS | \
@@ -65,6 +69,10 @@ static struct usb_device_id atp_table [] = {
65 { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) }, 69 { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) },
66 { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) }, 70 { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) },
67 71
72 { ATP_DEVICE(GEYSER3_ANSI_PRODUCT_ID) },
73 { ATP_DEVICE(GEYSER3_ISO_PRODUCT_ID) },
74 { ATP_DEVICE(GEYSER3_JIS_PRODUCT_ID) },
75
68 /* Terminating entry */ 76 /* Terminating entry */
69 { } 77 { }
70}; 78};
@@ -101,6 +109,13 @@ MODULE_DEVICE_TABLE (usb, atp_table);
101 */ 109 */
102#define ATP_THRESHOLD 5 110#define ATP_THRESHOLD 5
103 111
112/* MacBook Pro (Geyser 3) initialization constants */
113#define ATP_GEYSER3_MODE_READ_REQUEST_ID 1
114#define ATP_GEYSER3_MODE_WRITE_REQUEST_ID 9
115#define ATP_GEYSER3_MODE_REQUEST_VALUE 0x300
116#define ATP_GEYSER3_MODE_REQUEST_INDEX 0
117#define ATP_GEYSER3_MODE_VENDOR_VALUE 0x04
118
104/* Structure to hold all of our device specific stuff */ 119/* Structure to hold all of our device specific stuff */
105struct atp { 120struct atp {
106 char phys[64]; 121 char phys[64];
@@ -147,13 +162,22 @@ MODULE_PARM_DESC(debug, "Activate debugging output");
147/* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */ 162/* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */
148static inline int atp_is_geyser_2(struct atp *dev) 163static inline int atp_is_geyser_2(struct atp *dev)
149{ 164{
150 int16_t productId = le16_to_cpu(dev->udev->descriptor.idProduct); 165 u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
151 166
152 return (productId == GEYSER_ANSI_PRODUCT_ID) || 167 return (productId == GEYSER_ANSI_PRODUCT_ID) ||
153 (productId == GEYSER_ISO_PRODUCT_ID) || 168 (productId == GEYSER_ISO_PRODUCT_ID) ||
154 (productId == GEYSER_JIS_PRODUCT_ID); 169 (productId == GEYSER_JIS_PRODUCT_ID);
155} 170}
156 171
172static inline int atp_is_geyser_3(struct atp *dev)
173{
174 u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
175
176 return (productId == GEYSER3_ANSI_PRODUCT_ID) ||
177 (productId == GEYSER3_ISO_PRODUCT_ID) ||
178 (productId == GEYSER3_JIS_PRODUCT_ID);
179}
180
157static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, 181static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
158 int *z, int *fingers) 182 int *z, int *fingers)
159{ 183{
@@ -219,12 +243,33 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
219 243
220 /* drop incomplete datasets */ 244 /* drop incomplete datasets */
221 if (dev->urb->actual_length != dev->datalen) { 245 if (dev->urb->actual_length != dev->datalen) {
222 dprintk("appletouch: incomplete data package.\n"); 246 dprintk("appletouch: incomplete data package"
247 " (first byte: %d, length: %d).\n",
248 dev->data[0], dev->urb->actual_length);
223 goto exit; 249 goto exit;
224 } 250 }
225 251
226 /* reorder the sensors values */ 252 /* reorder the sensors values */
227 if (atp_is_geyser_2(dev)) { 253 if (atp_is_geyser_3(dev)) {
254 memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
255
256 /*
257 * The values are laid out like this:
258 * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ...
259 * '-' is an unused value.
260 */
261
262 /* read X values */
263 for (i = 0, j = 19; i < 20; i += 2, j += 3) {
264 dev->xy_cur[i] = dev->data[j + 1];
265 dev->xy_cur[i + 1] = dev->data[j + 2];
266 }
267 /* read Y values */
268 for (i = 0, j = 1; i < 9; i += 2, j += 3) {
269 dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
270 dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
271 }
272 } else if (atp_is_geyser_2(dev)) {
228 memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); 273 memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
229 274
230 /* 275 /*
@@ -267,6 +312,9 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
267 dev->x_old = dev->y_old = -1; 312 dev->x_old = dev->y_old = -1;
268 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); 313 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
269 314
315 if (atp_is_geyser_3(dev)) /* No 17" Macbooks (yet) */
316 goto exit;
317
270 /* 17" Powerbooks have extra X sensors */ 318 /* 17" Powerbooks have extra X sensors */
271 for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) { 319 for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) {
272 if (!dev->xy_cur[i]) continue; 320 if (!dev->xy_cur[i]) continue;
@@ -414,7 +462,50 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
414 dev->udev = udev; 462 dev->udev = udev;
415 dev->input = input_dev; 463 dev->input = input_dev;
416 dev->overflowwarn = 0; 464 dev->overflowwarn = 0;
417 dev->datalen = (atp_is_geyser_2(dev)?64:81); 465 if (atp_is_geyser_3(dev))
466 dev->datalen = 64;
467 else if (atp_is_geyser_2(dev))
468 dev->datalen = 64;
469 else
470 dev->datalen = 81;
471
472 if (atp_is_geyser_3(dev)) {
473 /*
474 * By default Geyser 3 device sends standard USB HID mouse
475 * packets (Report ID 2). This code changes device mode, so it
476 * sends raw sensor reports (Report ID 5).
477 */
478 char data[8];
479 int size;
480
481 size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
482 ATP_GEYSER3_MODE_READ_REQUEST_ID,
483 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
484 ATP_GEYSER3_MODE_REQUEST_VALUE,
485 ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);
486
487 if (size != 8) {
488 err("Could not do mode read request from device"
489 " (Geyser 3 mode)");
490 goto err_free_devs;
491 }
492
493 /* Apply the mode switch */
494 data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE;
495
496 size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
497 ATP_GEYSER3_MODE_WRITE_REQUEST_ID,
498 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
499 ATP_GEYSER3_MODE_REQUEST_VALUE,
500 ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);
501
502 if (size != 8) {
503 err("Could not do mode write request to device"
504 " (Geyser 3 mode)");
505 goto err_free_devs;
506 }
507 printk("appletouch Geyser 3 inited.\n");
508 }
418 509
419 dev->urb = usb_alloc_urb(0, GFP_KERNEL); 510 dev->urb = usb_alloc_urb(0, GFP_KERNEL);
420 if (!dev->urb) { 511 if (!dev->urb) {
@@ -447,7 +538,15 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
447 538
448 set_bit(EV_ABS, input_dev->evbit); 539 set_bit(EV_ABS, input_dev->evbit);
449 540
450 if (atp_is_geyser_2(dev)) { 541 if (atp_is_geyser_3(dev)) {
542 /*
543 * MacBook have 20 X sensors, 10 Y sensors
544 */
545 input_set_abs_params(input_dev, ABS_X, 0,
546 ((20 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0);
547 input_set_abs_params(input_dev, ABS_Y, 0,
548 ((10 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
549 } else if (atp_is_geyser_2(dev)) {
451 /* 550 /*
452 * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected 551 * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected
453 * later. 552 * later.
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
index 99f986cb6e95..07c8c0e665dd 100644
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/usb/input/ati_remote.c
@@ -92,9 +92,7 @@
92#include <linux/slab.h> 92#include <linux/slab.h>
93#include <linux/module.h> 93#include <linux/module.h>
94#include <linux/moduleparam.h> 94#include <linux/moduleparam.h>
95#include <linux/input.h> 95#include <linux/usb/input.h>
96#include <linux/usb.h>
97#include <linux/usb_input.h>
98#include <linux/wait.h> 96#include <linux/wait.h>
99#include <linux/jiffies.h> 97#include <linux/jiffies.h>
100 98
diff --git a/drivers/usb/input/ati_remote2.c b/drivers/usb/input/ati_remote2.c
index ab1a1ae24be9..ea71de81ca6b 100644
--- a/drivers/usb/input/ati_remote2.c
+++ b/drivers/usb/input/ati_remote2.c
@@ -8,7 +8,7 @@
8 * as published by the Free Software Foundation. 8 * as published by the Free Software Foundation.
9 */ 9 */
10 10
11#include <linux/usb_input.h> 11#include <linux/usb/input.h>
12 12
13#define DRIVER_DESC "ATI/Philips USB RF remote driver" 13#define DRIVER_DESC "ATI/Philips USB RF remote driver"
14#define DRIVER_VERSION "0.1" 14#define DRIVER_VERSION "0.1"
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 435273e7c85c..b9fb9687f926 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -944,21 +944,28 @@ static void hid_reset(void *_hid)
944 dev_dbg(&hid->intf->dev, "resetting device\n"); 944 dev_dbg(&hid->intf->dev, "resetting device\n");
945 rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf); 945 rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf);
946 if (rc_lock >= 0) { 946 if (rc_lock >= 0) {
947 rc = usb_reset_device(hid->dev); 947 rc = usb_reset_composite_device(hid->dev, hid->intf);
948 if (rc_lock) 948 if (rc_lock)
949 usb_unlock_device(hid->dev); 949 usb_unlock_device(hid->dev);
950 } 950 }
951 clear_bit(HID_RESET_PENDING, &hid->iofl); 951 clear_bit(HID_RESET_PENDING, &hid->iofl);
952 952
953 if (rc == 0) { 953 switch (rc) {
954 hid->retry_delay = 0; 954 case 0:
955 if (hid_start_in(hid)) 955 if (!test_bit(HID_IN_RUNNING, &hid->iofl))
956 hid_io_error(hid); 956 hid_io_error(hid);
957 } else if (!(rc == -ENODEV || rc == -EHOSTUNREACH || rc == -EINTR)) 957 break;
958 default:
958 err("can't reset device, %s-%s/input%d, status %d", 959 err("can't reset device, %s-%s/input%d, status %d",
959 hid->dev->bus->bus_name, 960 hid->dev->bus->bus_name,
960 hid->dev->devpath, 961 hid->dev->devpath,
961 hid->ifnum, rc); 962 hid->ifnum, rc);
963 /* FALLTHROUGH */
964 case -EHOSTUNREACH:
965 case -ENODEV:
966 case -EINTR:
967 break;
968 }
962} 969}
963 970
964/* Main I/O error handler */ 971/* Main I/O error handler */
@@ -1374,9 +1381,6 @@ void hid_close(struct hid_device *hid)
1374 1381
1375#define USB_VENDOR_ID_PANJIT 0x134c 1382#define USB_VENDOR_ID_PANJIT 0x134c
1376 1383
1377#define USB_VENDOR_ID_SILVERCREST 0x062a
1378#define USB_DEVICE_ID_SILVERCREST_KB 0x0201
1379
1380/* 1384/*
1381 * Initialize all reports 1385 * Initialize all reports
1382 */ 1386 */
@@ -1461,9 +1465,6 @@ void hid_init_reports(struct hid_device *hid)
1461#define USB_VENDOR_ID_ONTRAK 0x0a07 1465#define USB_VENDOR_ID_ONTRAK 0x0a07
1462#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 1466#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
1463 1467
1464#define USB_VENDOR_ID_TANGTOP 0x0d3d
1465#define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001
1466
1467#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f 1468#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
1468#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 1469#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
1469 1470
@@ -1520,12 +1521,6 @@ void hid_init_reports(struct hid_device *hid)
1520#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 1521#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076
1521#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a 1522#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a
1522 1523
1523#define USB_VENDOR_ID_CHICONY 0x04f2
1524#define USB_DEVICE_ID_CHICONY_USBHUB_KB 0x0100
1525
1526#define USB_VENDOR_ID_BTC 0x046e
1527#define USB_DEVICE_ID_BTC_KEYBOARD 0x5303
1528
1529#define USB_VENDOR_ID_VERNIER 0x08f7 1524#define USB_VENDOR_ID_VERNIER 0x08f7
1530#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 1525#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
1531#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 1526#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
@@ -1549,20 +1544,13 @@ void hid_init_reports(struct hid_device *hid)
1549#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 1544#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
1550 1545
1551#define USB_VENDOR_ID_APPLE 0x05ac 1546#define USB_VENDOR_ID_APPLE 0x05ac
1552#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 1547#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
1553 1548
1554#define USB_VENDOR_ID_CHERRY 0x046a 1549#define USB_VENDOR_ID_CHERRY 0x046a
1555#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 1550#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
1556 1551
1557#define USB_VENDOR_ID_HP 0x03f0 1552#define USB_VENDOR_ID_YEALINK 0x6993
1558#define USB_DEVICE_ID_HP_USBHUB_KB 0x020c 1553#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001
1559
1560#define USB_VENDOR_ID_IBM 0x04b3
1561#define USB_DEVICE_ID_IBM_USBHUB_KB 0x3005
1562
1563#define USB_VENDOR_ID_CREATIVELABS 0x062a
1564#define USB_DEVICE_ID_CREATIVELABS_SILVERCREST 0x0201
1565
1566/* 1554/*
1567 * Alphabetically sorted blacklist by quirk type. 1555 * Alphabetically sorted blacklist by quirk type.
1568 */ 1556 */
@@ -1671,6 +1659,7 @@ static const struct hid_blacklist {
1671 { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF + 3, HID_QUIRK_IGNORE }, 1659 { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF + 3, HID_QUIRK_IGNORE },
1672 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, 1660 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
1673 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, 1661 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
1662 { USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K, HID_QUIRK_IGNORE },
1674 1663
1675 { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, 1664 { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE },
1676 { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, 1665 { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE },
@@ -1680,16 +1669,9 @@ static const struct hid_blacklist {
1680 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, 1669 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
1681 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, 1670 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
1682 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, 1671 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
1683 { USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET},
1684 { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET},
1685 { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVELABS_SILVERCREST, HID_QUIRK_NOGET },
1686 { USB_VENDOR_ID_HP, USB_DEVICE_ID_HP_USBHUB_KB, HID_QUIRK_NOGET },
1687 { USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_USBHUB_KB, HID_QUIRK_NOGET },
1688 { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
1689 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 1672 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
1690 { USB_VENDOR_ID_SILVERCREST, USB_DEVICE_ID_SILVERCREST_KB, HID_QUIRK_NOGET },
1691 1673
1692 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE }, 1674 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
1693 { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, 1675 { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 },
1694 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, 1676 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 },
1695 1677
@@ -1711,6 +1693,9 @@ static const struct hid_blacklist {
1711 { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN }, 1693 { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN },
1712 { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN }, 1694 { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN },
1713 { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN }, 1695 { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN },
1696 { USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN },
1697 { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN },
1698 { USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN },
1714 { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, 1699 { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
1715 { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, 1700 { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },
1716 1701
@@ -1794,6 +1779,14 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1794 (hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct))) 1779 (hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct)))
1795 quirks = hid_blacklist[n].quirks; 1780 quirks = hid_blacklist[n].quirks;
1796 1781
1782 /* Many keyboards and mice don't like to be polled for reports,
1783 * so we will always set the HID_QUIRK_NOGET flag for them. */
1784 if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
1785 if (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_KEYBOARD ||
1786 interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE)
1787 quirks |= HID_QUIRK_NOGET;
1788 }
1789
1797 if (quirks & HID_QUIRK_IGNORE) 1790 if (quirks & HID_QUIRK_IGNORE)
1798 return NULL; 1791 return NULL;
1799 1792
@@ -2080,11 +2073,29 @@ static int hid_resume(struct usb_interface *intf)
2080 int status; 2073 int status;
2081 2074
2082 clear_bit(HID_SUSPENDED, &hid->iofl); 2075 clear_bit(HID_SUSPENDED, &hid->iofl);
2076 hid->retry_delay = 0;
2083 status = hid_start_in(hid); 2077 status = hid_start_in(hid);
2084 dev_dbg(&intf->dev, "resume status %d\n", status); 2078 dev_dbg(&intf->dev, "resume status %d\n", status);
2085 return status; 2079 return status;
2086} 2080}
2087 2081
2082/* Treat USB reset pretty much the same as suspend/resume */
2083static void hid_pre_reset(struct usb_interface *intf)
2084{
2085 /* FIXME: What if the interface is already suspended? */
2086 hid_suspend(intf, PMSG_ON);
2087}
2088
2089static void hid_post_reset(struct usb_interface *intf)
2090{
2091 struct usb_device *dev = interface_to_usbdev (intf);
2092
2093 hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
2094 /* FIXME: Any more reinitialization needed? */
2095
2096 hid_resume(intf);
2097}
2098
2088static struct usb_device_id hid_usb_ids [] = { 2099static struct usb_device_id hid_usb_ids [] = {
2089 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, 2100 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
2090 .bInterfaceClass = USB_INTERFACE_CLASS_HID }, 2101 .bInterfaceClass = USB_INTERFACE_CLASS_HID },
@@ -2099,6 +2110,8 @@ static struct usb_driver hid_driver = {
2099 .disconnect = hid_disconnect, 2110 .disconnect = hid_disconnect,
2100 .suspend = hid_suspend, 2111 .suspend = hid_suspend,
2101 .resume = hid_resume, 2112 .resume = hid_resume,
2113 .pre_reset = hid_pre_reset,
2114 .post_reset = hid_post_reset,
2102 .id_table = hid_usb_ids, 2115 .id_table = hid_usb_ids,
2103}; 2116};
2104 2117
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 25bc85f8ce39..028e1ad89f5d 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -29,9 +29,7 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/input.h> 32#include <linux/usb/input.h>
33#include <linux/usb.h>
34#include <linux/usb_input.h>
35 33
36#undef DEBUG 34#undef DEBUG
37 35
@@ -567,16 +565,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
567 break; 565 break;
568 } 566 }
569 567
570 set_bit(usage->type, input->evbit); 568 if (device->quirks & HID_QUIRK_MIGHTYMOUSE) {
571 569 if (usage->hid == HID_GD_Z)
572 while (usage->code <= max && test_and_set_bit(usage->code, bit)) 570 map_rel(REL_HWHEEL);
573 usage->code = find_next_zero_bit(bit, max + 1, usage->code); 571 else if (usage->code == BTN_1)
574 572 map_key(BTN_2);
575 if (usage->code > max) 573 else if (usage->code == BTN_2)
576 goto ignore; 574 map_key(BTN_1);
577 575 }
578 if (((device->quirks & (HID_QUIRK_2WHEEL_POWERMOUSE)) && (usage->hid == 0x00010032)))
579 map_rel(REL_HWHEEL);
580 576
581 if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && 577 if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) &&
582 (usage->type == EV_REL) && (usage->code == REL_WHEEL)) 578 (usage->type == EV_REL) && (usage->code == REL_WHEEL))
@@ -586,6 +582,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
586 || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) 582 || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007)))
587 goto ignore; 583 goto ignore;
588 584
585 set_bit(usage->type, input->evbit);
586
587 while (usage->code <= max && test_and_set_bit(usage->code, bit))
588 usage->code = find_next_zero_bit(bit, max + 1, usage->code);
589
590 if (usage->code > max)
591 goto ignore;
592
593
589 if (usage->type == EV_ABS) { 594 if (usage->type == EV_ABS) {
590 595
591 int a = field->logical_minimum; 596 int a = field->logical_minimum;
@@ -647,6 +652,11 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
647 return; 652 return;
648 } 653 }
649 654
655 if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) {
656 input_event(input, usage->type, usage->code, -value);
657 return;
658 }
659
650 if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { 660 if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) {
651 input_event(input, usage->type, REL_HWHEEL, value); 661 input_event(input, usage->type, REL_HWHEEL, value);
652 return; 662 return;
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
index 9c62837b5b89..778e575de352 100644
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -41,6 +41,14 @@
41#define USB_INTERFACE_CLASS_HID 3 41#define USB_INTERFACE_CLASS_HID 3
42 42
43/* 43/*
44 * USB HID interface subclass and protocol codes
45 */
46
47#define USB_INTERFACE_SUBCLASS_BOOT 1
48#define USB_INTERFACE_PROTOCOL_KEYBOARD 1
49#define USB_INTERFACE_PROTOCOL_MOUSE 2
50
51/*
44 * HID class requests 52 * HID class requests
45 */ 53 */
46 54
@@ -247,10 +255,11 @@ struct hid_item {
247#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080 255#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080
248#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100 256#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100
249#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 257#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200
250#define HID_QUIRK_2WHEEL_POWERMOUSE 0x00000400 258#define HID_QUIRK_MIGHTYMOUSE 0x00000400
251#define HID_QUIRK_CYMOTION 0x00000800 259#define HID_QUIRK_CYMOTION 0x00000800
252#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000 260#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000
253#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 261#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000
262#define HID_QUIRK_INVERT_HWHEEL 0x00004000
254 263
255/* 264/*
256 * This is the global environment of the parser. This information is 265 * This is the global environment of the parser. This information is
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c
index 7618ae5c104f..5c570cc703f3 100644
--- a/drivers/usb/input/itmtouch.c
+++ b/drivers/usb/input/itmtouch.c
@@ -42,11 +42,9 @@
42#include <linux/config.h> 42#include <linux/config.h>
43#include <linux/kernel.h> 43#include <linux/kernel.h>
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/input.h>
46#include <linux/module.h> 45#include <linux/module.h>
47#include <linux/init.h> 46#include <linux/init.h>
48#include <linux/usb.h> 47#include <linux/usb/input.h>
49#include <linux/usb_input.h>
50 48
51/* only an 8 byte buffer necessary for a single packet */ 49/* only an 8 byte buffer necessary for a single packet */
52#define ITM_BUFSIZE 8 50#define ITM_BUFSIZE 8
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
index f6d5cead542b..604ade356ead 100644
--- a/drivers/usb/input/kbtab.c
+++ b/drivers/usb/input/kbtab.c
@@ -1,12 +1,9 @@
1#include <linux/kernel.h> 1#include <linux/kernel.h>
2#include <linux/slab.h> 2#include <linux/slab.h>
3#include <linux/input.h>
4#include <linux/module.h> 3#include <linux/module.h>
5#include <linux/init.h> 4#include <linux/init.h>
6#include <linux/usb.h> 5#include <linux/usb/input.h>
7#include <linux/usb_input.h>
8#include <asm/unaligned.h> 6#include <asm/unaligned.h>
9#include <asm/byteorder.h>
10 7
11/* 8/*
12 * Version Information 9 * Version Information
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
index 3d911976f378..70af985b5db9 100644
--- a/drivers/usb/input/keyspan_remote.c
+++ b/drivers/usb/input/keyspan_remote.c
@@ -18,9 +18,7 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
21#include <linux/input.h> 21#include <linux/usb/input.h>
22#include <linux/usb.h>
23#include <linux/usb_input.h>
24 22
25#define DRIVER_VERSION "v0.1" 23#define DRIVER_VERSION "v0.1"
26#define DRIVER_AUTHOR "Michael Downey <downey@zymeta.com>" 24#define DRIVER_AUTHOR "Michael Downey <downey@zymeta.com>"
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
index f018953a5485..4fdee4db0729 100644
--- a/drivers/usb/input/mtouchusb.c
+++ b/drivers/usb/input/mtouchusb.c
@@ -42,11 +42,9 @@
42#include <linux/config.h> 42#include <linux/config.h>
43#include <linux/kernel.h> 43#include <linux/kernel.h>
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/input.h>
46#include <linux/module.h> 45#include <linux/module.h>
47#include <linux/init.h> 46#include <linux/init.h>
48#include <linux/usb.h> 47#include <linux/usb/input.h>
49#include <linux/usb_input.h>
50 48
51#define MTOUCHUSB_MIN_XC 0x0 49#define MTOUCHUSB_MIN_XC 0x0
52#define MTOUCHUSB_MAX_RAW_XC 0x4000 50#define MTOUCHUSB_MAX_RAW_XC 0x4000
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
index fdf0f788062c..b3c0d0c3eae9 100644
--- a/drivers/usb/input/powermate.c
+++ b/drivers/usb/input/powermate.c
@@ -30,12 +30,10 @@
30 30
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/input.h>
34#include <linux/module.h> 33#include <linux/module.h>
35#include <linux/init.h> 34#include <linux/init.h>
36#include <linux/spinlock.h> 35#include <linux/spinlock.h>
37#include <linux/usb.h> 36#include <linux/usb/input.h>
38#include <linux/usb_input.h>
39 37
40#define POWERMATE_VENDOR 0x077d /* Griffin Technology, Inc. */ 38#define POWERMATE_VENDOR 0x077d /* Griffin Technology, Inc. */
41#define POWERMATE_PRODUCT_NEW 0x0410 /* Griffin PowerMate */ 39#define POWERMATE_PRODUCT_NEW 0x0410 /* Griffin PowerMate */
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
index 697c5e573a11..da7b0bf51aff 100644
--- a/drivers/usb/input/touchkitusb.c
+++ b/drivers/usb/input/touchkitusb.c
@@ -27,11 +27,9 @@
27#include <linux/config.h> 27#include <linux/config.h>
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/input.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/init.h> 31#include <linux/init.h>
33#include <linux/usb.h> 32#include <linux/usb/input.h>
34#include <linux/usb_input.h>
35 33
36#define TOUCHKIT_MIN_XC 0x0 34#define TOUCHKIT_MIN_XC 0x0
37#define TOUCHKIT_MAX_XC 0x07ff 35#define TOUCHKIT_MAX_XC 0x07ff
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
index 2f3edc26cb50..5067a6ae650f 100644
--- a/drivers/usb/input/usbkbd.c
+++ b/drivers/usb/input/usbkbd.c
@@ -29,10 +29,8 @@
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/input.h>
33#include <linux/init.h> 32#include <linux/init.h>
34#include <linux/usb.h> 33#include <linux/usb/input.h>
35#include <linux/usb_input.h>
36 34
37/* 35/*
38 * Version Information 36 * Version Information
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
index af526135d210..446935b671d9 100644
--- a/drivers/usb/input/usbmouse.c
+++ b/drivers/usb/input/usbmouse.c
@@ -28,11 +28,9 @@
28 28
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/input.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/init.h> 32#include <linux/init.h>
34#include <linux/usb.h> 33#include <linux/usb/input.h>
35#include <linux/usb_input.h>
36 34
37/* 35/*
38 * Version Information 36 * Version Information
diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c
index e9a07c1e905b..3b175aa482cd 100644
--- a/drivers/usb/input/usbtouchscreen.c
+++ b/drivers/usb/input/usbtouchscreen.c
@@ -39,7 +39,7 @@
39#include <linux/module.h> 39#include <linux/module.h>
40#include <linux/init.h> 40#include <linux/init.h>
41#include <linux/usb.h> 41#include <linux/usb.h>
42#include <linux/usb_input.h> 42#include <linux/usb/input.h>
43 43
44 44
45#define DRIVER_VERSION "v0.3" 45#define DRIVER_VERSION "v0.3"
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
index cf84c6096f29..369461a70b72 100644
--- a/drivers/usb/input/wacom.c
+++ b/drivers/usb/input/wacom.c
@@ -69,13 +69,10 @@
69 69
70#include <linux/kernel.h> 70#include <linux/kernel.h>
71#include <linux/slab.h> 71#include <linux/slab.h>
72#include <linux/input.h>
73#include <linux/module.h> 72#include <linux/module.h>
74#include <linux/init.h> 73#include <linux/init.h>
75#include <linux/usb.h> 74#include <linux/usb/input.h>
76#include <linux/usb_input.h>
77#include <asm/unaligned.h> 75#include <asm/unaligned.h>
78#include <asm/byteorder.h>
79 76
80/* 77/*
81 * Version Information 78 * Version Information
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index e278489a80c6..cfd4a4e04334 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -56,13 +56,11 @@
56 56
57#include <linux/config.h> 57#include <linux/config.h>
58#include <linux/kernel.h> 58#include <linux/kernel.h>
59#include <linux/input.h>
60#include <linux/init.h> 59#include <linux/init.h>
61#include <linux/slab.h> 60#include <linux/slab.h>
62#include <linux/module.h> 61#include <linux/module.h>
63#include <linux/smp_lock.h> 62#include <linux/smp_lock.h>
64#include <linux/usb.h> 63#include <linux/usb/input.h>
65#include <linux/usb_input.h>
66 64
67#define DRIVER_VERSION "v0.0.5" 65#define DRIVER_VERSION "v0.0.5"
68#define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>" 66#define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>"
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
index 37d2f0ba0319..24aedbb20f03 100644
--- a/drivers/usb/input/yealink.c
+++ b/drivers/usb/input/yealink.c
@@ -48,13 +48,11 @@
48 48
49#include <linux/config.h> 49#include <linux/config.h>
50#include <linux/kernel.h> 50#include <linux/kernel.h>
51#include <linux/input.h>
52#include <linux/init.h> 51#include <linux/init.h>
53#include <linux/slab.h> 52#include <linux/slab.h>
54#include <linux/module.h> 53#include <linux/module.h>
55#include <linux/rwsem.h> 54#include <linux/rwsem.h>
56#include <linux/usb.h> 55#include <linux/usb/input.h>
57#include <linux/usb_input.h>
58 56
59#include "map_to_7segment.h" 57#include "map_to_7segment.h"
60#include "yealink.h" 58#include "yealink.h"
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index 8ba6a701e9c1..daa486dde8cf 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -88,6 +88,20 @@ config USB_LED
88 To compile this driver as a module, choose M here: the 88 To compile this driver as a module, choose M here: the
89 module will be called usbled. 89 module will be called usbled.
90 90
91config USB_CY7C63
92 tristate "Cypress CY7C63xxx USB driver support"
93 depends on USB
94 help
95 Say Y here if you want to connect a Cypress CY7C63xxx
96 micro controller to your computer's USB port. This driver
97 supports the pre-programmed devices (incl. firmware) by
98 AK Modul-Bus Computer GmbH.
99
100 Please see: http://www.ak-modul-bus.de/stat/mikrocontroller.html
101
102 To compile this driver as a module, choose M here: the
103 module will be called cy7c63.
104
91config USB_CYTHERM 105config USB_CYTHERM
92 tristate "Cypress USB thermometer driver support" 106 tristate "Cypress USB thermometer driver support"
93 depends on USB 107 depends on USB
@@ -137,6 +151,15 @@ config USB_IDMOUSE
137 151
138 See also <http://www.fs.tum.de/~echtler/idmouse/>. 152 See also <http://www.fs.tum.de/~echtler/idmouse/>.
139 153
154config USB_APPLEDISPLAY
155 tristate "Apple Cinema Display support"
156 depends on USB
157 select BACKLIGHT_LCD_SUPPORT
158 select BACKLIGHT_CLASS_DEVICE
159 help
160 Say Y here if you want to control the backlight of Apple Cinema
161 Displays over USB. This driver provides a sysfs interface.
162
140source "drivers/usb/misc/sisusbvga/Kconfig" 163source "drivers/usb/misc/sisusbvga/Kconfig"
141 164
142config USB_LD 165config USB_LD
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index 6c693bc68e2e..f25a97227297 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -4,6 +4,7 @@
4# 4#
5 5
6obj-$(CONFIG_USB_AUERSWALD) += auerswald.o 6obj-$(CONFIG_USB_AUERSWALD) += auerswald.o
7obj-$(CONFIG_USB_CY7C63) += cy7c63.o
7obj-$(CONFIG_USB_CYTHERM) += cytherm.o 8obj-$(CONFIG_USB_CYTHERM) += cytherm.o
8obj-$(CONFIG_USB_EMI26) += emi26.o 9obj-$(CONFIG_USB_EMI26) += emi26.o
9obj-$(CONFIG_USB_EMI62) += emi62.o 10obj-$(CONFIG_USB_EMI62) += emi62.o
@@ -17,6 +18,7 @@ obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o
17obj-$(CONFIG_USB_RIO500) += rio500.o 18obj-$(CONFIG_USB_RIO500) += rio500.o
18obj-$(CONFIG_USB_TEST) += usbtest.o 19obj-$(CONFIG_USB_TEST) += usbtest.o
19obj-$(CONFIG_USB_USS720) += uss720.o 20obj-$(CONFIG_USB_USS720) += uss720.o
21obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o
20 22
21obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ 23obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/
22 24
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
new file mode 100644
index 000000000000..bfde82f5d180
--- /dev/null
+++ b/drivers/usb/misc/appledisplay.c
@@ -0,0 +1,383 @@
1/*
2 * Apple Cinema Display driver
3 *
4 * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
5 *
6 * Thanks to Caskey L. Dickson for his work with acdctl.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/config.h>
24#include <linux/kernel.h>
25#include <linux/errno.h>
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/usb.h>
29#include <linux/backlight.h>
30#include <linux/timer.h>
31#include <linux/workqueue.h>
32#include <asm/atomic.h>
33#include <asm/semaphore.h>
34
35#define APPLE_VENDOR_ID 0x05AC
36
37#define USB_REQ_GET_REPORT 0x01
38#define USB_REQ_SET_REPORT 0x09
39
40#define ACD_USB_TIMEOUT 250
41
42#define ACD_USB_EDID 0x0302
43#define ACD_USB_BRIGHTNESS 0x0310
44
45#define ACD_BTN_NONE 0
46#define ACD_BTN_BRIGHT_UP 3
47#define ACD_BTN_BRIGHT_DOWN 4
48
49#define ACD_URB_BUFFER_LEN 2
50#define ACD_MSG_BUFFER_LEN 2
51
52#define APPLEDISPLAY_DEVICE(prod) \
53 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
54 USB_DEVICE_ID_MATCH_INT_CLASS | \
55 USB_DEVICE_ID_MATCH_INT_PROTOCOL, \
56 .idVendor = APPLE_VENDOR_ID, \
57 .idProduct = (prod), \
58 .bInterfaceClass = USB_CLASS_HID, \
59 .bInterfaceProtocol = 0x00
60
61/* table of devices that work with this driver */
62static struct usb_device_id appledisplay_table [] = {
63 { APPLEDISPLAY_DEVICE(0x9218) },
64 { APPLEDISPLAY_DEVICE(0x9219) },
65 { APPLEDISPLAY_DEVICE(0x921d) },
66
67 /* Terminating entry */
68 { }
69};
70MODULE_DEVICE_TABLE(usb, appledisplay_table);
71
72/* Structure to hold all of our device specific stuff */
73struct appledisplay {
74 struct usb_device *udev; /* usb device */
75 struct urb *urb; /* usb request block */
76 struct backlight_device *bd; /* backlight device */
77 char *urbdata; /* interrupt URB data buffer */
78 char *msgdata; /* control message data buffer */
79
80 struct work_struct work;
81 int button_pressed;
82 spinlock_t lock;
83};
84
85static atomic_t count_displays = ATOMIC_INIT(0);
86static struct workqueue_struct *wq;
87
88static void appledisplay_complete(struct urb *urb, struct pt_regs *regs)
89{
90 struct appledisplay *pdata = urb->context;
91 unsigned long flags;
92 int retval;
93
94 switch (urb->status) {
95 case 0:
96 /* success */
97 break;
98 case -EOVERFLOW:
99 printk(KERN_ERR "appletouch: OVERFLOW with data "
100 "length %d, actual length is %d\n",
101 ACD_URB_BUFFER_LEN, pdata->urb->actual_length);
102 case -ECONNRESET:
103 case -ENOENT:
104 case -ESHUTDOWN:
105 /* This urb is terminated, clean up */
106 dbg("%s - urb shutting down with status: %d",
107 __FUNCTION__, urb->status);
108 return;
109 default:
110 dbg("%s - nonzero urb status received: %d",
111 __FUNCTION__, urb->status);
112 goto exit;
113 }
114
115 spin_lock_irqsave(&pdata->lock, flags);
116
117 switch(pdata->urbdata[1]) {
118 case ACD_BTN_BRIGHT_UP:
119 case ACD_BTN_BRIGHT_DOWN:
120 pdata->button_pressed = 1;
121 queue_work(wq, &pdata->work);
122 break;
123 case ACD_BTN_NONE:
124 default:
125 pdata->button_pressed = 0;
126 break;
127 }
128
129 spin_unlock_irqrestore(&pdata->lock, flags);
130
131exit:
132 retval = usb_submit_urb(pdata->urb, GFP_ATOMIC);
133 if (retval) {
134 err("%s - usb_submit_urb failed with result %d",
135 __FUNCTION__, retval);
136 }
137}
138
139static int appledisplay_bl_update_status(struct backlight_device *bd)
140{
141 struct appledisplay *pdata = class_get_devdata(&bd->class_dev);
142 int retval;
143
144 pdata->msgdata[0] = 0x10;
145 pdata->msgdata[1] = bd->props->brightness;
146
147 retval = usb_control_msg(
148 pdata->udev,
149 usb_sndctrlpipe(pdata->udev, 0),
150 USB_REQ_SET_REPORT,
151 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
152 ACD_USB_BRIGHTNESS,
153 0,
154 pdata->msgdata, 2,
155 ACD_USB_TIMEOUT);
156
157 return retval;
158}
159
160static int appledisplay_bl_get_brightness(struct backlight_device *bd)
161{
162 struct appledisplay *pdata = class_get_devdata(&bd->class_dev);
163 int retval;
164
165 retval = usb_control_msg(
166 pdata->udev,
167 usb_rcvctrlpipe(pdata->udev, 0),
168 USB_REQ_GET_REPORT,
169 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
170 ACD_USB_BRIGHTNESS,
171 0,
172 pdata->msgdata, 2,
173 ACD_USB_TIMEOUT);
174
175 if (retval < 0)
176 return retval;
177 else
178 return pdata->msgdata[1];
179}
180
181static struct backlight_properties appledisplay_bl_data = {
182 .owner = THIS_MODULE,
183 .get_brightness = appledisplay_bl_get_brightness,
184 .update_status = appledisplay_bl_update_status,
185 .max_brightness = 0xFF
186};
187
188static void appledisplay_work(void *private)
189{
190 struct appledisplay *pdata = private;
191 int retval;
192
193 up(&pdata->bd->sem);
194 retval = appledisplay_bl_get_brightness(pdata->bd);
195 if (retval >= 0)
196 pdata->bd->props->brightness = retval;
197 down(&pdata->bd->sem);
198
199 /* Poll again in about 125ms if there's still a button pressed */
200 if (pdata->button_pressed)
201 schedule_delayed_work(&pdata->work, HZ / 8);
202}
203
204static int appledisplay_probe(struct usb_interface *iface,
205 const struct usb_device_id *id)
206{
207 struct appledisplay *pdata;
208 struct usb_device *udev = interface_to_usbdev(iface);
209 struct usb_host_interface *iface_desc;
210 struct usb_endpoint_descriptor *endpoint;
211 int int_in_endpointAddr = 0;
212 int i, retval = -ENOMEM, brightness;
213 char bl_name[20];
214
215 /* set up the endpoint information */
216 /* use only the first interrupt-in endpoint */
217 iface_desc = iface->cur_altsetting;
218 for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
219 endpoint = &iface_desc->endpoint[i].desc;
220 if (!int_in_endpointAddr &&
221 (endpoint->bEndpointAddress & USB_DIR_IN) &&
222 ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
223 USB_ENDPOINT_XFER_INT)) {
224 /* we found an interrupt in endpoint */
225 int_in_endpointAddr = endpoint->bEndpointAddress;
226 break;
227 }
228 }
229 if (!int_in_endpointAddr) {
230 err("Could not find int-in endpoint");
231 return -EIO;
232 }
233
234 /* allocate memory for our device state and initialize it */
235 pdata = kzalloc(sizeof(struct appledisplay), GFP_KERNEL);
236 if (!pdata) {
237 retval = -ENOMEM;
238 err("Out of memory");
239 goto error;
240 }
241
242 pdata->udev = udev;
243
244 spin_lock_init(&pdata->lock);
245 INIT_WORK(&pdata->work, appledisplay_work, pdata);
246
247 /* Allocate buffer for control messages */
248 pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL);
249 if (!pdata->msgdata) {
250 retval = -ENOMEM;
251 err("appledisplay: Allocating buffer for control messages "
252 "failed");
253 goto error;
254 }
255
256 /* Allocate interrupt URB */
257 pdata->urb = usb_alloc_urb(0, GFP_KERNEL);
258 if (!pdata->urb) {
259 retval = -ENOMEM;
260 err("appledisplay: Allocating URB failed");
261 goto error;
262 }
263
264 /* Allocate buffer for interrupt data */
265 pdata->urbdata = usb_buffer_alloc(pdata->udev, ACD_URB_BUFFER_LEN,
266 GFP_KERNEL, &pdata->urb->transfer_dma);
267 if (!pdata->urbdata) {
268 retval = -ENOMEM;
269 err("appledisplay: Allocating URB buffer failed");
270 goto error;
271 }
272
273 /* Configure interrupt URB */
274 usb_fill_int_urb(pdata->urb, udev,
275 usb_rcvintpipe(udev, int_in_endpointAddr),
276 pdata->urbdata, ACD_URB_BUFFER_LEN, appledisplay_complete,
277 pdata, 1);
278 if (usb_submit_urb(pdata->urb, GFP_KERNEL)) {
279 retval = -EIO;
280 err("appledisplay: Submitting URB failed");
281 goto error;
282 }
283
284 /* Register backlight device */
285 snprintf(bl_name, sizeof(bl_name), "appledisplay%d",
286 atomic_inc_return(&count_displays) - 1);
287 pdata->bd = backlight_device_register(bl_name, pdata,
288 &appledisplay_bl_data);
289 if (IS_ERR(pdata->bd)) {
290 err("appledisplay: Backlight registration failed");
291 goto error;
292 }
293
294 /* Try to get brightness */
295 up(&pdata->bd->sem);
296 brightness = appledisplay_bl_get_brightness(pdata->bd);
297 down(&pdata->bd->sem);
298
299 if (brightness < 0) {
300 retval = brightness;
301 err("appledisplay: Error while getting initial brightness: %d", retval);
302 goto error;
303 }
304
305 /* Set brightness in backlight device */
306 up(&pdata->bd->sem);
307 pdata->bd->props->brightness = brightness;
308 down(&pdata->bd->sem);
309
310 /* save our data pointer in the interface device */
311 usb_set_intfdata(iface, pdata);
312
313 printk(KERN_INFO "appledisplay: Apple Cinema Display connected\n");
314
315 return 0;
316
317error:
318 if (pdata) {
319 if (pdata->urb) {
320 usb_kill_urb(pdata->urb);
321 if (pdata->urbdata)
322 usb_buffer_free(pdata->udev, ACD_URB_BUFFER_LEN,
323 pdata->urbdata, pdata->urb->transfer_dma);
324 usb_free_urb(pdata->urb);
325 }
326 if (pdata->bd)
327 backlight_device_unregister(pdata->bd);
328 kfree(pdata->msgdata);
329 }
330 usb_set_intfdata(iface, NULL);
331 kfree(pdata);
332 return retval;
333}
334
335static void appledisplay_disconnect(struct usb_interface *iface)
336{
337 struct appledisplay *pdata = usb_get_intfdata(iface);
338
339 if (pdata) {
340 usb_kill_urb(pdata->urb);
341 cancel_delayed_work(&pdata->work);
342 backlight_device_unregister(pdata->bd);
343 usb_buffer_free(pdata->udev, ACD_URB_BUFFER_LEN,
344 pdata->urbdata, pdata->urb->transfer_dma);
345 usb_free_urb(pdata->urb);
346 kfree(pdata->msgdata);
347 kfree(pdata);
348 }
349
350 printk(KERN_INFO "appledisplay: Apple Cinema Display disconnected\n");
351}
352
353static struct usb_driver appledisplay_driver = {
354 .name = "appledisplay",
355 .probe = appledisplay_probe,
356 .disconnect = appledisplay_disconnect,
357 .id_table = appledisplay_table,
358};
359
360static int __init appledisplay_init(void)
361{
362 wq = create_singlethread_workqueue("appledisplay");
363 if (!wq) {
364 err("Could not create work queue\n");
365 return -ENOMEM;
366 }
367
368 return usb_register(&appledisplay_driver);
369}
370
371static void __exit appledisplay_exit(void)
372{
373 flush_workqueue(wq);
374 destroy_workqueue(wq);
375 usb_deregister(&appledisplay_driver);
376}
377
378MODULE_AUTHOR("Michael Hanselmann");
379MODULE_DESCRIPTION("Apple Cinema Display driver");
380MODULE_LICENSE("GPL");
381
382module_init(appledisplay_init);
383module_exit(appledisplay_exit);
diff --git a/drivers/usb/misc/cy7c63.c b/drivers/usb/misc/cy7c63.c
new file mode 100644
index 000000000000..8a1c10b89b76
--- /dev/null
+++ b/drivers/usb/misc/cy7c63.c
@@ -0,0 +1,244 @@
1/*
2* cy7c63.c
3*
4* Copyright (c) 2006 Oliver Bock (bock@fh-wolfenbuettel.de)
5*
6* This driver is based on the Cypress Thermometer USB Driver by
7* Marcus Maul and the 2.0 version of Greg Kroah-Hartman's
8* USB Skeleton driver.
9*
10* Is is a generic driver for the Cypress CY7C63000 family.
11* For the time being it enables you to toggle the single I/O ports
12* of the device.
13*
14* Supported vendors: AK Modul-Bus Computer GmbH
15* Supported devices: CY7C63001A-PC (to be continued...)
16* Supported functions: Read/Write Ports (to be continued...)
17*
18* Chipsets families: CY7C63000, CY7C63001, CY7C63100, CY7C63101
19*
20*
21* This program is free software; you can redistribute it and/or
22* modify it under the terms of the GNU General Public License as
23* published by the Free Software Foundation, version 2.
24*/
25
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/usb.h>
30
31#define DRIVER_AUTHOR "Oliver Bock (bock@fh-wolfenbuettel.de)"
32#define DRIVER_DESC "Cypress CY7C63xxx USB driver"
33
34#define CY7C63_VENDOR_ID 0xa2c
35#define CY7C63_PRODUCT_ID 0x8
36
37#define CY7C63_READ_PORT 0x4
38#define CY7C63_WRITE_PORT 0x5
39#define CY7C63_READ_RAM 0x2
40#define CY7C63_WRITE_RAM 0x3
41#define CY7C63_READ_ROM 0x1
42
43#define CY7C63_READ_PORT_ID0 0
44#define CY7C63_WRITE_PORT_ID0 0
45#define CY7C63_READ_PORT_ID1 0x2
46#define CY7C63_WRITE_PORT_ID1 1
47
48#define CY7C63_MAX_REQSIZE 8
49
50
51/* table of devices that work with this driver */
52static struct usb_device_id cy7c63_table [] = {
53 { USB_DEVICE(CY7C63_VENDOR_ID, CY7C63_PRODUCT_ID) },
54 { }
55};
56MODULE_DEVICE_TABLE(usb, cy7c63_table);
57
58/* structure to hold all of our device specific stuff */
59struct cy7c63 {
60 struct usb_device * udev;
61 char port0;
62 char port1;
63};
64
65/* used to send usb control messages to device */
66int vendor_command(struct cy7c63 *dev, unsigned char request,
67 unsigned char address, unsigned char data) {
68
69 int retval = 0;
70 unsigned int pipe;
71 unsigned char *iobuf;
72
73 /* allocate some memory for the i/o buffer*/
74 iobuf = kzalloc(CY7C63_MAX_REQSIZE, GFP_KERNEL);
75 if (!iobuf) {
76 dev_err(&dev->udev->dev, "Out of memory!\n");
77 retval = -ENOMEM;
78 goto error;
79 }
80
81 dev_dbg(&dev->udev->dev, "Sending usb_control_msg (data: %d)\n", data);
82
83 /* prepare usb control message and send it upstream */
84 pipe = usb_rcvctrlpipe(dev->udev, 0);
85 retval = usb_control_msg(dev->udev, pipe, request,
86 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
87 address, data, iobuf, CY7C63_MAX_REQSIZE,
88 USB_CTRL_GET_TIMEOUT);
89
90 /* store returned data (more READs to be added!) */
91 switch (request) {
92 case CY7C63_READ_PORT:
93 if (address == CY7C63_READ_PORT_ID0) {
94 dev->port0 = iobuf[1];
95 dev_dbg(&dev->udev->dev,
96 "READ_PORT0 returned: %d\n",dev->port0);
97 }
98 else if (address == CY7C63_READ_PORT_ID1) {
99 dev->port1 = iobuf[1];
100 dev_dbg(&dev->udev->dev,
101 "READ_PORT1 returned: %d\n",dev->port1);
102 }
103 break;
104 }
105
106 kfree(iobuf);
107error:
108 return retval;
109}
110
111#define get_set_port(num,read_id,write_id) \
112static ssize_t set_port##num(struct device *dev, struct device_attribute *attr, \
113 const char *buf, size_t count) { \
114 \
115 int value; \
116 int result = 0; \
117 \
118 struct usb_interface *intf = to_usb_interface(dev); \
119 struct cy7c63 *cyp = usb_get_intfdata(intf); \
120 \
121 dev_dbg(&cyp->udev->dev, "WRITE_PORT%d called\n", num); \
122 \
123 /* validate input data */ \
124 if (sscanf(buf, "%d", &value) < 1) { \
125 result = -EINVAL; \
126 goto error; \
127 } \
128 if (value>255 || value<0) { \
129 result = -EINVAL; \
130 goto error; \
131 } \
132 \
133 result = vendor_command(cyp, CY7C63_WRITE_PORT, write_id, \
134 (unsigned char)value); \
135 \
136 dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n",result); \
137error: \
138 return result < 0 ? result : count; \
139} \
140 \
141static ssize_t get_port##num(struct device *dev, \
142 struct device_attribute *attr, char *buf) { \
143 \
144 int result = 0; \
145 \
146 struct usb_interface *intf = to_usb_interface(dev); \
147 struct cy7c63 *cyp = usb_get_intfdata(intf); \
148 \
149 dev_dbg(&cyp->udev->dev, "READ_PORT%d called\n", num); \
150 \
151 result = vendor_command(cyp, CY7C63_READ_PORT, read_id, 0); \
152 \
153 dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n", result); \
154 \
155 return sprintf(buf, "%d", cyp->port##num); \
156} \
157static DEVICE_ATTR(port##num, S_IWUGO | S_IRUGO, get_port##num, set_port##num);
158
159get_set_port(0, CY7C63_READ_PORT_ID0, CY7C63_WRITE_PORT_ID0);
160get_set_port(1, CY7C63_READ_PORT_ID1, CY7C63_WRITE_PORT_ID1);
161
162static int cy7c63_probe(struct usb_interface *interface,
163 const struct usb_device_id *id) {
164
165 struct cy7c63 *dev = NULL;
166 int retval = -ENOMEM;
167
168 /* allocate memory for our device state and initialize it */
169 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
170 if (dev == NULL) {
171 dev_err(&dev->udev->dev, "Out of memory!\n");
172 goto error;
173 }
174
175 dev->udev = usb_get_dev(interface_to_usbdev(interface));
176
177 /* save our data pointer in this interface device */
178 usb_set_intfdata(interface, dev);
179
180 /* create device attribute files */
181 device_create_file(&interface->dev, &dev_attr_port0);
182 device_create_file(&interface->dev, &dev_attr_port1);
183
184 /* let the user know what node this device is now attached to */
185 dev_info(&interface->dev,
186 "Cypress CY7C63xxx device now attached\n");
187
188 retval = 0;
189error:
190 return retval;
191}
192
193static void cy7c63_disconnect(struct usb_interface *interface) {
194
195 struct cy7c63 *dev;
196
197 dev = usb_get_intfdata(interface);
198 usb_set_intfdata(interface, NULL);
199
200 /* remove device attribute files */
201 device_remove_file(&interface->dev, &dev_attr_port0);
202 device_remove_file(&interface->dev, &dev_attr_port1);
203
204 usb_put_dev(dev->udev);
205
206 dev_info(&interface->dev,
207 "Cypress CY7C63xxx device now disconnected\n");
208
209 kfree(dev);
210}
211
212static struct usb_driver cy7c63_driver = {
213 .name = "cy7c63",
214 .probe = cy7c63_probe,
215 .disconnect = cy7c63_disconnect,
216 .id_table = cy7c63_table,
217};
218
219static int __init cy7c63_init(void) {
220
221 int result;
222
223 /* register this driver with the USB subsystem */
224 result = usb_register(&cy7c63_driver);
225 if (result) {
226 err("Function usb_register failed! Error number: %d\n", result);
227 }
228
229 return result;
230}
231
232static void __exit cy7c63_exit(void) {
233
234 /* deregister this driver with the USB subsystem */
235 usb_deregister(&cy7c63_driver);
236}
237
238module_init(cy7c63_init);
239module_exit(cy7c63_exit);
240
241MODULE_AUTHOR(DRIVER_AUTHOR);
242MODULE_DESCRIPTION(DRIVER_DESC);
243
244MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c
index 997db5d8e35b..13aeea2026cc 100644
--- a/drivers/usb/misc/phidgetkit.c
+++ b/drivers/usb/misc/phidgetkit.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * USB PhidgetInterfaceKit driver 1.0 2 * USB PhidgetInterfaceKit driver 1.0
3 * 3 *
4 * Copyright (C) 2004 Sean Young <sean@mess.org> 4 * Copyright (C) 2004, 2006 Sean Young <sean@mess.org>
5 * Copyright (C) 2005 Daniel Saakes <daniel@saakes.net>
5 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> 6 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
@@ -25,6 +26,7 @@
25 26
26#define USB_VENDOR_ID_GLAB 0x06c2 27#define USB_VENDOR_ID_GLAB 0x06c2
27#define USB_DEVICE_ID_INTERFACEKIT004 0x0040 28#define USB_DEVICE_ID_INTERFACEKIT004 0x0040
29#define USB_DEVICE_ID_INTERFACEKIT01616 0x0044
28#define USB_DEVICE_ID_INTERFACEKIT888 0x0045 30#define USB_DEVICE_ID_INTERFACEKIT888 0x0045
29#define USB_DEVICE_ID_INTERFACEKIT047 0x0051 31#define USB_DEVICE_ID_INTERFACEKIT047 0x0051
30#define USB_DEVICE_ID_INTERFACEKIT088 0x0053 32#define USB_DEVICE_ID_INTERFACEKIT088 0x0053
@@ -32,7 +34,9 @@
32#define USB_VENDOR_ID_WISEGROUP 0x0925 34#define USB_VENDOR_ID_WISEGROUP 0x0925
33#define USB_DEVICE_ID_INTERFACEKIT884 0x8201 35#define USB_DEVICE_ID_INTERFACEKIT884 0x8201
34 36
35#define MAX_INTERFACES 8 37#define MAX_INTERFACES 16
38
39#define URB_INT_SIZE 8
36 40
37struct driver_interfacekit { 41struct driver_interfacekit {
38 int sensors; 42 int sensors;
@@ -52,19 +56,24 @@ ifkit(8, 8, 8, 0);
52ifkit(0, 4, 7, 1); 56ifkit(0, 4, 7, 1);
53ifkit(8, 8, 4, 0); 57ifkit(8, 8, 4, 0);
54ifkit(0, 8, 8, 1); 58ifkit(0, 8, 8, 1);
59ifkit(0, 16, 16, 0);
55 60
56struct phidget_interfacekit { 61struct interfacekit {
57 struct usb_device *udev; 62 struct usb_device *udev;
58 struct usb_interface *intf; 63 struct usb_interface *intf;
59 struct driver_interfacekit *ifkit; 64 struct driver_interfacekit *ifkit;
60 int outputs[MAX_INTERFACES]; 65 unsigned long outputs;
61 int inputs[MAX_INTERFACES]; 66 u8 inputs[MAX_INTERFACES];
62 int sensors[MAX_INTERFACES]; 67 u16 sensors[MAX_INTERFACES];
63 u8 lcd_files_on; 68 u8 lcd_files_on;
64 69
65 struct urb *irq; 70 struct urb *irq;
66 unsigned char *data; 71 unsigned char *data;
67 dma_addr_t data_dma; 72 dma_addr_t data_dma;
73
74 struct work_struct do_notify;
75 unsigned long input_events;
76 unsigned long sensor_events;
68}; 77};
69 78
70static struct usb_device_id id_table[] = { 79static struct usb_device_id id_table[] = {
@@ -76,33 +85,33 @@ static struct usb_device_id id_table[] = {
76 .driver_info = (kernel_ulong_t)&ph_047}, 85 .driver_info = (kernel_ulong_t)&ph_047},
77 {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT088), 86 {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT088),
78 .driver_info = (kernel_ulong_t)&ph_088}, 87 .driver_info = (kernel_ulong_t)&ph_088},
88 {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT01616),
89 .driver_info = (kernel_ulong_t)&ph_01616},
79 {USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_INTERFACEKIT884), 90 {USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_INTERFACEKIT884),
80 .driver_info = (kernel_ulong_t)&ph_884}, 91 .driver_info = (kernel_ulong_t)&ph_884},
81 {} 92 {}
82}; 93};
83MODULE_DEVICE_TABLE(usb, id_table); 94MODULE_DEVICE_TABLE(usb, id_table);
84 95
85static int change_outputs(struct phidget_interfacekit *kit, int output_num, int enable) 96static int change_outputs(struct interfacekit *kit, int output_num, int enable)
86{ 97{
87 unsigned char *buffer; 98 u8 *buffer;
88 int retval; 99 int retval;
89 int n; 100
101 if (enable)
102 set_bit(output_num, &kit->outputs);
103 else
104 clear_bit(output_num, &kit->outputs);
90 105
91 buffer = kzalloc(4, GFP_KERNEL); 106 buffer = kzalloc(4, GFP_KERNEL);
92 if (!buffer) { 107 if (!buffer) {
93 dev_err(&kit->udev->dev, "%s - out of memory\n", 108 dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__);
94 __FUNCTION__);
95 return -ENOMEM; 109 return -ENOMEM;
96 } 110 }
111 buffer[0] = (u8)kit->outputs;
112 buffer[1] = (u8)(kit->outputs >> 8);
97 113
98 kit->outputs[output_num] = enable; 114 dev_dbg(&kit->udev->dev, "sending data: 0x%04x\n", (u16)kit->outputs);
99 for (n=0; n<8; n++) {
100 if (kit->outputs[n]) {
101 buffer[0] |= 1 << n;
102 }
103 }
104
105 dev_dbg(&kit->udev->dev, "sending data: %02x\n", buffer[0]);
106 115
107 retval = usb_control_msg(kit->udev, 116 retval = usb_control_msg(kit->udev,
108 usb_sndctrlpipe(kit->udev, 0), 117 usb_sndctrlpipe(kit->udev, 0),
@@ -116,10 +125,10 @@ static int change_outputs(struct phidget_interfacekit *kit, int output_num, int
116 return retval < 0 ? retval : 0; 125 return retval < 0 ? retval : 0;
117} 126}
118 127
119static int change_string(struct phidget_interfacekit *kit, const char *display, unsigned char row) 128static int change_string(struct interfacekit *kit, const char *display, unsigned char row)
120{ 129{
121 unsigned char *buffer; 130 unsigned char *buffer;
122 unsigned char *form_buffer; 131 unsigned char *form_buffer;
123 int retval = -ENOMEM; 132 int retval = -ENOMEM;
124 int i,j, len, buf_ptr; 133 int i,j, len, buf_ptr;
125 134
@@ -175,7 +184,7 @@ exit:
175static ssize_t lcd_line_##number(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ 184static ssize_t lcd_line_##number(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
176{ \ 185{ \
177 struct usb_interface *intf = to_usb_interface(dev); \ 186 struct usb_interface *intf = to_usb_interface(dev); \
178 struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ 187 struct interfacekit *kit = usb_get_intfdata(intf); \
179 change_string(kit, buf, number - 1); \ 188 change_string(kit, buf, number - 1); \
180 return count; \ 189 return count; \
181} \ 190} \
@@ -186,7 +195,7 @@ set_lcd_line(2);
186static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 195static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
187{ 196{
188 struct usb_interface *intf = to_usb_interface(dev); 197 struct usb_interface *intf = to_usb_interface(dev);
189 struct phidget_interfacekit *kit = usb_get_intfdata(intf); 198 struct interfacekit *kit = usb_get_intfdata(intf);
190 int enabled; 199 int enabled;
191 unsigned char *buffer; 200 unsigned char *buffer;
192 int retval = -ENOMEM; 201 int retval = -ENOMEM;
@@ -220,7 +229,7 @@ exit:
220} 229}
221static DEVICE_ATTR(backlight, S_IWUGO, NULL, set_backlight); 230static DEVICE_ATTR(backlight, S_IWUGO, NULL, set_backlight);
222 231
223static void remove_lcd_files(struct phidget_interfacekit *kit) 232static void remove_lcd_files(struct interfacekit *kit)
224{ 233{
225 if (kit->lcd_files_on) { 234 if (kit->lcd_files_on) {
226 dev_dbg(&kit->udev->dev, "Removing lcd files\n"); 235 dev_dbg(&kit->udev->dev, "Removing lcd files\n");
@@ -233,7 +242,7 @@ static void remove_lcd_files(struct phidget_interfacekit *kit)
233static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 242static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
234{ 243{
235 struct usb_interface *intf = to_usb_interface(dev); 244 struct usb_interface *intf = to_usb_interface(dev);
236 struct phidget_interfacekit *kit = usb_get_intfdata(intf); 245 struct interfacekit *kit = usb_get_intfdata(intf);
237 int enable; 246 int enable;
238 247
239 if (kit->ifkit->has_lcd == 0) 248 if (kit->ifkit->has_lcd == 0)
@@ -263,10 +272,10 @@ static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files);
263 272
264static void interfacekit_irq(struct urb *urb, struct pt_regs *regs) 273static void interfacekit_irq(struct urb *urb, struct pt_regs *regs)
265{ 274{
266 struct phidget_interfacekit *kit = urb->context; 275 struct interfacekit *kit = urb->context;
267 unsigned char *buffer = kit->data; 276 unsigned char *buffer = kit->data;
277 int i, level, sensor;
268 int status; 278 int status;
269 int n;
270 279
271 switch (urb->status) { 280 switch (urb->status) {
272 case 0: /* success */ 281 case 0: /* success */
@@ -280,22 +289,63 @@ static void interfacekit_irq(struct urb *urb, struct pt_regs *regs)
280 goto resubmit; 289 goto resubmit;
281 } 290 }
282 291
283 for (n=0; n<8; n++) { 292 /* digital inputs */
284 kit->inputs[n] = buffer[1] & (1 << n) ? 1 : 0; 293 if (kit->ifkit->inputs == 16) {
294 for (i=0; i < 8; i++) {
295 level = (buffer[0] >> i) & 1;
296 if (kit->inputs[i] != level) {
297 kit->inputs[i] = level;
298 set_bit(i, &kit->input_events);
299 }
300 level = (buffer[1] >> i) & 1;
301 if (kit->inputs[8 + i] != level) {
302 kit->inputs[8 + i] = level;
303 set_bit(8 + i, &kit->input_events);
304 }
305 }
306 }
307 else if (kit->ifkit->inputs == 8) {
308 for (i=0; i < 8; i++) {
309 level = (buffer[1] >> i) & 1;
310 if (kit->inputs[i] != level) {
311 kit->inputs[i] = level;
312 set_bit(i, &kit->input_events);
313 }
314 }
285 } 315 }
286 316
287 if (buffer[0] & 1) { 317 /* analog inputs */
288 kit->sensors[4] = buffer[2] + (buffer[3] & 0x0f) * 256; 318 if (kit->ifkit->sensors) {
289 kit->sensors[5] = buffer[4] + (buffer[3] & 0xf0) * 16; 319 sensor = (buffer[0] & 1) ? 4 : 0;
290 kit->sensors[6] = buffer[5] + (buffer[6] & 0x0f) * 256; 320
291 kit->sensors[7] = buffer[7] + (buffer[6] & 0xf0) * 16; 321 level = buffer[2] + (buffer[3] & 0x0f) * 256;
292 } else { 322 if (level != kit->sensors[sensor]) {
293 kit->sensors[0] = buffer[2] + (buffer[3] & 0x0f) * 256; 323 kit->sensors[sensor] = level;
294 kit->sensors[1] = buffer[4] + (buffer[3] & 0xf0) * 16; 324 set_bit(sensor, &kit->sensor_events);
295 kit->sensors[2] = buffer[5] + (buffer[6] & 0x0f) * 256; 325 }
296 kit->sensors[3] = buffer[7] + (buffer[6] & 0xf0) * 16; 326 sensor++;
327 level = buffer[4] + (buffer[3] & 0xf0) * 16;
328 if (level != kit->sensors[sensor]) {
329 kit->sensors[sensor] = level;
330 set_bit(sensor, &kit->sensor_events);
331 }
332 sensor++;
333 level = buffer[5] + (buffer[6] & 0x0f) * 256;
334 if (level != kit->sensors[sensor]) {
335 kit->sensors[sensor] = level;
336 set_bit(sensor, &kit->sensor_events);
337 }
338 sensor++;
339 level = buffer[7] + (buffer[6] & 0xf0) * 16;
340 if (level != kit->sensors[sensor]) {
341 kit->sensors[sensor] = level;
342 set_bit(sensor, &kit->sensor_events);
343 }
297 } 344 }
298 345
346 if (kit->input_events || kit->sensor_events)
347 schedule_work(&kit->do_notify);
348
299resubmit: 349resubmit:
300 status = usb_submit_urb(urb, SLAB_ATOMIC); 350 status = usb_submit_urb(urb, SLAB_ATOMIC);
301 if (status) 351 if (status)
@@ -304,20 +354,40 @@ resubmit:
304 kit->udev->devpath, status); 354 kit->udev->devpath, status);
305} 355}
306 356
357static void do_notify(void *data)
358{
359 struct interfacekit *kit = data;
360 int i;
361 char sysfs_file[8];
362
363 for (i=0; i<kit->ifkit->inputs; i++) {
364 if (test_and_clear_bit(i, &kit->input_events)) {
365 sprintf(sysfs_file, "input%d", i + 1);
366 sysfs_notify(&kit->intf->dev.kobj, NULL, sysfs_file);
367 }
368 }
369
370 for (i=0; i<kit->ifkit->sensors; i++) {
371 if (test_and_clear_bit(i, &kit->sensor_events)) {
372 sprintf(sysfs_file, "sensor%d", i + 1);
373 sysfs_notify(&kit->intf->dev.kobj, NULL, sysfs_file);
374 }
375 }
376}
377
307#define show_set_output(value) \ 378#define show_set_output(value) \
308static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, \ 379static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, \
309 size_t count) \ 380 size_t count) \
310{ \ 381{ \
311 struct usb_interface *intf = to_usb_interface(dev); \ 382 struct usb_interface *intf = to_usb_interface(dev); \
312 struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ 383 struct interfacekit *kit = usb_get_intfdata(intf); \
313 int enabled; \ 384 int enabled; \
314 int retval; \ 385 int retval; \
315 \ 386 \
316 if (sscanf(buf, "%d", &enabled) < 1) { \ 387 if (sscanf(buf, "%d", &enabled) < 1) \
317 return -EINVAL; \ 388 return -EINVAL; \
318 } \
319 \ 389 \
320 retval = change_outputs(kit, value - 1, enabled ? 1 : 0); \ 390 retval = change_outputs(kit, value - 1, enabled); \
321 \ 391 \
322 return retval ? retval : count; \ 392 return retval ? retval : count; \
323} \ 393} \
@@ -325,9 +395,9 @@ static ssize_t set_output##value(struct device *dev, struct device_attribute *at
325static ssize_t show_output##value(struct device *dev, struct device_attribute *attr, char *buf) \ 395static ssize_t show_output##value(struct device *dev, struct device_attribute *attr, char *buf) \
326{ \ 396{ \
327 struct usb_interface *intf = to_usb_interface(dev); \ 397 struct usb_interface *intf = to_usb_interface(dev); \
328 struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ 398 struct interfacekit *kit = usb_get_intfdata(intf); \
329 \ 399 \
330 return sprintf(buf, "%d\n", kit->outputs[value - 1]); \ 400 return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\
331} \ 401} \
332static DEVICE_ATTR(output##value, S_IWUGO | S_IRUGO, \ 402static DEVICE_ATTR(output##value, S_IWUGO | S_IRUGO, \
333 show_output##value, set_output##value); 403 show_output##value, set_output##value);
@@ -338,15 +408,23 @@ show_set_output(4);
338show_set_output(5); 408show_set_output(5);
339show_set_output(6); 409show_set_output(6);
340show_set_output(7); 410show_set_output(7);
341show_set_output(8); /* should be MAX_INTERFACES - 1 */ 411show_set_output(8);
412show_set_output(9);
413show_set_output(10);
414show_set_output(11);
415show_set_output(12);
416show_set_output(13);
417show_set_output(14);
418show_set_output(15);
419show_set_output(16);
342 420
343#define show_input(value) \ 421#define show_input(value) \
344static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf) \ 422static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf) \
345{ \ 423{ \
346 struct usb_interface *intf = to_usb_interface(dev); \ 424 struct usb_interface *intf = to_usb_interface(dev); \
347 struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ 425 struct interfacekit *kit = usb_get_intfdata(intf); \
348 \ 426 \
349 return sprintf(buf, "%d\n", kit->inputs[value - 1]); \ 427 return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \
350} \ 428} \
351static DEVICE_ATTR(input##value, S_IRUGO, show_input##value, NULL); 429static DEVICE_ATTR(input##value, S_IRUGO, show_input##value, NULL);
352 430
@@ -357,15 +435,23 @@ show_input(4);
357show_input(5); 435show_input(5);
358show_input(6); 436show_input(6);
359show_input(7); 437show_input(7);
360show_input(8); /* should be MAX_INTERFACES - 1 */ 438show_input(8);
439show_input(9);
440show_input(10);
441show_input(11);
442show_input(12);
443show_input(13);
444show_input(14);
445show_input(15);
446show_input(16);
361 447
362#define show_sensor(value) \ 448#define show_sensor(value) \
363static ssize_t show_sensor##value(struct device *dev, struct device_attribute *attr, char *buf) \ 449static ssize_t show_sensor##value(struct device *dev, struct device_attribute *attr, char *buf) \
364{ \ 450{ \
365 struct usb_interface *intf = to_usb_interface(dev); \ 451 struct usb_interface *intf = to_usb_interface(dev); \
366 struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ 452 struct interfacekit *kit = usb_get_intfdata(intf); \
367 \ 453 \
368 return sprintf(buf, "%d\n", kit->sensors[value - 1]); \ 454 return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \
369} \ 455} \
370static DEVICE_ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL); 456static DEVICE_ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL);
371 457
@@ -376,16 +462,16 @@ show_sensor(4);
376show_sensor(5); 462show_sensor(5);
377show_sensor(6); 463show_sensor(6);
378show_sensor(7); 464show_sensor(7);
379show_sensor(8); /* should be MAX_INTERFACES - 1 */ 465show_sensor(8);
380 466
381static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id) 467static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id)
382{ 468{
383 struct usb_device *dev = interface_to_usbdev(intf); 469 struct usb_device *dev = interface_to_usbdev(intf);
384 struct usb_host_interface *interface; 470 struct usb_host_interface *interface;
385 struct usb_endpoint_descriptor *endpoint; 471 struct usb_endpoint_descriptor *endpoint;
386 struct phidget_interfacekit *kit; 472 struct interfacekit *kit;
387 struct driver_interfacekit *ifkit; 473 struct driver_interfacekit *ifkit;
388 int pipe, maxp; 474 int pipe, maxp, rc = -ENOMEM;
389 475
390 ifkit = (struct driver_interfacekit *)id->driver_info; 476 ifkit = (struct driver_interfacekit *)id->driver_info;
391 if (!ifkit) 477 if (!ifkit)
@@ -405,29 +491,23 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
405 maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); 491 maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
406 492
407 kit = kzalloc(sizeof(*kit), GFP_KERNEL); 493 kit = kzalloc(sizeof(*kit), GFP_KERNEL);
408 if (kit == NULL) { 494 if (!kit)
409 dev_err(&intf->dev, "%s - out of memory\n", __FUNCTION__); 495 goto out;
410 return -ENOMEM;
411 }
412 kit->ifkit = ifkit;
413 496
414 kit->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &kit->data_dma); 497 kit->ifkit = ifkit;
415 if (!kit->data) { 498 kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &kit->data_dma);
416 kfree(kit); 499 if (!kit->data)
417 return -ENOMEM; 500 goto out;
418 }
419 501
420 kit->irq = usb_alloc_urb(0, GFP_KERNEL); 502 kit->irq = usb_alloc_urb(0, GFP_KERNEL);
421 if (!kit->irq) { 503 if (!kit->irq)
422 usb_buffer_free(dev, 8, kit->data, kit->data_dma); 504 goto out;
423 kfree(kit);
424 return -ENOMEM;
425 }
426 505
427 kit->udev = usb_get_dev(dev); 506 kit->udev = usb_get_dev(dev);
428 kit->intf = intf; 507 kit->intf = intf;
508 INIT_WORK(&kit->do_notify, do_notify, kit);
429 usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data, 509 usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data,
430 (maxp > 8 ? 8 : maxp), 510 maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp,
431 interfacekit_irq, kit, endpoint->bInterval); 511 interfacekit_irq, kit, endpoint->bInterval);
432 kit->irq->transfer_dma = kit->data_dma; 512 kit->irq->transfer_dma = kit->data_dma;
433 kit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 513 kit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
@@ -435,7 +515,8 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
435 usb_set_intfdata(intf, kit); 515 usb_set_intfdata(intf, kit);
436 516
437 if (usb_submit_urb(kit->irq, GFP_KERNEL)) { 517 if (usb_submit_urb(kit->irq, GFP_KERNEL)) {
438 return -EIO; 518 rc = -EIO;
519 goto out;
439 } 520 }
440 521
441 if (ifkit->outputs >= 4) { 522 if (ifkit->outputs >= 4) {
@@ -444,12 +525,22 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
444 device_create_file(&intf->dev, &dev_attr_output3); 525 device_create_file(&intf->dev, &dev_attr_output3);
445 device_create_file(&intf->dev, &dev_attr_output4); 526 device_create_file(&intf->dev, &dev_attr_output4);
446 } 527 }
447 if (ifkit->outputs == 8) { 528 if (ifkit->outputs >= 8) {
448 device_create_file(&intf->dev, &dev_attr_output5); 529 device_create_file(&intf->dev, &dev_attr_output5);
449 device_create_file(&intf->dev, &dev_attr_output6); 530 device_create_file(&intf->dev, &dev_attr_output6);
450 device_create_file(&intf->dev, &dev_attr_output7); 531 device_create_file(&intf->dev, &dev_attr_output7);
451 device_create_file(&intf->dev, &dev_attr_output8); 532 device_create_file(&intf->dev, &dev_attr_output8);
452 } 533 }
534 if (ifkit->outputs == 16) {
535 device_create_file(&intf->dev, &dev_attr_output9);
536 device_create_file(&intf->dev, &dev_attr_output10);
537 device_create_file(&intf->dev, &dev_attr_output11);
538 device_create_file(&intf->dev, &dev_attr_output12);
539 device_create_file(&intf->dev, &dev_attr_output13);
540 device_create_file(&intf->dev, &dev_attr_output14);
541 device_create_file(&intf->dev, &dev_attr_output15);
542 device_create_file(&intf->dev, &dev_attr_output16);
543 }
453 544
454 if (ifkit->inputs >= 4) { 545 if (ifkit->inputs >= 4) {
455 device_create_file(&intf->dev, &dev_attr_input1); 546 device_create_file(&intf->dev, &dev_attr_input1);
@@ -457,12 +548,22 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
457 device_create_file(&intf->dev, &dev_attr_input3); 548 device_create_file(&intf->dev, &dev_attr_input3);
458 device_create_file(&intf->dev, &dev_attr_input4); 549 device_create_file(&intf->dev, &dev_attr_input4);
459 } 550 }
460 if (ifkit->inputs == 8) { 551 if (ifkit->inputs >= 8) {
461 device_create_file(&intf->dev, &dev_attr_input5); 552 device_create_file(&intf->dev, &dev_attr_input5);
462 device_create_file(&intf->dev, &dev_attr_input6); 553 device_create_file(&intf->dev, &dev_attr_input6);
463 device_create_file(&intf->dev, &dev_attr_input7); 554 device_create_file(&intf->dev, &dev_attr_input7);
464 device_create_file(&intf->dev, &dev_attr_input8); 555 device_create_file(&intf->dev, &dev_attr_input8);
465 } 556 }
557 if (ifkit->inputs == 16) {
558 device_create_file(&intf->dev, &dev_attr_input9);
559 device_create_file(&intf->dev, &dev_attr_input10);
560 device_create_file(&intf->dev, &dev_attr_input11);
561 device_create_file(&intf->dev, &dev_attr_input12);
562 device_create_file(&intf->dev, &dev_attr_input13);
563 device_create_file(&intf->dev, &dev_attr_input14);
564 device_create_file(&intf->dev, &dev_attr_input15);
565 device_create_file(&intf->dev, &dev_attr_input16);
566 }
466 567
467 if (ifkit->sensors >= 4) { 568 if (ifkit->sensors >= 4) {
468 device_create_file(&intf->dev, &dev_attr_sensor1); 569 device_create_file(&intf->dev, &dev_attr_sensor1);
@@ -475,9 +576,8 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
475 device_create_file(&intf->dev, &dev_attr_sensor6); 576 device_create_file(&intf->dev, &dev_attr_sensor6);
476 device_create_file(&intf->dev, &dev_attr_sensor7); 577 device_create_file(&intf->dev, &dev_attr_sensor7);
477 } 578 }
478 if (ifkit->sensors == 8) { 579 if (ifkit->sensors == 8)
479 device_create_file(&intf->dev, &dev_attr_sensor8); 580 device_create_file(&intf->dev, &dev_attr_sensor8);
480 }
481 581
482 if (ifkit->has_lcd) 582 if (ifkit->has_lcd)
483 device_create_file(&intf->dev, &dev_attr_lcd); 583 device_create_file(&intf->dev, &dev_attr_lcd);
@@ -486,29 +586,56 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
486 ifkit->sensors, ifkit->inputs, ifkit->outputs); 586 ifkit->sensors, ifkit->inputs, ifkit->outputs);
487 587
488 return 0; 588 return 0;
589
590out:
591 if (kit) {
592 if (kit->irq)
593 usb_free_urb(kit->irq);
594 if (kit->data)
595 usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma);
596 kfree(kit);
597 }
598
599 return rc;
489} 600}
490 601
491static void interfacekit_disconnect(struct usb_interface *interface) 602static void interfacekit_disconnect(struct usb_interface *interface)
492{ 603{
493 struct phidget_interfacekit *kit; 604 struct interfacekit *kit;
494 605
495 kit = usb_get_intfdata(interface); 606 kit = usb_get_intfdata(interface);
496 usb_set_intfdata(interface, NULL); 607 usb_set_intfdata(interface, NULL);
497 if (!kit) 608 if (!kit)
498 return; 609 return;
499 610
611 usb_kill_urb(kit->irq);
612 usb_free_urb(kit->irq);
613 usb_buffer_free(kit->udev, URB_INT_SIZE, kit->data, kit->data_dma);
614
615 cancel_delayed_work(&kit->do_notify);
616
500 if (kit->ifkit->outputs >= 4) { 617 if (kit->ifkit->outputs >= 4) {
501 device_remove_file(&interface->dev, &dev_attr_output1); 618 device_remove_file(&interface->dev, &dev_attr_output1);
502 device_remove_file(&interface->dev, &dev_attr_output2); 619 device_remove_file(&interface->dev, &dev_attr_output2);
503 device_remove_file(&interface->dev, &dev_attr_output3); 620 device_remove_file(&interface->dev, &dev_attr_output3);
504 device_remove_file(&interface->dev, &dev_attr_output4); 621 device_remove_file(&interface->dev, &dev_attr_output4);
505 } 622 }
506 if (kit->ifkit->outputs == 8) { 623 if (kit->ifkit->outputs >= 8) {
507 device_remove_file(&interface->dev, &dev_attr_output5); 624 device_remove_file(&interface->dev, &dev_attr_output5);
508 device_remove_file(&interface->dev, &dev_attr_output6); 625 device_remove_file(&interface->dev, &dev_attr_output6);
509 device_remove_file(&interface->dev, &dev_attr_output7); 626 device_remove_file(&interface->dev, &dev_attr_output7);
510 device_remove_file(&interface->dev, &dev_attr_output8); 627 device_remove_file(&interface->dev, &dev_attr_output8);
511 } 628 }
629 if (kit->ifkit->outputs == 16) {
630 device_remove_file(&interface->dev, &dev_attr_output9);
631 device_remove_file(&interface->dev, &dev_attr_output10);
632 device_remove_file(&interface->dev, &dev_attr_output11);
633 device_remove_file(&interface->dev, &dev_attr_output12);
634 device_remove_file(&interface->dev, &dev_attr_output13);
635 device_remove_file(&interface->dev, &dev_attr_output14);
636 device_remove_file(&interface->dev, &dev_attr_output15);
637 device_remove_file(&interface->dev, &dev_attr_output16);
638 }
512 639
513 if (kit->ifkit->inputs >= 4) { 640 if (kit->ifkit->inputs >= 4) {
514 device_remove_file(&interface->dev, &dev_attr_input1); 641 device_remove_file(&interface->dev, &dev_attr_input1);
@@ -516,12 +643,22 @@ static void interfacekit_disconnect(struct usb_interface *interface)
516 device_remove_file(&interface->dev, &dev_attr_input3); 643 device_remove_file(&interface->dev, &dev_attr_input3);
517 device_remove_file(&interface->dev, &dev_attr_input4); 644 device_remove_file(&interface->dev, &dev_attr_input4);
518 } 645 }
519 if (kit->ifkit->inputs == 8) { 646 if (kit->ifkit->inputs >= 8) {
520 device_remove_file(&interface->dev, &dev_attr_input5); 647 device_remove_file(&interface->dev, &dev_attr_input5);
521 device_remove_file(&interface->dev, &dev_attr_input6); 648 device_remove_file(&interface->dev, &dev_attr_input6);
522 device_remove_file(&interface->dev, &dev_attr_input7); 649 device_remove_file(&interface->dev, &dev_attr_input7);
523 device_remove_file(&interface->dev, &dev_attr_input8); 650 device_remove_file(&interface->dev, &dev_attr_input8);
524 } 651 }
652 if (kit->ifkit->inputs == 16) {
653 device_remove_file(&interface->dev, &dev_attr_input9);
654 device_remove_file(&interface->dev, &dev_attr_input10);
655 device_remove_file(&interface->dev, &dev_attr_input11);
656 device_remove_file(&interface->dev, &dev_attr_input12);
657 device_remove_file(&interface->dev, &dev_attr_input13);
658 device_remove_file(&interface->dev, &dev_attr_input14);
659 device_remove_file(&interface->dev, &dev_attr_input15);
660 device_remove_file(&interface->dev, &dev_attr_input16);
661 }
525 662
526 if (kit->ifkit->sensors >= 4) { 663 if (kit->ifkit->sensors >= 4) {
527 device_remove_file(&interface->dev, &dev_attr_sensor1); 664 device_remove_file(&interface->dev, &dev_attr_sensor1);
@@ -534,19 +671,15 @@ static void interfacekit_disconnect(struct usb_interface *interface)
534 device_remove_file(&interface->dev, &dev_attr_sensor6); 671 device_remove_file(&interface->dev, &dev_attr_sensor6);
535 device_remove_file(&interface->dev, &dev_attr_sensor7); 672 device_remove_file(&interface->dev, &dev_attr_sensor7);
536 } 673 }
537 if (kit->ifkit->sensors == 8) { 674 if (kit->ifkit->sensors == 8)
538 device_remove_file(&interface->dev, &dev_attr_sensor8); 675 device_remove_file(&interface->dev, &dev_attr_sensor8);
539 } 676
540 if (kit->ifkit->has_lcd) 677 if (kit->ifkit->has_lcd)
541 device_remove_file(&interface->dev, &dev_attr_lcd); 678 device_remove_file(&interface->dev, &dev_attr_lcd);
542 679
543 dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n", 680 dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n",
544 kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs); 681 kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs);
545 682
546 usb_kill_urb(kit->irq);
547 usb_free_urb(kit->irq);
548 usb_buffer_free(kit->udev, 8, kit->data, kit->data_dma);
549
550 usb_put_dev(kit->udev); 683 usb_put_dev(kit->udev);
551 kfree(kit); 684 kfree(kit);
552} 685}
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 196c8794a73c..738bd7c7451f 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -37,6 +37,7 @@
37 */ 37 */
38 38
39#include <linux/config.h> 39#include <linux/config.h>
40#include <linux/mutex.h>
40#include <linux/module.h> 41#include <linux/module.h>
41#include <linux/kernel.h> 42#include <linux/kernel.h>
42#include <linux/signal.h> 43#include <linux/signal.h>
@@ -52,6 +53,7 @@
52#include <linux/vmalloc.h> 53#include <linux/vmalloc.h>
53 54
54#include "sisusb.h" 55#include "sisusb.h"
56#include "sisusb_init.h"
55 57
56#ifdef INCL_SISUSB_CON 58#ifdef INCL_SISUSB_CON
57#include <linux/font.h> 59#include <linux/font.h>
@@ -62,36 +64,6 @@
62/* Forward declarations / clean-up routines */ 64/* Forward declarations / clean-up routines */
63 65
64#ifdef INCL_SISUSB_CON 66#ifdef INCL_SISUSB_CON
65int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data);
66int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data);
67int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data);
68int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data);
69int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand, u8 myor);
70int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, u8 index, u8 myor);
71int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand);
72
73int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data);
74int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data);
75int sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data);
76int sisusb_readw(struct sisusb_usb_data *sisusb, u32 adr, u16 *data);
77int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src,
78 u32 dest, int length, size_t *bytes_written);
79
80int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init);
81
82extern int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
83extern int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo);
84
85extern void sisusb_init_concode(void);
86extern int sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last);
87extern void sisusb_console_exit(struct sisusb_usb_data *sisusb);
88
89extern void sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location);
90
91extern int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot,
92 u8 *arg, int cmapsz, int ch512, int dorecalc,
93 struct vc_data *c, int fh, int uplock);
94
95static int sisusb_first_vc = 0; 67static int sisusb_first_vc = 0;
96static int sisusb_last_vc = 0; 68static int sisusb_last_vc = 0;
97module_param_named(first, sisusb_first_vc, int, 0); 69module_param_named(first, sisusb_first_vc, int, 0);
@@ -102,7 +74,7 @@ MODULE_PARM_DESC(last, "Number of last console to take over (1 - MAX_NR_CONSOLES
102 74
103static struct usb_driver sisusb_driver; 75static struct usb_driver sisusb_driver;
104 76
105DECLARE_MUTEX(disconnect_sem); 77DEFINE_MUTEX(disconnect_mutex);
106 78
107static void 79static void
108sisusb_free_buffers(struct sisusb_usb_data *sisusb) 80sisusb_free_buffers(struct sisusb_usb_data *sisusb)
@@ -1359,9 +1331,6 @@ sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data)
1359} 1331}
1360#endif 1332#endif
1361 1333
1362#ifndef INCL_SISUSB_CON
1363static
1364#endif
1365int 1334int
1366sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data) 1335sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data)
1367{ 1336{
@@ -1371,9 +1340,6 @@ sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data)
1371 return ret; 1340 return ret;
1372} 1341}
1373 1342
1374#ifndef INCL_SISUSB_CON
1375static
1376#endif
1377int 1343int
1378sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data) 1344sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data)
1379{ 1345{
@@ -1383,9 +1349,6 @@ sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data)
1383 return ret; 1349 return ret;
1384} 1350}
1385 1351
1386#ifndef INCL_SISUSB_CON
1387static
1388#endif
1389int 1352int
1390sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx, 1353sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx,
1391 u8 myand, u8 myor) 1354 u8 myand, u8 myor)
@@ -1415,18 +1378,12 @@ sisusb_setidxregmask(struct sisusb_usb_data *sisusb, int port, u8 idx,
1415 return ret; 1378 return ret;
1416} 1379}
1417 1380
1418#ifndef INCL_SISUSB_CON
1419static
1420#endif
1421int 1381int
1422sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, u8 index, u8 myor) 1382sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, u8 index, u8 myor)
1423{ 1383{
1424 return(sisusb_setidxregandor(sisusb, port, index, 0xff, myor)); 1384 return(sisusb_setidxregandor(sisusb, port, index, 0xff, myor));
1425} 1385}
1426 1386
1427#ifndef INCL_SISUSB_CON
1428static
1429#endif
1430int 1387int
1431sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand) 1388sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand)
1432{ 1389{
@@ -1448,6 +1405,8 @@ sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data)
1448 return(sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data)); 1405 return(sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data));
1449} 1406}
1450 1407
1408#if 0
1409
1451int 1410int
1452sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data) 1411sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data)
1453{ 1412{
@@ -1460,6 +1419,8 @@ sisusb_readw(struct sisusb_usb_data *sisusb, u32 adr, u16 *data)
1460 return(sisusb_read_memio_word(sisusb, SISUSB_TYPE_MEM, adr, data)); 1419 return(sisusb_read_memio_word(sisusb, SISUSB_TYPE_MEM, adr, data));
1461} 1420}
1462 1421
1422#endif /* 0 */
1423
1463int 1424int
1464sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, 1425sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src,
1465 u32 dest, int length, size_t *bytes_written) 1426 u32 dest, int length, size_t *bytes_written)
@@ -2552,39 +2513,39 @@ sisusb_open(struct inode *inode, struct file *file)
2552 struct usb_interface *interface; 2513 struct usb_interface *interface;
2553 int subminor = iminor(inode); 2514 int subminor = iminor(inode);
2554 2515
2555 down(&disconnect_sem); 2516 mutex_lock(&disconnect_mutex);
2556 2517
2557 if (!(interface = usb_find_interface(&sisusb_driver, subminor))) { 2518 if (!(interface = usb_find_interface(&sisusb_driver, subminor))) {
2558 printk(KERN_ERR "sisusb[%d]: Failed to find interface\n", 2519 printk(KERN_ERR "sisusb[%d]: Failed to find interface\n",
2559 subminor); 2520 subminor);
2560 up(&disconnect_sem); 2521 mutex_unlock(&disconnect_mutex);
2561 return -ENODEV; 2522 return -ENODEV;
2562 } 2523 }
2563 2524
2564 if (!(sisusb = usb_get_intfdata(interface))) { 2525 if (!(sisusb = usb_get_intfdata(interface))) {
2565 up(&disconnect_sem); 2526 mutex_unlock(&disconnect_mutex);
2566 return -ENODEV; 2527 return -ENODEV;
2567 } 2528 }
2568 2529
2569 down(&sisusb->lock); 2530 mutex_lock(&sisusb->lock);
2570 2531
2571 if (!sisusb->present || !sisusb->ready) { 2532 if (!sisusb->present || !sisusb->ready) {
2572 up(&sisusb->lock); 2533 mutex_unlock(&sisusb->lock);
2573 up(&disconnect_sem); 2534 mutex_unlock(&disconnect_mutex);
2574 return -ENODEV; 2535 return -ENODEV;
2575 } 2536 }
2576 2537
2577 if (sisusb->isopen) { 2538 if (sisusb->isopen) {
2578 up(&sisusb->lock); 2539 mutex_unlock(&sisusb->lock);
2579 up(&disconnect_sem); 2540 mutex_unlock(&disconnect_mutex);
2580 return -EBUSY; 2541 return -EBUSY;
2581 } 2542 }
2582 2543
2583 if (!sisusb->devinit) { 2544 if (!sisusb->devinit) {
2584 if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH) { 2545 if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH) {
2585 if (sisusb_init_gfxdevice(sisusb, 0)) { 2546 if (sisusb_init_gfxdevice(sisusb, 0)) {
2586 up(&sisusb->lock); 2547 mutex_unlock(&sisusb->lock);
2587 up(&disconnect_sem); 2548 mutex_unlock(&disconnect_mutex);
2588 printk(KERN_ERR 2549 printk(KERN_ERR
2589 "sisusbvga[%d]: Failed to initialize " 2550 "sisusbvga[%d]: Failed to initialize "
2590 "device\n", 2551 "device\n",
@@ -2592,8 +2553,8 @@ sisusb_open(struct inode *inode, struct file *file)
2592 return -EIO; 2553 return -EIO;
2593 } 2554 }
2594 } else { 2555 } else {
2595 up(&sisusb->lock); 2556 mutex_unlock(&sisusb->lock);
2596 up(&disconnect_sem); 2557 mutex_unlock(&disconnect_mutex);
2597 printk(KERN_ERR 2558 printk(KERN_ERR
2598 "sisusbvga[%d]: Device not attached to " 2559 "sisusbvga[%d]: Device not attached to "
2599 "USB 2.0 hub\n", 2560 "USB 2.0 hub\n",
@@ -2609,9 +2570,9 @@ sisusb_open(struct inode *inode, struct file *file)
2609 2570
2610 file->private_data = sisusb; 2571 file->private_data = sisusb;
2611 2572
2612 up(&sisusb->lock); 2573 mutex_unlock(&sisusb->lock);
2613 2574
2614 up(&disconnect_sem); 2575 mutex_unlock(&disconnect_mutex);
2615 2576
2616 return 0; 2577 return 0;
2617} 2578}
@@ -2642,14 +2603,14 @@ sisusb_release(struct inode *inode, struct file *file)
2642 struct sisusb_usb_data *sisusb; 2603 struct sisusb_usb_data *sisusb;
2643 int myminor; 2604 int myminor;
2644 2605
2645 down(&disconnect_sem); 2606 mutex_lock(&disconnect_mutex);
2646 2607
2647 if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) { 2608 if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) {
2648 up(&disconnect_sem); 2609 mutex_unlock(&disconnect_mutex);
2649 return -ENODEV; 2610 return -ENODEV;
2650 } 2611 }
2651 2612
2652 down(&sisusb->lock); 2613 mutex_lock(&sisusb->lock);
2653 2614
2654 if (sisusb->present) { 2615 if (sisusb->present) {
2655 /* Wait for all URBs to finish if device still present */ 2616 /* Wait for all URBs to finish if device still present */
@@ -2662,12 +2623,12 @@ sisusb_release(struct inode *inode, struct file *file)
2662 sisusb->isopen = 0; 2623 sisusb->isopen = 0;
2663 file->private_data = NULL; 2624 file->private_data = NULL;
2664 2625
2665 up(&sisusb->lock); 2626 mutex_unlock(&sisusb->lock);
2666 2627
2667 /* decrement the usage count on our device */ 2628 /* decrement the usage count on our device */
2668 kref_put(&sisusb->kref, sisusb_delete); 2629 kref_put(&sisusb->kref, sisusb_delete);
2669 2630
2670 up(&disconnect_sem); 2631 mutex_unlock(&disconnect_mutex);
2671 2632
2672 return 0; 2633 return 0;
2673} 2634}
@@ -2685,11 +2646,11 @@ sisusb_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
2685 if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) 2646 if (!(sisusb = (struct sisusb_usb_data *)file->private_data))
2686 return -ENODEV; 2647 return -ENODEV;
2687 2648
2688 down(&sisusb->lock); 2649 mutex_lock(&sisusb->lock);
2689 2650
2690 /* Sanity check */ 2651 /* Sanity check */
2691 if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) { 2652 if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) {
2692 up(&sisusb->lock); 2653 mutex_unlock(&sisusb->lock);
2693 return -ENODEV; 2654 return -ENODEV;
2694 } 2655 }
2695 2656
@@ -2784,7 +2745,7 @@ sisusb_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
2784 (*ppos) <= SISUSB_PCI_PSEUDO_PCIBASE + 0x5c) { 2745 (*ppos) <= SISUSB_PCI_PSEUDO_PCIBASE + 0x5c) {
2785 2746
2786 if (count != 4) { 2747 if (count != 4) {
2787 up(&sisusb->lock); 2748 mutex_unlock(&sisusb->lock);
2788 return -EINVAL; 2749 return -EINVAL;
2789 } 2750 }
2790 2751
@@ -2808,7 +2769,7 @@ sisusb_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
2808 2769
2809 (*ppos) += bytes_read; 2770 (*ppos) += bytes_read;
2810 2771
2811 up(&sisusb->lock); 2772 mutex_unlock(&sisusb->lock);
2812 2773
2813 return errno ? errno : bytes_read; 2774 return errno ? errno : bytes_read;
2814} 2775}
@@ -2827,11 +2788,11 @@ sisusb_write(struct file *file, const char __user *buffer, size_t count,
2827 if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) 2788 if (!(sisusb = (struct sisusb_usb_data *)file->private_data))
2828 return -ENODEV; 2789 return -ENODEV;
2829 2790
2830 down(&sisusb->lock); 2791 mutex_lock(&sisusb->lock);
2831 2792
2832 /* Sanity check */ 2793 /* Sanity check */
2833 if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) { 2794 if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) {
2834 up(&sisusb->lock); 2795 mutex_unlock(&sisusb->lock);
2835 return -ENODEV; 2796 return -ENODEV;
2836 } 2797 }
2837 2798
@@ -2930,7 +2891,7 @@ sisusb_write(struct file *file, const char __user *buffer, size_t count,
2930 (*ppos) <= SISUSB_PCI_PSEUDO_PCIBASE + SISUSB_PCI_PCONFSIZE) { 2891 (*ppos) <= SISUSB_PCI_PSEUDO_PCIBASE + SISUSB_PCI_PCONFSIZE) {
2931 2892
2932 if (count != 4) { 2893 if (count != 4) {
2933 up(&sisusb->lock); 2894 mutex_unlock(&sisusb->lock);
2934 return -EINVAL; 2895 return -EINVAL;
2935 } 2896 }
2936 2897
@@ -2956,7 +2917,7 @@ sisusb_write(struct file *file, const char __user *buffer, size_t count,
2956 2917
2957 (*ppos) += bytes_written; 2918 (*ppos) += bytes_written;
2958 2919
2959 up(&sisusb->lock); 2920 mutex_unlock(&sisusb->lock);
2960 2921
2961 return errno ? errno : bytes_written; 2922 return errno ? errno : bytes_written;
2962} 2923}
@@ -2970,11 +2931,11 @@ sisusb_lseek(struct file *file, loff_t offset, int orig)
2970 if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) 2931 if (!(sisusb = (struct sisusb_usb_data *)file->private_data))
2971 return -ENODEV; 2932 return -ENODEV;
2972 2933
2973 down(&sisusb->lock); 2934 mutex_lock(&sisusb->lock);
2974 2935
2975 /* Sanity check */ 2936 /* Sanity check */
2976 if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) { 2937 if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) {
2977 up(&sisusb->lock); 2938 mutex_unlock(&sisusb->lock);
2978 return -ENODEV; 2939 return -ENODEV;
2979 } 2940 }
2980 2941
@@ -2994,7 +2955,7 @@ sisusb_lseek(struct file *file, loff_t offset, int orig)
2994 ret = -EINVAL; 2955 ret = -EINVAL;
2995 } 2956 }
2996 2957
2997 up(&sisusb->lock); 2958 mutex_unlock(&sisusb->lock);
2998 return ret; 2959 return ret;
2999} 2960}
3000 2961
@@ -3136,7 +3097,7 @@ sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
3136 if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) 3097 if (!(sisusb = (struct sisusb_usb_data *)file->private_data))
3137 return -ENODEV; 3098 return -ENODEV;
3138 3099
3139 down(&sisusb->lock); 3100 mutex_lock(&sisusb->lock);
3140 3101
3141 /* Sanity check */ 3102 /* Sanity check */
3142 if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) { 3103 if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) {
@@ -3193,7 +3154,7 @@ sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
3193 } 3154 }
3194 3155
3195err_out: 3156err_out:
3196 up(&sisusb->lock); 3157 mutex_unlock(&sisusb->lock);
3197 return retval; 3158 return retval;
3198} 3159}
3199 3160
@@ -3258,7 +3219,7 @@ static int sisusb_probe(struct usb_interface *intf,
3258 } 3219 }
3259 kref_init(&sisusb->kref); 3220 kref_init(&sisusb->kref);
3260 3221
3261 init_MUTEX(&(sisusb->lock)); 3222 mutex_init(&(sisusb->lock));
3262 3223
3263 /* Register device */ 3224 /* Register device */
3264 if ((retval = usb_register_dev(intf, &usb_sisusb_class))) { 3225 if ((retval = usb_register_dev(intf, &usb_sisusb_class))) {
@@ -3429,9 +3390,9 @@ static void sisusb_disconnect(struct usb_interface *intf)
3429 * protect all other routines from the disconnect 3390 * protect all other routines from the disconnect
3430 * case, not the other way round. 3391 * case, not the other way round.
3431 */ 3392 */
3432 down(&disconnect_sem); 3393 mutex_lock(&disconnect_mutex);
3433 3394
3434 down(&sisusb->lock); 3395 mutex_lock(&sisusb->lock);
3435 3396
3436 /* Wait for all URBs to complete and kill them in case (MUST do) */ 3397 /* Wait for all URBs to complete and kill them in case (MUST do) */
3437 if (!sisusb_wait_all_out_complete(sisusb)) 3398 if (!sisusb_wait_all_out_complete(sisusb))
@@ -3462,12 +3423,12 @@ static void sisusb_disconnect(struct usb_interface *intf)
3462 sisusb->present = 0; 3423 sisusb->present = 0;
3463 sisusb->ready = 0; 3424 sisusb->ready = 0;
3464 3425
3465 up(&sisusb->lock); 3426 mutex_unlock(&sisusb->lock);
3466 3427
3467 /* decrement our usage count */ 3428 /* decrement our usage count */
3468 kref_put(&sisusb->kref, sisusb_delete); 3429 kref_put(&sisusb->kref, sisusb_delete);
3469 3430
3470 up(&disconnect_sem); 3431 mutex_unlock(&disconnect_mutex);
3471 3432
3472 printk(KERN_INFO "sisusbvga[%d]: Disconnected\n", minor); 3433 printk(KERN_INFO "sisusbvga[%d]: Disconnected\n", minor);
3473} 3434}
diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h
index a716825d1f9b..8e1120a64806 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.h
+++ b/drivers/usb/misc/sisusbvga/sisusb.h
@@ -41,6 +41,8 @@
41#define SISUSB_NEW_CONFIG_COMPAT 41#define SISUSB_NEW_CONFIG_COMPAT
42#endif 42#endif
43 43
44#include <linux/mutex.h>
45
44/* For older kernels, support for text consoles is by default 46/* For older kernels, support for text consoles is by default
45 * off. To ensable text console support, change the following: 47 * off. To ensable text console support, change the following:
46 */ 48 */
@@ -60,11 +62,9 @@
60#define INCL_SISUSB_CON 1 62#define INCL_SISUSB_CON 1
61#endif 63#endif
62 64
63#ifdef INCL_SISUSB_CON
64#include <linux/console.h> 65#include <linux/console.h>
65#include <linux/vt_kern.h> 66#include <linux/vt_kern.h>
66#include "sisusb_struct.h" 67#include "sisusb_struct.h"
67#endif
68 68
69/* USB related */ 69/* USB related */
70 70
@@ -116,7 +116,7 @@ struct sisusb_usb_data {
116 struct usb_interface *interface; 116 struct usb_interface *interface;
117 struct kref kref; 117 struct kref kref;
118 wait_queue_head_t wait_q; /* for syncind and timeouts */ 118 wait_queue_head_t wait_q; /* for syncind and timeouts */
119 struct semaphore lock; /* general race avoidance */ 119 struct mutex lock; /* general race avoidance */
120 unsigned int ifnum; /* interface number of the USB device */ 120 unsigned int ifnum; /* interface number of the USB device */
121 int minor; /* minor (for logging clarity) */ 121 int minor; /* minor (for logging clarity) */
122 int isopen; /* !=0 if open */ 122 int isopen; /* !=0 if open */
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index be5c1a25ae21..fb48feca8353 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -48,6 +48,7 @@
48 */ 48 */
49 49
50#include <linux/config.h> 50#include <linux/config.h>
51#include <linux/mutex.h>
51#include <linux/module.h> 52#include <linux/module.h>
52#include <linux/kernel.h> 53#include <linux/kernel.h>
53#include <linux/signal.h> 54#include <linux/signal.h>
@@ -69,27 +70,9 @@
69#include <linux/vmalloc.h> 70#include <linux/vmalloc.h>
70 71
71#include "sisusb.h" 72#include "sisusb.h"
73#include "sisusb_init.h"
72 74
73#ifdef INCL_SISUSB_CON 75#ifdef INCL_SISUSB_CON
74extern int sisusb_setreg(struct sisusb_usb_data *, int, u8);
75extern int sisusb_getreg(struct sisusb_usb_data *, int, u8 *);
76extern int sisusb_setidxreg(struct sisusb_usb_data *, int, u8, u8);
77extern int sisusb_getidxreg(struct sisusb_usb_data *, int, u8, u8 *);
78extern int sisusb_setidxregor(struct sisusb_usb_data *, int, u8, u8);
79extern int sisusb_setidxregand(struct sisusb_usb_data *, int, u8, u8);
80extern int sisusb_setidxregandor(struct sisusb_usb_data *, int, u8, u8, u8);
81
82extern int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data);
83extern int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data);
84extern int sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data);
85extern int sisusb_readw(struct sisusb_usb_data *sisusb, u32 adr, u16 *data);
86extern int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src,
87 u32 dest, int length, size_t *bytes_written);
88
89extern void sisusb_delete(struct kref *kref);
90extern int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init);
91
92extern int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
93 76
94#define sisusbcon_writew(val, addr) (*(addr) = (val)) 77#define sisusbcon_writew(val, addr) (*(addr) = (val))
95#define sisusbcon_readw(addr) (*(addr)) 78#define sisusbcon_readw(addr) (*(addr))
@@ -102,8 +85,6 @@ static struct sisusb_usb_data *mysisusbs[MAX_NR_CONSOLES];
102/* Forward declaration */ 85/* Forward declaration */
103static const struct consw sisusb_con; 86static const struct consw sisusb_con;
104 87
105extern struct semaphore disconnect_sem;
106
107static inline void 88static inline void
108sisusbcon_memsetw(u16 *s, u16 c, unsigned int count) 89sisusbcon_memsetw(u16 *s, u16 c, unsigned int count)
109{ 90{
@@ -194,11 +175,11 @@ sisusb_get_sisusb_lock_and_check(unsigned short console)
194 if (!(sisusb = sisusb_get_sisusb(console))) 175 if (!(sisusb = sisusb_get_sisusb(console)))
195 return NULL; 176 return NULL;
196 177
197 down(&sisusb->lock); 178 mutex_lock(&sisusb->lock);
198 179
199 if (!sisusb_sisusb_valid(sisusb) || 180 if (!sisusb_sisusb_valid(sisusb) ||
200 !sisusb->havethisconsole[console]) { 181 !sisusb->havethisconsole[console]) {
201 up(&sisusb->lock); 182 mutex_unlock(&sisusb->lock);
202 return NULL; 183 return NULL;
203 } 184 }
204 185
@@ -236,18 +217,18 @@ sisusbcon_init(struct vc_data *c, int init)
236 * are set up/restored. 217 * are set up/restored.
237 */ 218 */
238 219
239 down(&disconnect_sem); 220 mutex_lock(&disconnect_mutex);
240 221
241 if (!(sisusb = sisusb_get_sisusb(c->vc_num))) { 222 if (!(sisusb = sisusb_get_sisusb(c->vc_num))) {
242 up(&disconnect_sem); 223 mutex_unlock(&disconnect_mutex);
243 return; 224 return;
244 } 225 }
245 226
246 down(&sisusb->lock); 227 mutex_lock(&sisusb->lock);
247 228
248 if (!sisusb_sisusb_valid(sisusb)) { 229 if (!sisusb_sisusb_valid(sisusb)) {
249 up(&sisusb->lock); 230 mutex_unlock(&sisusb->lock);
250 up(&disconnect_sem); 231 mutex_unlock(&disconnect_mutex);
251 return; 232 return;
252 } 233 }
253 234
@@ -284,9 +265,9 @@ sisusbcon_init(struct vc_data *c, int init)
284 if (!*c->vc_uni_pagedir_loc) 265 if (!*c->vc_uni_pagedir_loc)
285 con_set_default_unimap(c); 266 con_set_default_unimap(c);
286 267
287 up(&sisusb->lock); 268 mutex_unlock(&sisusb->lock);
288 269
289 up(&disconnect_sem); 270 mutex_unlock(&disconnect_mutex);
290 271
291 if (init) { 272 if (init) {
292 c->vc_cols = cols; 273 c->vc_cols = cols;
@@ -306,14 +287,14 @@ sisusbcon_deinit(struct vc_data *c)
306 * and others, ie not under our control. 287 * and others, ie not under our control.
307 */ 288 */
308 289
309 down(&disconnect_sem); 290 mutex_lock(&disconnect_mutex);
310 291
311 if (!(sisusb = sisusb_get_sisusb(c->vc_num))) { 292 if (!(sisusb = sisusb_get_sisusb(c->vc_num))) {
312 up(&disconnect_sem); 293 mutex_unlock(&disconnect_mutex);
313 return; 294 return;
314 } 295 }
315 296
316 down(&sisusb->lock); 297 mutex_lock(&sisusb->lock);
317 298
318 /* Clear ourselves in mysisusbs */ 299 /* Clear ourselves in mysisusbs */
319 mysisusbs[c->vc_num] = NULL; 300 mysisusbs[c->vc_num] = NULL;
@@ -332,12 +313,12 @@ sisusbcon_deinit(struct vc_data *c)
332 } 313 }
333 } 314 }
334 315
335 up(&sisusb->lock); 316 mutex_unlock(&sisusb->lock);
336 317
337 /* decrement the usage count on our sisusb */ 318 /* decrement the usage count on our sisusb */
338 kref_put(&sisusb->kref, sisusb_delete); 319 kref_put(&sisusb->kref, sisusb_delete);
339 320
340 up(&disconnect_sem); 321 mutex_unlock(&disconnect_mutex);
341} 322}
342 323
343/* interface routine */ 324/* interface routine */
@@ -417,7 +398,7 @@ sisusbcon_putc(struct vc_data *c, int ch, int y, int x)
417#endif 398#endif
418 399
419 if (sisusb_is_inactive(c, sisusb)) { 400 if (sisusb_is_inactive(c, sisusb)) {
420 up(&sisusb->lock); 401 mutex_unlock(&sisusb->lock);
421 return; 402 return;
422 } 403 }
423 404
@@ -425,7 +406,7 @@ sisusbcon_putc(struct vc_data *c, int ch, int y, int x)
425 sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), 406 sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y),
426 (u32)SISUSB_HADDR(x, y), 2, &written); 407 (u32)SISUSB_HADDR(x, y), 2, &written);
427 408
428 up(&sisusb->lock); 409 mutex_unlock(&sisusb->lock);
429} 410}
430 411
431/* Interface routine */ 412/* Interface routine */
@@ -453,14 +434,14 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s,
453 sisusbcon_writew(sisusbcon_readw(s++), dest++); 434 sisusbcon_writew(sisusbcon_readw(s++), dest++);
454 435
455 if (sisusb_is_inactive(c, sisusb)) { 436 if (sisusb_is_inactive(c, sisusb)) {
456 up(&sisusb->lock); 437 mutex_unlock(&sisusb->lock);
457 return; 438 return;
458 } 439 }
459 440
460 sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), 441 sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y),
461 (u32)SISUSB_HADDR(x, y), count * 2, &written); 442 (u32)SISUSB_HADDR(x, y), count * 2, &written);
462 443
463 up(&sisusb->lock); 444 mutex_unlock(&sisusb->lock);
464} 445}
465 446
466/* Interface routine */ 447/* Interface routine */
@@ -504,7 +485,7 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width)
504 } 485 }
505 486
506 if (sisusb_is_inactive(c, sisusb)) { 487 if (sisusb_is_inactive(c, sisusb)) {
507 up(&sisusb->lock); 488 mutex_unlock(&sisusb->lock);
508 return; 489 return;
509 } 490 }
510 491
@@ -514,7 +495,7 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width)
514 sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(x, y), 495 sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(x, y),
515 (u32)SISUSB_HADDR(x, y), length, &written); 496 (u32)SISUSB_HADDR(x, y), length, &written);
516 497
517 up(&sisusb->lock); 498 mutex_unlock(&sisusb->lock);
518} 499}
519 500
520/* Interface routine */ 501/* Interface routine */
@@ -576,7 +557,7 @@ sisusbcon_bmove(struct vc_data *c, int sy, int sx,
576#endif 557#endif
577 558
578 if (sisusb_is_inactive(c, sisusb)) { 559 if (sisusb_is_inactive(c, sisusb)) {
579 up(&sisusb->lock); 560 mutex_unlock(&sisusb->lock);
580 return; 561 return;
581 } 562 }
582 563
@@ -586,7 +567,7 @@ sisusbcon_bmove(struct vc_data *c, int sy, int sx,
586 sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(dx, dy), 567 sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(dx, dy),
587 (u32)SISUSB_HADDR(dx, dy), length, &written); 568 (u32)SISUSB_HADDR(dx, dy), length, &written);
588 569
589 up(&sisusb->lock); 570 mutex_unlock(&sisusb->lock);
590} 571}
591 572
592/* interface routine */ 573/* interface routine */
@@ -609,7 +590,7 @@ sisusbcon_switch(struct vc_data *c)
609 590
610 /* Don't write to screen if in gfx mode */ 591 /* Don't write to screen if in gfx mode */
611 if (sisusb_is_inactive(c, sisusb)) { 592 if (sisusb_is_inactive(c, sisusb)) {
612 up(&sisusb->lock); 593 mutex_unlock(&sisusb->lock);
613 return 0; 594 return 0;
614 } 595 }
615 596
@@ -618,7 +599,7 @@ sisusbcon_switch(struct vc_data *c)
618 * as origin. 599 * as origin.
619 */ 600 */
620 if (c->vc_origin == (unsigned long)c->vc_screenbuf) { 601 if (c->vc_origin == (unsigned long)c->vc_screenbuf) {
621 up(&sisusb->lock); 602 mutex_unlock(&sisusb->lock);
622 printk(KERN_DEBUG "sisusb: ASSERT ORIGIN != SCREENBUF!\n"); 603 printk(KERN_DEBUG "sisusb: ASSERT ORIGIN != SCREENBUF!\n");
623 return 0; 604 return 0;
624 } 605 }
@@ -635,7 +616,7 @@ sisusbcon_switch(struct vc_data *c)
635 (u32)SISUSB_HADDR(0, 0), 616 (u32)SISUSB_HADDR(0, 0),
636 length, &written); 617 length, &written);
637 618
638 up(&sisusb->lock); 619 mutex_unlock(&sisusb->lock);
639 620
640 return 0; 621 return 0;
641} 622}
@@ -657,7 +638,7 @@ sisusbcon_save_screen(struct vc_data *c)
657 /* sisusb->lock is down */ 638 /* sisusb->lock is down */
658 639
659 if (sisusb_is_inactive(c, sisusb)) { 640 if (sisusb_is_inactive(c, sisusb)) {
660 up(&sisusb->lock); 641 mutex_unlock(&sisusb->lock);
661 return; 642 return;
662 } 643 }
663 644
@@ -669,7 +650,7 @@ sisusbcon_save_screen(struct vc_data *c)
669 sisusbcon_memcpyw((u16 *)c->vc_screenbuf, (u16 *)c->vc_origin, 650 sisusbcon_memcpyw((u16 *)c->vc_screenbuf, (u16 *)c->vc_origin,
670 length); 651 length);
671 652
672 up(&sisusb->lock); 653 mutex_unlock(&sisusb->lock);
673} 654}
674 655
675/* interface routine */ 656/* interface routine */
@@ -690,7 +671,7 @@ sisusbcon_set_palette(struct vc_data *c, unsigned char *table)
690 /* sisusb->lock is down */ 671 /* sisusb->lock is down */
691 672
692 if (sisusb_is_inactive(c, sisusb)) { 673 if (sisusb_is_inactive(c, sisusb)) {
693 up(&sisusb->lock); 674 mutex_unlock(&sisusb->lock);
694 return -EINVAL; 675 return -EINVAL;
695 } 676 }
696 677
@@ -705,7 +686,7 @@ sisusbcon_set_palette(struct vc_data *c, unsigned char *table)
705 break; 686 break;
706 } 687 }
707 688
708 up(&sisusb->lock); 689 mutex_unlock(&sisusb->lock);
709 690
710 return 0; 691 return 0;
711} 692}
@@ -728,7 +709,7 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch)
728 sisusb->is_gfx = blank ? 1 : 0; 709 sisusb->is_gfx = blank ? 1 : 0;
729 710
730 if (sisusb_is_inactive(c, sisusb)) { 711 if (sisusb_is_inactive(c, sisusb)) {
731 up(&sisusb->lock); 712 mutex_unlock(&sisusb->lock);
732 return 0; 713 return 0;
733 } 714 }
734 715
@@ -777,7 +758,7 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch)
777 cr63 = 0x40; 758 cr63 = 0x40;
778 break; 759 break;
779 default: 760 default:
780 up(&sisusb->lock); 761 mutex_unlock(&sisusb->lock);
781 return -EINVAL; 762 return -EINVAL;
782 } 763 }
783 764
@@ -788,7 +769,7 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch)
788 769
789 } 770 }
790 771
791 up(&sisusb->lock); 772 mutex_unlock(&sisusb->lock);
792 773
793 return ret; 774 return ret;
794} 775}
@@ -809,7 +790,7 @@ sisusbcon_scrolldelta(struct vc_data *c, int lines)
809 /* sisusb->lock is down */ 790 /* sisusb->lock is down */
810 791
811 if (sisusb_is_inactive(c, sisusb)) { 792 if (sisusb_is_inactive(c, sisusb)) {
812 up(&sisusb->lock); 793 mutex_unlock(&sisusb->lock);
813 return 0; 794 return 0;
814 } 795 }
815 796
@@ -849,7 +830,7 @@ sisusbcon_scrolldelta(struct vc_data *c, int lines)
849 830
850 sisusbcon_set_start_address(sisusb, c); 831 sisusbcon_set_start_address(sisusb, c);
851 832
852 up(&sisusb->lock); 833 mutex_unlock(&sisusb->lock);
853 834
854 return 1; 835 return 1;
855} 836}
@@ -867,7 +848,7 @@ sisusbcon_cursor(struct vc_data *c, int mode)
867 /* sisusb->lock is down */ 848 /* sisusb->lock is down */
868 849
869 if (sisusb_is_inactive(c, sisusb)) { 850 if (sisusb_is_inactive(c, sisusb)) {
870 up(&sisusb->lock); 851 mutex_unlock(&sisusb->lock);
871 return; 852 return;
872 } 853 }
873 854
@@ -879,7 +860,7 @@ sisusbcon_cursor(struct vc_data *c, int mode)
879 if (mode == CM_ERASE) { 860 if (mode == CM_ERASE) {
880 sisusb_setidxregor(sisusb, SISCR, 0x0a, 0x20); 861 sisusb_setidxregor(sisusb, SISCR, 0x0a, 0x20);
881 sisusb->sisusb_cursor_size_to = -1; 862 sisusb->sisusb_cursor_size_to = -1;
882 up(&sisusb->lock); 863 mutex_unlock(&sisusb->lock);
883 return; 864 return;
884 } 865 }
885 866
@@ -919,7 +900,7 @@ sisusbcon_cursor(struct vc_data *c, int mode)
919 sisusb->sisusb_cursor_size_to = to; 900 sisusb->sisusb_cursor_size_to = to;
920 } 901 }
921 902
922 up(&sisusb->lock); 903 mutex_unlock(&sisusb->lock);
923} 904}
924 905
925static int 906static int
@@ -961,7 +942,7 @@ sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb,
961 sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t), 942 sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t),
962 (u32)SISUSB_HADDR(0, t), length, &written); 943 (u32)SISUSB_HADDR(0, t), length, &written);
963 944
964 up(&sisusb->lock); 945 mutex_unlock(&sisusb->lock);
965 946
966 return 1; 947 return 1;
967} 948}
@@ -994,7 +975,7 @@ sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
994 /* sisusb->lock is down */ 975 /* sisusb->lock is down */
995 976
996 if (sisusb_is_inactive(c, sisusb)) { 977 if (sisusb_is_inactive(c, sisusb)) {
997 up(&sisusb->lock); 978 mutex_unlock(&sisusb->lock);
998 return 0; 979 return 0;
999 } 980 }
1000 981
@@ -1084,7 +1065,7 @@ sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
1084 1065
1085 c->vc_pos = c->vc_pos - oldorigin + c->vc_origin; 1066 c->vc_pos = c->vc_pos - oldorigin + c->vc_origin;
1086 1067
1087 up(&sisusb->lock); 1068 mutex_unlock(&sisusb->lock);
1088 1069
1089 return 1; 1070 return 1;
1090} 1071}
@@ -1106,7 +1087,7 @@ sisusbcon_set_origin(struct vc_data *c)
1106 /* sisusb->lock is down */ 1087 /* sisusb->lock is down */
1107 1088
1108 if (sisusb_is_inactive(c, sisusb) || sisusb->con_blanked) { 1089 if (sisusb_is_inactive(c, sisusb) || sisusb->con_blanked) {
1109 up(&sisusb->lock); 1090 mutex_unlock(&sisusb->lock);
1110 return 0; 1091 return 0;
1111 } 1092 }
1112 1093
@@ -1116,7 +1097,7 @@ sisusbcon_set_origin(struct vc_data *c)
1116 1097
1117 sisusb->con_rolled_over = 0; 1098 sisusb->con_rolled_over = 0;
1118 1099
1119 up(&sisusb->lock); 1100 mutex_unlock(&sisusb->lock);
1120 1101
1121 return 1; 1102 return 1;
1122} 1103}
@@ -1133,7 +1114,7 @@ sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows)
1133 1114
1134 fh = sisusb->current_font_height; 1115 fh = sisusb->current_font_height;
1135 1116
1136 up(&sisusb->lock); 1117 mutex_unlock(&sisusb->lock);
1137 1118
1138 /* We are quite unflexible as regards resizing. The vt code 1119 /* We are quite unflexible as regards resizing. The vt code
1139 * handles sizes where the line length isn't equal the pitch 1120 * handles sizes where the line length isn't equal the pitch
@@ -1167,7 +1148,7 @@ sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot,
1167 1148
1168 if ((slot != 0 && slot != 2) || !fh) { 1149 if ((slot != 0 && slot != 2) || !fh) {
1169 if (uplock) 1150 if (uplock)
1170 up(&sisusb->lock); 1151 mutex_unlock(&sisusb->lock);
1171 return -EINVAL; 1152 return -EINVAL;
1172 } 1153 }
1173 1154
@@ -1327,7 +1308,7 @@ sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot,
1327 } 1308 }
1328 1309
1329 if (uplock) 1310 if (uplock)
1330 up(&sisusb->lock); 1311 mutex_unlock(&sisusb->lock);
1331 1312
1332 if (dorecalc && c) { 1313 if (dorecalc && c) {
1333 int i, rows = c->vc_scan_lines / fh; 1314 int i, rows = c->vc_scan_lines / fh;
@@ -1351,7 +1332,7 @@ sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot,
1351 1332
1352font_op_error: 1333font_op_error:
1353 if (uplock) 1334 if (uplock)
1354 up(&sisusb->lock); 1335 mutex_unlock(&sisusb->lock);
1355 1336
1356 return -EIO; 1337 return -EIO;
1357} 1338}
@@ -1417,19 +1398,19 @@ sisusbcon_font_get(struct vc_data *c, struct console_font *font)
1417 font->charcount = 256; 1398 font->charcount = 256;
1418 1399
1419 if (!font->data) { 1400 if (!font->data) {
1420 up(&sisusb->lock); 1401 mutex_unlock(&sisusb->lock);
1421 return 0; 1402 return 0;
1422 } 1403 }
1423 1404
1424 if (!sisusb->font_backup) { 1405 if (!sisusb->font_backup) {
1425 up(&sisusb->lock); 1406 mutex_unlock(&sisusb->lock);
1426 return -ENODEV; 1407 return -ENODEV;
1427 } 1408 }
1428 1409
1429 /* Copy 256 chars only, like vgacon */ 1410 /* Copy 256 chars only, like vgacon */
1430 memcpy(font->data, sisusb->font_backup, 256 * 32); 1411 memcpy(font->data, sisusb->font_backup, 256 * 32);
1431 1412
1432 up(&sisusb->lock); 1413 mutex_unlock(&sisusb->lock);
1433 1414
1434 return 0; 1415 return 0;
1435} 1416}
@@ -1486,7 +1467,7 @@ static int sisusbdummycon_dummy(void)
1486 1467
1487#define SISUSBCONDUMMY (void *)sisusbdummycon_dummy 1468#define SISUSBCONDUMMY (void *)sisusbdummycon_dummy
1488 1469
1489const struct consw sisusb_dummy_con = { 1470static const struct consw sisusb_dummy_con = {
1490 .owner = THIS_MODULE, 1471 .owner = THIS_MODULE,
1491 .con_startup = sisusbdummycon_startup, 1472 .con_startup = sisusbdummycon_startup,
1492 .con_init = sisusbdummycon_init, 1473 .con_init = sisusbdummycon_init,
@@ -1512,14 +1493,14 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
1512{ 1493{
1513 int i, ret, minor = sisusb->minor; 1494 int i, ret, minor = sisusb->minor;
1514 1495
1515 down(&disconnect_sem); 1496 mutex_lock(&disconnect_mutex);
1516 1497
1517 down(&sisusb->lock); 1498 mutex_lock(&sisusb->lock);
1518 1499
1519 /* Erm.. that should not happen */ 1500 /* Erm.. that should not happen */
1520 if (sisusb->haveconsole || !sisusb->SiS_Pr) { 1501 if (sisusb->haveconsole || !sisusb->SiS_Pr) {
1521 up(&sisusb->lock); 1502 mutex_unlock(&sisusb->lock);
1522 up(&disconnect_sem); 1503 mutex_unlock(&disconnect_mutex);
1523 return 1; 1504 return 1;
1524 } 1505 }
1525 1506
@@ -1529,15 +1510,15 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
1529 if (first > last || 1510 if (first > last ||
1530 first > MAX_NR_CONSOLES || 1511 first > MAX_NR_CONSOLES ||
1531 last > MAX_NR_CONSOLES) { 1512 last > MAX_NR_CONSOLES) {
1532 up(&sisusb->lock); 1513 mutex_unlock(&sisusb->lock);
1533 up(&disconnect_sem); 1514 mutex_unlock(&disconnect_mutex);
1534 return 1; 1515 return 1;
1535 } 1516 }
1536 1517
1537 /* If gfxcore not initialized or no consoles given, quit graciously */ 1518 /* If gfxcore not initialized or no consoles given, quit graciously */
1538 if (!sisusb->gfxinit || first < 1 || last < 1) { 1519 if (!sisusb->gfxinit || first < 1 || last < 1) {
1539 up(&sisusb->lock); 1520 mutex_unlock(&sisusb->lock);
1540 up(&disconnect_sem); 1521 mutex_unlock(&disconnect_mutex);
1541 return 0; 1522 return 0;
1542 } 1523 }
1543 1524
@@ -1547,8 +1528,8 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
1547 1528
1548 /* Set up text mode (and upload default font) */ 1529 /* Set up text mode (and upload default font) */
1549 if (sisusb_reset_text_mode(sisusb, 1)) { 1530 if (sisusb_reset_text_mode(sisusb, 1)) {
1550 up(&sisusb->lock); 1531 mutex_unlock(&sisusb->lock);
1551 up(&disconnect_sem); 1532 mutex_unlock(&disconnect_mutex);
1552 printk(KERN_ERR 1533 printk(KERN_ERR
1553 "sisusbvga[%d]: Failed to set up text mode\n", 1534 "sisusbvga[%d]: Failed to set up text mode\n",
1554 minor); 1535 minor);
@@ -1571,16 +1552,16 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
1571 1552
1572 /* Allocate screen buffer */ 1553 /* Allocate screen buffer */
1573 if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) { 1554 if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) {
1574 up(&sisusb->lock); 1555 mutex_unlock(&sisusb->lock);
1575 up(&disconnect_sem); 1556 mutex_unlock(&disconnect_mutex);
1576 printk(KERN_ERR 1557 printk(KERN_ERR
1577 "sisusbvga[%d]: Failed to allocate screen buffer\n", 1558 "sisusbvga[%d]: Failed to allocate screen buffer\n",
1578 minor); 1559 minor);
1579 return 1; 1560 return 1;
1580 } 1561 }
1581 1562
1582 up(&sisusb->lock); 1563 mutex_unlock(&sisusb->lock);
1583 up(&disconnect_sem); 1564 mutex_unlock(&disconnect_mutex);
1584 1565
1585 /* Now grab the desired console(s) */ 1566 /* Now grab the desired console(s) */
1586 ret = take_over_console(&sisusb_con, first - 1, last - 1, 0); 1567 ret = take_over_console(&sisusb_con, first - 1, last - 1, 0);
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c
index 044fa4482f9f..968f0d38cff7 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_init.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_init.c
@@ -74,6 +74,7 @@ SiSUSB_InitPtr(struct SiS_Private *SiS_Pr)
74/* HELPER: Get ModeID */ 74/* HELPER: Get ModeID */
75/*********************************************/ 75/*********************************************/
76 76
77#if 0
77unsigned short 78unsigned short
78SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth) 79SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth)
79{ 80{
@@ -157,6 +158,7 @@ SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth)
157 158
158 return ModeIndex; 159 return ModeIndex;
159} 160}
161#endif /* 0 */
160 162
161/*********************************************/ 163/*********************************************/
162/* HELPER: SetReg, GetReg */ 164/* HELPER: SetReg, GetReg */
@@ -233,7 +235,7 @@ SiS_DisplayOn(struct SiS_Private *SiS_Pr)
233/* HELPER: Init Port Addresses */ 235/* HELPER: Init Port Addresses */
234/*********************************************/ 236/*********************************************/
235 237
236void 238static void
237SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr) 239SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr)
238{ 240{
239 SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; 241 SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.h b/drivers/usb/misc/sisusbvga/sisusb_init.h
index 5b11577835c8..f05f83268af4 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_init.h
+++ b/drivers/usb/misc/sisusbvga/sisusb_init.h
@@ -690,7 +690,7 @@ static const struct SiS_CRT1Table SiSUSB_CRT1Table[] =
690 0x41}} /* 0x54 */ 690 0x41}} /* 0x54 */
691}; 691};
692 692
693static struct SiS_VCLKData SiSUSB_VCLKData[] = 693static const struct SiS_VCLKData SiSUSB_VCLKData[] =
694{ 694{
695 { 0x1b,0xe1, 25}, /* 0x00 */ 695 { 0x1b,0xe1, 25}, /* 0x00 */
696 { 0x4e,0xe4, 28}, /* 0x01 */ 696 { 0x4e,0xe4, 28}, /* 0x01 */
@@ -808,8 +808,8 @@ static struct SiS_VCLKData SiSUSB_VCLKData[] =
808 { 0x2b,0xc2, 35} /* 0x71 768@576@60 */ 808 { 0x2b,0xc2, 35} /* 0x71 768@576@60 */
809}; 809};
810 810
811void SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr); 811extern struct mutex disconnect_mutex;
812unsigned short SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth); 812
813int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); 813int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
814int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo); 814int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo);
815 815
@@ -826,5 +826,19 @@ extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port,
826extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, 826extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port,
827 u8 idx, u8 myand); 827 u8 idx, u8 myand);
828 828
829void sisusb_delete(struct kref *kref);
830int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data);
831int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data);
832int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src,
833 u32 dest, int length, size_t *bytes_written);
834int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init);
835int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot,
836 u8 *arg, int cmapsz, int ch512, int dorecalc,
837 struct vc_data *c, int fh, int uplock);
838void sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location);
839int sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last);
840void sisusb_console_exit(struct sisusb_usb_data *sisusb);
841void sisusb_init_concode(void);
842
829#endif 843#endif
830 844
diff --git a/drivers/usb/misc/sisusbvga/sisusb_struct.h b/drivers/usb/misc/sisusbvga/sisusb_struct.h
index 94edd4726c42..f325ecb29a61 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_struct.h
+++ b/drivers/usb/misc/sisusbvga/sisusb_struct.h
@@ -161,7 +161,7 @@ struct SiS_Private
161 const struct SiS_Ext *SiS_EModeIDTable; 161 const struct SiS_Ext *SiS_EModeIDTable;
162 const struct SiS_Ext2 *SiS_RefIndex; 162 const struct SiS_Ext2 *SiS_RefIndex;
163 const struct SiS_CRT1Table *SiS_CRT1Table; 163 const struct SiS_CRT1Table *SiS_CRT1Table;
164 struct SiS_VCLKData *SiS_VCLKData; 164 const struct SiS_VCLKData *SiS_VCLKData;
165 const struct SiS_ModeResInfo *SiS_ModeResInfo; 165 const struct SiS_ModeResInfo *SiS_ModeResInfo;
166}; 166};
167 167
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index ccc5e8238bd8..81ba14c73dc7 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -802,7 +802,9 @@ error:
802 802
803 if (u == urb || !u->dev) 803 if (u == urb || !u->dev)
804 continue; 804 continue;
805 spin_unlock(&ctx->lock);
805 status = usb_unlink_urb (u); 806 status = usb_unlink_urb (u);
807 spin_lock(&ctx->lock);
806 switch (status) { 808 switch (status) {
807 case -EINPROGRESS: 809 case -EINPROGRESS:
808 case -EBUSY: 810 case -EBUSY:
@@ -1335,7 +1337,9 @@ struct iso_context {
1335 unsigned pending; 1337 unsigned pending;
1336 spinlock_t lock; 1338 spinlock_t lock;
1337 struct completion done; 1339 struct completion done;
1340 int submit_error;
1338 unsigned long errors; 1341 unsigned long errors;
1342 unsigned long packet_count;
1339 struct usbtest_dev *dev; 1343 struct usbtest_dev *dev;
1340}; 1344};
1341 1345
@@ -1346,10 +1350,14 @@ static void iso_callback (struct urb *urb, struct pt_regs *regs)
1346 spin_lock(&ctx->lock); 1350 spin_lock(&ctx->lock);
1347 ctx->count--; 1351 ctx->count--;
1348 1352
1353 ctx->packet_count += urb->number_of_packets;
1349 if (urb->error_count > 0) 1354 if (urb->error_count > 0)
1350 ctx->errors += urb->error_count; 1355 ctx->errors += urb->error_count;
1356 else if (urb->status != 0)
1357 ctx->errors += urb->number_of_packets;
1351 1358
1352 if (urb->status == 0 && ctx->count > (ctx->pending - 1)) { 1359 if (urb->status == 0 && ctx->count > (ctx->pending - 1)
1360 && !ctx->submit_error) {
1353 int status = usb_submit_urb (urb, GFP_ATOMIC); 1361 int status = usb_submit_urb (urb, GFP_ATOMIC);
1354 switch (status) { 1362 switch (status) {
1355 case 0: 1363 case 0:
@@ -1360,6 +1368,8 @@ static void iso_callback (struct urb *urb, struct pt_regs *regs)
1360 status); 1368 status);
1361 /* FALLTHROUGH */ 1369 /* FALLTHROUGH */
1362 case -ENODEV: /* disconnected */ 1370 case -ENODEV: /* disconnected */
1371 case -ESHUTDOWN: /* endpoint disabled */
1372 ctx->submit_error = 1;
1363 break; 1373 break;
1364 } 1374 }
1365 } 1375 }
@@ -1369,8 +1379,8 @@ static void iso_callback (struct urb *urb, struct pt_regs *regs)
1369 if (ctx->pending == 0) { 1379 if (ctx->pending == 0) {
1370 if (ctx->errors) 1380 if (ctx->errors)
1371 dev_dbg (&ctx->dev->intf->dev, 1381 dev_dbg (&ctx->dev->intf->dev,
1372 "iso test, %lu errors\n", 1382 "iso test, %lu errors out of %lu\n",
1373 ctx->errors); 1383 ctx->errors, ctx->packet_count);
1374 complete (&ctx->done); 1384 complete (&ctx->done);
1375 } 1385 }
1376done: 1386done:
@@ -1431,15 +1441,14 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param,
1431 struct usb_device *udev; 1441 struct usb_device *udev;
1432 unsigned i; 1442 unsigned i;
1433 unsigned long packets = 0; 1443 unsigned long packets = 0;
1434 int status; 1444 int status = 0;
1435 struct urb *urbs[10]; /* FIXME no limit */ 1445 struct urb *urbs[10]; /* FIXME no limit */
1436 1446
1437 if (param->sglen > 10) 1447 if (param->sglen > 10)
1438 return -EDOM; 1448 return -EDOM;
1439 1449
1450 memset(&context, 0, sizeof context);
1440 context.count = param->iterations * param->sglen; 1451 context.count = param->iterations * param->sglen;
1441 context.pending = param->sglen;
1442 context.errors = 0;
1443 context.dev = dev; 1452 context.dev = dev;
1444 init_completion (&context.done); 1453 init_completion (&context.done);
1445 spin_lock_init (&context.lock); 1454 spin_lock_init (&context.lock);
@@ -1471,6 +1480,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param,
1471 1480
1472 spin_lock_irq (&context.lock); 1481 spin_lock_irq (&context.lock);
1473 for (i = 0; i < param->sglen; i++) { 1482 for (i = 0; i < param->sglen; i++) {
1483 ++context.pending;
1474 status = usb_submit_urb (urbs [i], SLAB_ATOMIC); 1484 status = usb_submit_urb (urbs [i], SLAB_ATOMIC);
1475 if (status < 0) { 1485 if (status < 0) {
1476 ERROR (dev, "submit iso[%d], error %d\n", i, status); 1486 ERROR (dev, "submit iso[%d], error %d\n", i, status);
@@ -1481,12 +1491,26 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param,
1481 1491
1482 simple_free_urb (urbs [i]); 1492 simple_free_urb (urbs [i]);
1483 context.pending--; 1493 context.pending--;
1494 context.submit_error = 1;
1495 break;
1484 } 1496 }
1485 } 1497 }
1486 spin_unlock_irq (&context.lock); 1498 spin_unlock_irq (&context.lock);
1487 1499
1488 wait_for_completion (&context.done); 1500 wait_for_completion (&context.done);
1489 return 0; 1501
1502 /*
1503 * Isochronous transfers are expected to fail sometimes. As an
1504 * arbitrary limit, we will report an error if any submissions
1505 * fail or if the transfer failure rate is > 10%.
1506 */
1507 if (status != 0)
1508 ;
1509 else if (context.submit_error)
1510 status = -EACCES;
1511 else if (context.errors > context.packet_count / 10)
1512 status = -EIO;
1513 return status;
1490 1514
1491fail: 1515fail:
1492 for (i = 0; i < param->sglen; i++) { 1516 for (i = 0; i < param->sglen; i++) {
diff --git a/drivers/usb/mon/mon_dma.c b/drivers/usb/mon/mon_dma.c
index 0a1367b760a0..ddcfc01e77a0 100644
--- a/drivers/usb/mon/mon_dma.c
+++ b/drivers/usb/mon/mon_dma.c
@@ -13,7 +13,10 @@
13#include <linux/usb.h> /* Only needed for declarations in usb_mon.h */ 13#include <linux/usb.h> /* Only needed for declarations in usb_mon.h */
14#include "usb_mon.h" 14#include "usb_mon.h"
15 15
16#ifdef __i386__ /* CONFIG_ARCH_I386 does not exit */ 16/*
17 * PC-compatibles, are, fortunately, sufficiently cache-coherent for this.
18 */
19#if defined(__i386__) || defined(__x86_64__) /* CONFIG_ARCH_I386 doesn't exit */
17#define MON_HAS_UNMAP 1 20#define MON_HAS_UNMAP 1
18 21
19#define phys_to_page(phys) pfn_to_page((phys) >> PAGE_SHIFT) 22#define phys_to_page(phys) pfn_to_page((phys) >> PAGE_SHIFT)
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
index 6ecc27302211..275a66f83058 100644
--- a/drivers/usb/mon/mon_main.c
+++ b/drivers/usb/mon/mon_main.c
@@ -97,6 +97,7 @@ static void mon_submit(struct usb_bus *ubus, struct urb *urb)
97 if (mbus->nreaders == 0) 97 if (mbus->nreaders == 0)
98 goto out_locked; 98 goto out_locked;
99 99
100 mbus->cnt_events++;
100 list_for_each (pos, &mbus->r_list) { 101 list_for_each (pos, &mbus->r_list) {
101 r = list_entry(pos, struct mon_reader, r_link); 102 r = list_entry(pos, struct mon_reader, r_link);
102 r->rnf_submit(r->r_data, urb); 103 r->rnf_submit(r->r_data, urb);
@@ -113,20 +114,32 @@ out_unlocked:
113 114
114/* 115/*
115 */ 116 */
116static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int err) 117static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error)
117{ 118{
118 struct mon_bus *mbus; 119 struct mon_bus *mbus;
120 unsigned long flags;
121 struct list_head *pos;
122 struct mon_reader *r;
119 123
120 mbus = ubus->mon_bus; 124 mbus = ubus->mon_bus;
121 if (mbus == NULL) 125 if (mbus == NULL)
122 goto out_unlocked; 126 goto out_unlocked;
123 127
124 /* 128 spin_lock_irqsave(&mbus->lock, flags);
125 * XXX Capture the error code and the 'E' event. 129 if (mbus->nreaders == 0)
126 */ 130 goto out_locked;
127 131
132 mbus->cnt_events++;
133 list_for_each (pos, &mbus->r_list) {
134 r = list_entry(pos, struct mon_reader, r_link);
135 r->rnf_error(r->r_data, urb, error);
136 }
137
138 spin_unlock_irqrestore(&mbus->lock, flags);
128 return; 139 return;
129 140
141out_locked:
142 spin_unlock_irqrestore(&mbus->lock, flags);
130out_unlocked: 143out_unlocked:
131 return; 144 return;
132} 145}
@@ -152,6 +165,7 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb)
152 } 165 }
153 166
154 spin_lock_irqsave(&mbus->lock, flags); 167 spin_lock_irqsave(&mbus->lock, flags);
168 mbus->cnt_events++;
155 list_for_each (pos, &mbus->r_list) { 169 list_for_each (pos, &mbus->r_list) {
156 r = list_entry(pos, struct mon_reader, r_link); 170 r = list_entry(pos, struct mon_reader, r_link);
157 r->rnf_complete(r->r_data, urb); 171 r->rnf_complete(r->r_data, urb);
@@ -163,7 +177,6 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb)
163 177
164/* 178/*
165 * Stop monitoring. 179 * Stop monitoring.
166 * Obviously this must be well locked, so no need to play with mb's.
167 */ 180 */
168static void mon_stop(struct mon_bus *mbus) 181static void mon_stop(struct mon_bus *mbus)
169{ 182{
diff --git a/drivers/usb/mon/mon_stat.c b/drivers/usb/mon/mon_stat.c
index 6e4b165d070a..1fe01d994a79 100644
--- a/drivers/usb/mon/mon_stat.c
+++ b/drivers/usb/mon/mon_stat.c
@@ -31,8 +31,8 @@ static int mon_stat_open(struct inode *inode, struct file *file)
31 mbus = inode->u.generic_ip; 31 mbus = inode->u.generic_ip;
32 32
33 sp->slen = snprintf(sp->str, STAT_BUF_SIZE, 33 sp->slen = snprintf(sp->str, STAT_BUF_SIZE,
34 "nreaders %d text_lost %u\n", 34 "nreaders %d events %u text_lost %u\n",
35 mbus->nreaders, mbus->cnt_text_lost); 35 mbus->nreaders, mbus->cnt_events, mbus->cnt_text_lost);
36 36
37 file->private_data = sp; 37 file->private_data = sp;
38 return 0; 38 return 0;
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index ac043ec2b8dc..e02c1a30c4cd 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -26,10 +26,13 @@
26 26
27/* 27/*
28 * This limit exists to prevent OOMs when the user process stops reading. 28 * This limit exists to prevent OOMs when the user process stops reading.
29 * If usbmon were available to unprivileged processes, it might be open
30 * to a local DoS. But we have to keep to root in order to prevent
31 * password sniffing from HID devices.
29 */ 32 */
30#define EVENT_MAX 25 33#define EVENT_MAX (2*PAGE_SIZE / sizeof(struct mon_event_text))
31 34
32#define PRINTF_DFL 130 35#define PRINTF_DFL 160
33 36
34struct mon_event_text { 37struct mon_event_text {
35 struct list_head e_link; 38 struct list_head e_link;
@@ -111,7 +114,7 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
111 * number of corner cases, but it seems that the following is 114 * number of corner cases, but it seems that the following is
112 * more or less safe. 115 * more or less safe.
113 * 116 *
114 * We do not even try to look transfer_buffer, because it can 117 * We do not even try to look at transfer_buffer, because it can
115 * contain non-NULL garbage in case the upper level promised to 118 * contain non-NULL garbage in case the upper level promised to
116 * set DMA for the HCD. 119 * set DMA for the HCD.
117 */ 120 */
@@ -179,6 +182,32 @@ static void mon_text_complete(void *data, struct urb *urb)
179 mon_text_event(rp, urb, 'C'); 182 mon_text_event(rp, urb, 'C');
180} 183}
181 184
185static void mon_text_error(void *data, struct urb *urb, int error)
186{
187 struct mon_reader_text *rp = data;
188 struct mon_event_text *ep;
189
190 if (rp->nevents >= EVENT_MAX ||
191 (ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) {
192 rp->r.m_bus->cnt_text_lost++;
193 return;
194 }
195
196 ep->type = 'E';
197 ep->pipe = urb->pipe;
198 ep->id = (unsigned long) urb;
199 ep->tstamp = 0;
200 ep->length = 0;
201 ep->status = error;
202
203 ep->setup_flag = '-';
204 ep->data_flag = 'E';
205
206 rp->nevents++;
207 list_add_tail(&ep->e_link, &rp->e_list);
208 wake_up(&rp->wait);
209}
210
182/* 211/*
183 * Fetch next event from the circular buffer. 212 * Fetch next event from the circular buffer.
184 */ 213 */
@@ -232,6 +261,7 @@ static int mon_text_open(struct inode *inode, struct file *file)
232 rp->r.m_bus = mbus; 261 rp->r.m_bus = mbus;
233 rp->r.r_data = rp; 262 rp->r.r_data = rp;
234 rp->r.rnf_submit = mon_text_submit; 263 rp->r.rnf_submit = mon_text_submit;
264 rp->r.rnf_error = mon_text_error;
235 rp->r.rnf_complete = mon_text_complete; 265 rp->r.rnf_complete = mon_text_complete;
236 266
237 snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum, 267 snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum,
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h
index 8e0613c350cc..33678c24ebee 100644
--- a/drivers/usb/mon/usb_mon.h
+++ b/drivers/usb/mon/usb_mon.h
@@ -27,6 +27,7 @@ struct mon_bus {
27 struct kref ref; /* Under mon_lock */ 27 struct kref ref; /* Under mon_lock */
28 28
29 /* Stats */ 29 /* Stats */
30 unsigned int cnt_events;
30 unsigned int cnt_text_lost; 31 unsigned int cnt_text_lost;
31}; 32};
32 33
@@ -39,6 +40,7 @@ struct mon_reader {
39 void *r_data; /* Use container_of instead? */ 40 void *r_data; /* Use container_of instead? */
40 41
41 void (*rnf_submit)(void *data, struct urb *urb); 42 void (*rnf_submit)(void *data, struct urb *urb);
43 void (*rnf_error)(void *data, struct urb *urb, int error);
42 void (*rnf_complete)(void *data, struct urb *urb); 44 void (*rnf_complete)(void *data, struct urb *urb);
43}; 45};
44 46
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
index 12b599a0b539..37111acec875 100644
--- a/drivers/usb/net/asix.c
+++ b/drivers/usb/net/asix.c
@@ -912,6 +912,10 @@ static const struct usb_device_id products [] = {
912 USB_DEVICE (0x0b95, 0x7720), 912 USB_DEVICE (0x0b95, 0x7720),
913 .driver_info = (unsigned long) &ax88772_info, 913 .driver_info = (unsigned long) &ax88772_info,
914}, { 914}, {
915 // ASIX AX88178 10/100/1000
916 USB_DEVICE (0x0b95, 0x1780),
917 .driver_info = (unsigned long) &ax88772_info,
918}, {
915 // Linksys USB200M Rev 2 919 // Linksys USB200M Rev 2
916 USB_DEVICE (0x13b1, 0x0018), 920 USB_DEVICE (0x13b1, 0x0018),
917 .driver_info = (unsigned long) &ax88772_info, 921 .driver_info = (unsigned long) &ax88772_info,
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c
index 63f1f3ba8e0b..efd195b5912c 100644
--- a/drivers/usb/net/cdc_ether.c
+++ b/drivers/usb/net/cdc_ether.c
@@ -31,7 +31,7 @@
31#include <linux/workqueue.h> 31#include <linux/workqueue.h>
32#include <linux/mii.h> 32#include <linux/mii.h>
33#include <linux/usb.h> 33#include <linux/usb.h>
34#include <linux/usb_cdc.h> 34#include <linux/usb/cdc.h>
35 35
36#include "usbnet.h" 36#include "usbnet.h"
37 37
@@ -455,6 +455,18 @@ static const struct usb_device_id products [] = {
455 .driver_info = 0, 455 .driver_info = 0,
456}, 456},
457 457
458/* Olympus has some models with a Zaurus-compatible option.
459 * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
460 */
461{
462 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
463 | USB_DEVICE_ID_MATCH_DEVICE,
464 .idVendor = 0x07B4,
465 .idProduct = 0x0F02, /* R-1000 */
466 ZAURUS_MASTER_INTERFACE,
467 .driver_info = 0,
468},
469
458/* 470/*
459 * WHITELIST!!! 471 * WHITELIST!!!
460 * 472 *
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
index 7683926a1b6f..ab21f960d255 100644
--- a/drivers/usb/net/pegasus.c
+++ b/drivers/usb/net/pegasus.c
@@ -163,6 +163,8 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
163 163
164 /* using ATOMIC, we'd never wake up if we slept */ 164 /* using ATOMIC, we'd never wake up if we slept */
165 if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { 165 if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
166 if (ret == -ENODEV)
167 netif_device_detach(pegasus->net);
166 if (netif_msg_drv(pegasus)) 168 if (netif_msg_drv(pegasus))
167 dev_err(&pegasus->intf->dev, "%s, status %d\n", 169 dev_err(&pegasus->intf->dev, "%s, status %d\n",
168 __FUNCTION__, ret); 170 __FUNCTION__, ret);
@@ -217,6 +219,8 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
217 set_current_state(TASK_UNINTERRUPTIBLE); 219 set_current_state(TASK_UNINTERRUPTIBLE);
218 220
219 if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { 221 if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
222 if (ret == -ENODEV)
223 netif_device_detach(pegasus->net);
220 if (netif_msg_drv(pegasus)) 224 if (netif_msg_drv(pegasus))
221 dev_err(&pegasus->intf->dev, "%s, status %d\n", 225 dev_err(&pegasus->intf->dev, "%s, status %d\n",
222 __FUNCTION__, ret); 226 __FUNCTION__, ret);
@@ -268,6 +272,8 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
268 set_current_state(TASK_UNINTERRUPTIBLE); 272 set_current_state(TASK_UNINTERRUPTIBLE);
269 273
270 if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { 274 if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
275 if (ret == -ENODEV)
276 netif_device_detach(pegasus->net);
271 if (netif_msg_drv(pegasus)) 277 if (netif_msg_drv(pegasus))
272 dev_err(&pegasus->intf->dev, "%s, status %d\n", 278 dev_err(&pegasus->intf->dev, "%s, status %d\n",
273 __FUNCTION__, ret); 279 __FUNCTION__, ret);
@@ -298,10 +304,13 @@ static int update_eth_regs_async(pegasus_t * pegasus)
298 (char *) &pegasus->dr, 304 (char *) &pegasus->dr,
299 pegasus->eth_regs, 3, ctrl_callback, pegasus); 305 pegasus->eth_regs, 3, ctrl_callback, pegasus);
300 306
301 if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) 307 if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
308 if (ret == -ENODEV)
309 netif_device_detach(pegasus->net);
302 if (netif_msg_drv(pegasus)) 310 if (netif_msg_drv(pegasus))
303 dev_err(&pegasus->intf->dev, "%s, status %d\n", 311 dev_err(&pegasus->intf->dev, "%s, status %d\n",
304 __FUNCTION__, ret); 312 __FUNCTION__, ret);
313 }
305 314
306 return ret; 315 return ret;
307} 316}
@@ -692,7 +701,10 @@ goon:
692 usb_rcvbulkpipe(pegasus->usb, 1), 701 usb_rcvbulkpipe(pegasus->usb, 1),
693 pegasus->rx_skb->data, PEGASUS_MTU + 8, 702 pegasus->rx_skb->data, PEGASUS_MTU + 8,
694 read_bulk_callback, pegasus); 703 read_bulk_callback, pegasus);
695 if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) { 704 rx_status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC);
705 if (rx_status == -ENODEV)
706 netif_device_detach(pegasus->net);
707 else if (rx_status) {
696 pegasus->flags |= PEGASUS_RX_URB_FAIL; 708 pegasus->flags |= PEGASUS_RX_URB_FAIL;
697 goto tl_sched; 709 goto tl_sched;
698 } else { 710 } else {
@@ -709,6 +721,7 @@ static void rx_fixup(unsigned long data)
709{ 721{
710 pegasus_t *pegasus; 722 pegasus_t *pegasus;
711 unsigned long flags; 723 unsigned long flags;
724 int status;
712 725
713 pegasus = (pegasus_t *) data; 726 pegasus = (pegasus_t *) data;
714 if (pegasus->flags & PEGASUS_UNPLUG) 727 if (pegasus->flags & PEGASUS_UNPLUG)
@@ -734,7 +747,10 @@ static void rx_fixup(unsigned long data)
734 pegasus->rx_skb->data, PEGASUS_MTU + 8, 747 pegasus->rx_skb->data, PEGASUS_MTU + 8,
735 read_bulk_callback, pegasus); 748 read_bulk_callback, pegasus);
736try_again: 749try_again:
737 if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) { 750 status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC);
751 if (status == -ENODEV)
752 netif_device_detach(pegasus->net);
753 else if (status) {
738 pegasus->flags |= PEGASUS_RX_URB_FAIL; 754 pegasus->flags |= PEGASUS_RX_URB_FAIL;
739 tasklet_schedule(&pegasus->rx_tl); 755 tasklet_schedule(&pegasus->rx_tl);
740 } else { 756 } else {
@@ -836,6 +852,8 @@ static void intr_callback(struct urb *urb, struct pt_regs *regs)
836 } 852 }
837 853
838 status = usb_submit_urb(urb, SLAB_ATOMIC); 854 status = usb_submit_urb(urb, SLAB_ATOMIC);
855 if (status == -ENODEV)
856 netif_device_detach(pegasus->net);
839 if (status && netif_msg_timer(pegasus)) 857 if (status && netif_msg_timer(pegasus))
840 printk(KERN_ERR "%s: can't resubmit interrupt urb, %d\n", 858 printk(KERN_ERR "%s: can't resubmit interrupt urb, %d\n",
841 net->name, status); 859 net->name, status);
@@ -874,6 +892,7 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
874 /* cleanup should already have been scheduled */ 892 /* cleanup should already have been scheduled */
875 break; 893 break;
876 case -ENODEV: /* disconnect() upcoming */ 894 case -ENODEV: /* disconnect() upcoming */
895 netif_device_detach(pegasus->net);
877 break; 896 break;
878 default: 897 default:
879 pegasus->stats.tx_errors++; 898 pegasus->stats.tx_errors++;
@@ -999,6 +1018,8 @@ static int pegasus_open(struct net_device *net)
999 pegasus->rx_skb->data, PEGASUS_MTU + 8, 1018 pegasus->rx_skb->data, PEGASUS_MTU + 8,
1000 read_bulk_callback, pegasus); 1019 read_bulk_callback, pegasus);
1001 if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) { 1020 if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) {
1021 if (res == -ENODEV)
1022 netif_device_detach(pegasus->net);
1002 if (netif_msg_ifup(pegasus)) 1023 if (netif_msg_ifup(pegasus))
1003 pr_debug("%s: failed rx_urb, %d", net->name, res); 1024 pr_debug("%s: failed rx_urb, %d", net->name, res);
1004 goto exit; 1025 goto exit;
@@ -1009,6 +1030,8 @@ static int pegasus_open(struct net_device *net)
1009 pegasus->intr_buff, sizeof (pegasus->intr_buff), 1030 pegasus->intr_buff, sizeof (pegasus->intr_buff),
1010 intr_callback, pegasus, pegasus->intr_interval); 1031 intr_callback, pegasus, pegasus->intr_interval);
1011 if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) { 1032 if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) {
1033 if (res == -ENODEV)
1034 netif_device_detach(pegasus->net);
1012 if (netif_msg_ifup(pegasus)) 1035 if (netif_msg_ifup(pegasus))
1013 pr_debug("%s: failed intr_urb, %d\n", net->name, res); 1036 pr_debug("%s: failed intr_urb, %d\n", net->name, res);
1014 usb_kill_urb(pegasus->rx_urb); 1037 usb_kill_urb(pegasus->rx_urb);
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c
index 94ddfe16fdda..f551546d7521 100644
--- a/drivers/usb/net/rndis_host.c
+++ b/drivers/usb/net/rndis_host.c
@@ -30,7 +30,7 @@
30#include <linux/workqueue.h> 30#include <linux/workqueue.h>
31#include <linux/mii.h> 31#include <linux/mii.h>
32#include <linux/usb.h> 32#include <linux/usb.h>
33#include <linux/usb_cdc.h> 33#include <linux/usb/cdc.h>
34 34
35#include "usbnet.h" 35#include "usbnet.h"
36 36
diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c
index f7ac9d6b9856..813e470d0600 100644
--- a/drivers/usb/net/zaurus.c
+++ b/drivers/usb/net/zaurus.c
@@ -30,7 +30,7 @@
30#include <linux/mii.h> 30#include <linux/mii.h>
31#include <linux/crc32.h> 31#include <linux/crc32.h>
32#include <linux/usb.h> 32#include <linux/usb.h>
33#include <linux/usb_cdc.h> 33#include <linux/usb/cdc.h>
34 34
35#include "usbnet.h" 35#include "usbnet.h"
36 36
@@ -109,7 +109,7 @@ static const struct driver_info zaurus_sl5x00_info = {
109 .check_connect = always_connected, 109 .check_connect = always_connected,
110 .bind = zaurus_bind, 110 .bind = zaurus_bind,
111 .unbind = usbnet_cdc_unbind, 111 .unbind = usbnet_cdc_unbind,
112 .tx_fixup = zaurus_tx_fixup, 112 .tx_fixup = zaurus_tx_fixup,
113}; 113};
114#define ZAURUS_STRONGARM_INFO ((unsigned long)&zaurus_sl5x00_info) 114#define ZAURUS_STRONGARM_INFO ((unsigned long)&zaurus_sl5x00_info)
115 115
@@ -119,7 +119,7 @@ static const struct driver_info zaurus_pxa_info = {
119 .check_connect = always_connected, 119 .check_connect = always_connected,
120 .bind = zaurus_bind, 120 .bind = zaurus_bind,
121 .unbind = usbnet_cdc_unbind, 121 .unbind = usbnet_cdc_unbind,
122 .tx_fixup = zaurus_tx_fixup, 122 .tx_fixup = zaurus_tx_fixup,
123}; 123};
124#define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info) 124#define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info)
125 125
@@ -129,7 +129,7 @@ static const struct driver_info olympus_mxl_info = {
129 .check_connect = always_connected, 129 .check_connect = always_connected,
130 .bind = zaurus_bind, 130 .bind = zaurus_bind,
131 .unbind = usbnet_cdc_unbind, 131 .unbind = usbnet_cdc_unbind,
132 .tx_fixup = zaurus_tx_fixup, 132 .tx_fixup = zaurus_tx_fixup,
133}; 133};
134#define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info) 134#define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info)
135 135
@@ -228,6 +228,11 @@ bad_detail:
228 detail->bDetailData[2]); 228 detail->bDetailData[2]);
229 goto bad_desc; 229 goto bad_desc;
230 } 230 }
231
232 /* same extra framing as for non-BLAN mode */
233 dev->net->hard_header_len += 6;
234 dev->rx_urb_size = dev->net->hard_header_len
235 + dev->net->mtu;
231 break; 236 break;
232 } 237 }
233next_desc: 238next_desc:
@@ -258,7 +263,7 @@ static const struct driver_info bogus_mdlm_info = {
258 .description = "pseudo-MDLM (BLAN) device", 263 .description = "pseudo-MDLM (BLAN) device",
259 .flags = FLAG_FRAMING_Z, 264 .flags = FLAG_FRAMING_Z,
260 .check_connect = always_connected, 265 .check_connect = always_connected,
261 .tx_fixup = zaurus_tx_fixup, 266 .tx_fixup = zaurus_tx_fixup,
262 .bind = blan_mdlm_bind, 267 .bind = blan_mdlm_bind,
263}; 268};
264 269
@@ -367,13 +372,13 @@ static struct usb_driver zaurus_driver = {
367 372
368static int __init zaurus_init(void) 373static int __init zaurus_init(void)
369{ 374{
370 return usb_register(&zaurus_driver); 375 return usb_register(&zaurus_driver);
371} 376}
372module_init(zaurus_init); 377module_init(zaurus_init);
373 378
374static void __exit zaurus_exit(void) 379static void __exit zaurus_exit(void)
375{ 380{
376 usb_deregister(&zaurus_driver); 381 usb_deregister(&zaurus_driver);
377} 382}
378module_exit(zaurus_exit); 383module_exit(zaurus_exit);
379 384
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 5c60be521561..8bd44fda5eaf 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -417,7 +417,7 @@ config USB_SERIAL_MCT_U232
417 Magic Control Technology Corp. (U232 is one of the model numbers). 417 Magic Control Technology Corp. (U232 is one of the model numbers).
418 418
419 This driver also works with Sitecom U232-P25 and D-Link DU-H3SP USB 419 This driver also works with Sitecom U232-P25 and D-Link DU-H3SP USB
420 BAY devices. 420 BAY, Belkin F5U109, and Belkin F5U409 devices.
421 421
422 To compile this driver as a module, choose M here: the 422 To compile this driver as a module, choose M here: the
423 module will be called mct_u232. 423 module will be called mct_u232.
@@ -491,16 +491,22 @@ config USB_SERIAL_XIRCOM
491 module will be called keyspan_pda. 491 module will be called keyspan_pda.
492 492
493config USB_SERIAL_OPTION 493config USB_SERIAL_OPTION
494 tristate "USB Option PCMCIA serial driver" 494 tristate "USB driver for GSM modems"
495 depends on USB_SERIAL && USB_OHCI_HCD && PCCARD 495 depends on USB_SERIAL
496 help 496 help
497 Say Y here if you want to use an Option card. This is a 497 Say Y here if you have an "Option" GSM PCMCIA card
498 GSM card, controlled by three serial ports which are connected 498 (or an OEM version: branded Huawei, Audiovox, or Novatel).
499 via an OHCI adapter located on a PC card. 499
500 These cards feature a built-in OHCI-USB adapter and an
501 internally-connected GSM modem. The USB bus is not
502 accessible externally.
500 503
501 To compile this driver as a module, choose M here: the 504 To compile this driver as a module, choose M here: the
502 module will be called option. 505 module will be called option.
503 506
507 If this driver doesn't recognize your device,
508 it might be accessible via the FTDI_SIO driver.
509
504config USB_SERIAL_OMNINET 510config USB_SERIAL_OMNINET
505 tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)" 511 tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)"
506 depends on USB_SERIAL && EXPERIMENTAL 512 depends on USB_SERIAL && EXPERIMENTAL
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
index 694b205f9b73..94b9ba0ff875 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -16,9 +16,11 @@
16#include "usb-serial.h" 16#include "usb-serial.h"
17 17
18static struct usb_device_id id_table [] = { 18static struct usb_device_id id_table [] = {
19 { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
19 { USB_DEVICE(0xf3d, 0x0112) }, /* AirPrime CDMA Wireless PC Card */ 20 { USB_DEVICE(0xf3d, 0x0112) }, /* AirPrime CDMA Wireless PC Card */
20 { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ 21 { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */
21 { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless Aircard 580 */ 22 { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless Aircard 580 */
23 { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
22 { }, 24 { },
23}; 25};
24MODULE_DEVICE_TABLE(usb, id_table); 26MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 8023bb7279b1..f3404e10afb4 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -202,7 +202,7 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun
202 struct usb_serial *serial; 202 struct usb_serial *serial;
203 int retval = -ENODEV; 203 int retval = -ENODEV;
204 204
205 if (!port) 205 if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED)
206 return; 206 return;
207 serial = port->serial; 207 serial = port->serial;
208 208
@@ -213,17 +213,38 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun
213 213
214 if (!port->open_count) { 214 if (!port->open_count) {
215 dbg ("%s - port not opened", __FUNCTION__); 215 dbg ("%s - port not opened", __FUNCTION__);
216 goto exit; 216 return;
217 } 217 }
218 218
219 /* pass on to the driver specific version of this function if it is available */ 219 while (count) {
220 if (serial->type->write) 220 unsigned int i;
221 retval = serial->type->write(port, buf, count); 221 unsigned int lf;
222 else 222 /* search for LF so we can insert CR if necessary */
223 retval = usb_serial_generic_write(port, buf, count); 223 for (i=0, lf=0 ; i < count ; i++) {
224 224 if (*(buf + i) == 10) {
225exit: 225 lf = 1;
226 dbg("%s - return value (if we had one): %d", __FUNCTION__, retval); 226 i++;
227 break;
228 }
229 }
230 /* pass on to the driver specific version of this function if it is available */
231 if (serial->type->write)
232 retval = serial->type->write(port, buf, i);
233 else
234 retval = usb_serial_generic_write(port, buf, i);
235 dbg("%s - return value : %d", __FUNCTION__, retval);
236 if (lf) {
237 /* append CR after LF */
238 unsigned char cr = 13;
239 if (serial->type->write)
240 retval = serial->type->write(port, &cr, 1);
241 else
242 retval = usb_serial_generic_write(port, &cr, 1);
243 dbg("%s - return value : %d", __FUNCTION__, retval);
244 }
245 buf += i;
246 count -= i;
247 }
227} 248}
228 249
229static struct console usbcons = { 250static struct console usbcons = {
@@ -234,6 +255,14 @@ static struct console usbcons = {
234 .index = -1, 255 .index = -1,
235}; 256};
236 257
258void usb_serial_console_disconnect(struct usb_serial *serial)
259{
260 if (serial && serial->port && serial->port[0] && serial->port[0] == usbcons_info.port) {
261 usb_serial_console_exit();
262 usb_serial_put(serial);
263 }
264}
265
237void usb_serial_console_init (int serial_debug, int minor) 266void usb_serial_console_init (int serial_debug, int minor)
238{ 267{
239 debug = serial_debug; 268 debug = serial_debug;
@@ -259,6 +288,11 @@ void usb_serial_console_init (int serial_debug, int minor)
259 288
260void usb_serial_console_exit (void) 289void usb_serial_console_exit (void)
261{ 290{
262 unregister_console(&usbcons); 291 if (usbcons_info.port) {
292 unregister_console(&usbcons);
293 if (usbcons_info.port->open_count)
294 usbcons_info.port->open_count--;
295 usbcons_info.port = NULL;
296 }
263} 297}
264 298
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index e0c2acdb3f06..f8c0cb287736 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -59,6 +59,7 @@ static struct usb_device_id id_table [] = {
59 { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ 59 { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
60 { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ 60 { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
61 { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ 61 { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
62 { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */
62 { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ 63 { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */
63 { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ 64 { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
64 { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ 65 { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 2357b1d102d7..1fd5c5a9f2ef 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -469,7 +469,7 @@ static void cyberjack_write_bulk_callback (struct urb *urb, struct pt_regs *regs
469 469
470exit: 470exit:
471 spin_unlock(&priv->lock); 471 spin_unlock(&priv->lock);
472 schedule_work(&port->work); 472 usb_serial_port_softint(port);
473} 473}
474 474
475static int __init cyberjack_init (void) 475static int __init cyberjack_init (void)
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 7212fbe3b6f2..5de76efe1b37 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -824,7 +824,7 @@ send:
824 priv->bytes_out += count; /* do not count the line control and size bytes */ 824 priv->bytes_out += count; /* do not count the line control and size bytes */
825 spin_unlock_irqrestore(&priv->lock, flags); 825 spin_unlock_irqrestore(&priv->lock, flags);
826 826
827 schedule_work(&port->work); 827 usb_serial_port_softint(port);
828} /* cypress_send */ 828} /* cypress_send */
829 829
830 830
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 63f7c78a1152..afca1eae5fb5 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -335,7 +335,7 @@ static void empeg_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
335 return; 335 return;
336 } 336 }
337 337
338 schedule_work(&port->work); 338 usb_serial_port_softint(port);
339} 339}
340 340
341 341
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 986d7622273d..b2bfea7c815a 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -500,6 +500,7 @@ static struct usb_device_id id_table_combined [] = {
500 { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, 500 { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) },
501 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, 501 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) },
502 { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) }, 502 { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) },
503 { USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) },
503 { }, /* Optional parameter entry */ 504 { }, /* Optional parameter entry */
504 { } /* Terminating entry */ 505 { } /* Terminating entry */
505}; 506};
@@ -1261,7 +1262,6 @@ static void ftdi_shutdown (struct usb_serial *serial)
1261 1262
1262static int ftdi_open (struct usb_serial_port *port, struct file *filp) 1263static int ftdi_open (struct usb_serial_port *port, struct file *filp)
1263{ /* ftdi_open */ 1264{ /* ftdi_open */
1264 struct termios tmp_termios;
1265 struct usb_device *dev = port->serial->dev; 1265 struct usb_device *dev = port->serial->dev;
1266 struct ftdi_private *priv = usb_get_serial_port_data(port); 1266 struct ftdi_private *priv = usb_get_serial_port_data(port);
1267 unsigned long flags; 1267 unsigned long flags;
@@ -1271,8 +1271,8 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp)
1271 1271
1272 dbg("%s", __FUNCTION__); 1272 dbg("%s", __FUNCTION__);
1273 1273
1274 1274 if (port->tty)
1275 port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1275 port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1276 1276
1277 /* No error checking for this (will get errors later anyway) */ 1277 /* No error checking for this (will get errors later anyway) */
1278 /* See ftdi_sio.h for description of what is reset */ 1278 /* See ftdi_sio.h for description of what is reset */
@@ -1286,7 +1286,8 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp)
1286 This is same behaviour as serial.c/rs_open() - Kuba */ 1286 This is same behaviour as serial.c/rs_open() - Kuba */
1287 1287
1288 /* ftdi_set_termios will send usb control messages */ 1288 /* ftdi_set_termios will send usb control messages */
1289 ftdi_set_termios(port, &tmp_termios); 1289 if (port->tty)
1290 ftdi_set_termios(port, NULL);
1290 1291
1291 /* FIXME: Flow control might be enabled, so it should be checked - 1292 /* FIXME: Flow control might be enabled, so it should be checked -
1292 we have no control of defaults! */ 1293 we have no control of defaults! */
@@ -1472,7 +1473,7 @@ static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
1472 return; 1473 return;
1473 } 1474 }
1474 1475
1475 schedule_work(&port->work); 1476 usb_serial_port_softint(port);
1476} /* ftdi_write_bulk_callback */ 1477} /* ftdi_write_bulk_callback */
1477 1478
1478 1479
@@ -1867,7 +1868,7 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_
1867 err("%s urb failed to set baudrate", __FUNCTION__); 1868 err("%s urb failed to set baudrate", __FUNCTION__);
1868 } 1869 }
1869 /* Ensure RTS and DTR are raised when baudrate changed from 0 */ 1870 /* Ensure RTS and DTR are raised when baudrate changed from 0 */
1870 if ((old_termios->c_cflag & CBAUD) == B0) { 1871 if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) {
1871 set_mctrl(port, TIOCM_DTR | TIOCM_RTS); 1872 set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
1872 } 1873 }
1873 } 1874 }
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index d69a917e768f..6ab2ac845bd7 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -436,6 +436,12 @@
436 */ 436 */
437#define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */ 437#define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */
438 438
439/*
440 * Yost Engineering, Inc. products (www.yostengineering.com).
441 * PID 0xE050 submitted by Aaron Prose.
442 */
443#define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */
444
439/* Commands */ 445/* Commands */
440#define FTDI_SIO_RESET 0 /* Reset the port */ 446#define FTDI_SIO_RESET 0 /* Reset the port */
441#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ 447#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 5ec9bf5bac8d..04767759cf8a 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1012,7 +1012,7 @@ static void garmin_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
1012 garmin_data_p->flags |= CLEAR_HALT_REQUIRED; 1012 garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
1013 } 1013 }
1014 1014
1015 schedule_work(&port->work); 1015 usb_serial_port_softint(port);
1016} 1016}
1017 1017
1018 1018
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index c62cc2876519..07a478c59fb2 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -299,9 +299,7 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *re
299 return; 299 return;
300 } 300 }
301 301
302 usb_serial_port_softint((void *)port); 302 usb_serial_port_softint(port);
303
304 schedule_work(&port->work);
305} 303}
306EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); 304EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
307 305
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index b606c5968102..b85d2156dfdc 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -142,7 +142,7 @@ struct edgeport_port {
142 142
143/* This structure holds all of the individual device information */ 143/* This structure holds all of the individual device information */
144struct edgeport_serial { 144struct edgeport_serial {
145 char name[MAX_NAME_LEN+1]; /* string name of this device */ 145 char name[MAX_NAME_LEN+2]; /* string name of this device */
146 146
147 struct edge_manuf_descriptor manuf_descriptor; /* the manufacturer descriptor */ 147 struct edge_manuf_descriptor manuf_descriptor; /* the manufacturer descriptor */
148 struct edge_boot_descriptor boot_descriptor; /* the boot firmware descriptor */ 148 struct edge_boot_descriptor boot_descriptor; /* the boot firmware descriptor */
@@ -270,7 +270,7 @@ static void get_manufacturing_desc (struct edgeport_serial *edge_serial);
270static void get_boot_desc (struct edgeport_serial *edge_serial); 270static void get_boot_desc (struct edgeport_serial *edge_serial);
271static void load_application_firmware (struct edgeport_serial *edge_serial); 271static void load_application_firmware (struct edgeport_serial *edge_serial);
272 272
273static void unicode_to_ascii (char *string, __le16 *unicode, int unicode_size); 273static void unicode_to_ascii(char *string, int buflen, __le16 *unicode, int unicode_size);
274 274
275 275
276// ************************************************************************ 276// ************************************************************************
@@ -373,7 +373,7 @@ static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial)
373 * Get string descriptor from device * 373 * Get string descriptor from device *
374 * * 374 * *
375 ************************************************************************/ 375 ************************************************************************/
376static int get_string (struct usb_device *dev, int Id, char *string) 376static int get_string (struct usb_device *dev, int Id, char *string, int buflen)
377{ 377{
378 struct usb_string_descriptor StringDesc; 378 struct usb_string_descriptor StringDesc;
379 struct usb_string_descriptor *pStringDesc; 379 struct usb_string_descriptor *pStringDesc;
@@ -395,7 +395,7 @@ static int get_string (struct usb_device *dev, int Id, char *string)
395 return 0; 395 return 0;
396 } 396 }
397 397
398 unicode_to_ascii(string, pStringDesc->wData, pStringDesc->bLength/2-1); 398 unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2);
399 399
400 kfree(pStringDesc); 400 kfree(pStringDesc);
401 return strlen(string); 401 return strlen(string);
@@ -2564,16 +2564,20 @@ static void change_port_settings (struct edgeport_port *edge_port, struct termio
2564 * ASCII range, but it's only for debugging... 2564 * ASCII range, but it's only for debugging...
2565 * NOTE: expects the unicode in LE format 2565 * NOTE: expects the unicode in LE format
2566 ****************************************************************************/ 2566 ****************************************************************************/
2567static void unicode_to_ascii (char *string, __le16 *unicode, int unicode_size) 2567static void unicode_to_ascii(char *string, int buflen, __le16 *unicode, int unicode_size)
2568{ 2568{
2569 int i; 2569 int i;
2570 2570
2571 if (unicode_size <= 0) 2571 if (buflen <= 0) /* never happens, but... */
2572 return; 2572 return;
2573 --buflen; /* space for nul */
2573 2574
2574 for (i = 0; i < unicode_size; ++i) 2575 for (i = 0; i < unicode_size; i++) {
2576 if (i >= buflen)
2577 break;
2575 string[i] = (char)(le16_to_cpu(unicode[i])); 2578 string[i] = (char)(le16_to_cpu(unicode[i]));
2576 string[unicode_size] = 0x00; 2579 }
2580 string[i] = 0x00;
2577} 2581}
2578 2582
2579 2583
@@ -2603,11 +2607,17 @@ static void get_manufacturing_desc (struct edgeport_serial *edge_serial)
2603 dbg(" BoardRev: %d", edge_serial->manuf_descriptor.BoardRev); 2607 dbg(" BoardRev: %d", edge_serial->manuf_descriptor.BoardRev);
2604 dbg(" NumPorts: %d", edge_serial->manuf_descriptor.NumPorts); 2608 dbg(" NumPorts: %d", edge_serial->manuf_descriptor.NumPorts);
2605 dbg(" DescDate: %d/%d/%d", edge_serial->manuf_descriptor.DescDate[0], edge_serial->manuf_descriptor.DescDate[1], edge_serial->manuf_descriptor.DescDate[2]+1900); 2609 dbg(" DescDate: %d/%d/%d", edge_serial->manuf_descriptor.DescDate[0], edge_serial->manuf_descriptor.DescDate[1], edge_serial->manuf_descriptor.DescDate[2]+1900);
2606 unicode_to_ascii (string, edge_serial->manuf_descriptor.SerialNumber, edge_serial->manuf_descriptor.SerNumLength/2-1); 2610 unicode_to_ascii(string, sizeof(string),
2611 edge_serial->manuf_descriptor.SerialNumber,
2612 edge_serial->manuf_descriptor.SerNumLength/2);
2607 dbg(" SerialNumber: %s", string); 2613 dbg(" SerialNumber: %s", string);
2608 unicode_to_ascii (string, edge_serial->manuf_descriptor.AssemblyNumber, edge_serial->manuf_descriptor.AssemblyNumLength/2-1); 2614 unicode_to_ascii(string, sizeof(string),
2615 edge_serial->manuf_descriptor.AssemblyNumber,
2616 edge_serial->manuf_descriptor.AssemblyNumLength/2);
2609 dbg(" AssemblyNumber: %s", string); 2617 dbg(" AssemblyNumber: %s", string);
2610 unicode_to_ascii (string, edge_serial->manuf_descriptor.OemAssyNumber, edge_serial->manuf_descriptor.OemAssyNumLength/2-1); 2618 unicode_to_ascii(string, sizeof(string),
2619 edge_serial->manuf_descriptor.OemAssyNumber,
2620 edge_serial->manuf_descriptor.OemAssyNumLength/2);
2611 dbg(" OemAssyNumber: %s", string); 2621 dbg(" OemAssyNumber: %s", string);
2612 dbg(" UartType: %d", edge_serial->manuf_descriptor.UartType); 2622 dbg(" UartType: %d", edge_serial->manuf_descriptor.UartType);
2613 dbg(" IonPid: %d", edge_serial->manuf_descriptor.IonPid); 2623 dbg(" IonPid: %d", edge_serial->manuf_descriptor.IonPid);
@@ -2720,7 +2730,7 @@ static int edge_startup (struct usb_serial *serial)
2720 struct edgeport_serial *edge_serial; 2730 struct edgeport_serial *edge_serial;
2721 struct edgeport_port *edge_port; 2731 struct edgeport_port *edge_port;
2722 struct usb_device *dev; 2732 struct usb_device *dev;
2723 int i; 2733 int i, j;
2724 2734
2725 dev = serial->dev; 2735 dev = serial->dev;
2726 2736
@@ -2735,11 +2745,11 @@ static int edge_startup (struct usb_serial *serial)
2735 usb_set_serial_data(serial, edge_serial); 2745 usb_set_serial_data(serial, edge_serial);
2736 2746
2737 /* get the name for the device from the device */ 2747 /* get the name for the device from the device */
2738 if ( (i = get_string(dev, dev->descriptor.iManufacturer, &edge_serial->name[0])) != 0) { 2748 i = get_string(dev, dev->descriptor.iManufacturer,
2739 edge_serial->name[i-1] = ' '; 2749 &edge_serial->name[0], MAX_NAME_LEN+1);
2740 } 2750 edge_serial->name[i++] = ' ';
2741 2751 get_string(dev, dev->descriptor.iProduct,
2742 get_string(dev, dev->descriptor.iProduct, &edge_serial->name[i]); 2752 &edge_serial->name[i], MAX_NAME_LEN+2 - i);
2743 2753
2744 dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); 2754 dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name);
2745 2755
@@ -2784,6 +2794,10 @@ static int edge_startup (struct usb_serial *serial)
2784 edge_port = kmalloc (sizeof(struct edgeport_port), GFP_KERNEL); 2794 edge_port = kmalloc (sizeof(struct edgeport_port), GFP_KERNEL);
2785 if (edge_port == NULL) { 2795 if (edge_port == NULL) {
2786 dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__); 2796 dev_err(&serial->dev->dev, "%s - Out of memory\n", __FUNCTION__);
2797 for (j = 0; j < i; ++j) {
2798 kfree (usb_get_serial_port_data(serial->port[j]));
2799 usb_set_serial_port_data(serial->port[j], NULL);
2800 }
2787 usb_set_serial_data(serial, NULL); 2801 usb_set_serial_data(serial, NULL);
2788 kfree(edge_serial); 2802 kfree(edge_serial);
2789 return -ENOMEM; 2803 return -ENOMEM;
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 9a5c97989562..9da6d2a8f2b0 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -870,7 +870,7 @@ static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
870 spin_unlock_irqrestore(&write_list_lock, flags); 870 spin_unlock_irqrestore(&write_list_lock, flags);
871 } 871 }
872 872
873 schedule_work(&port->work); 873 usb_serial_port_softint(port);
874} 874}
875 875
876static int ipaq_write_room(struct usb_serial_port *port) 876static int ipaq_write_room(struct usb_serial_port *port)
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index e760a70242c1..a4a0bfeaab00 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -376,7 +376,7 @@ static void ipw_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
376 if (urb->status) 376 if (urb->status)
377 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); 377 dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
378 378
379 schedule_work(&port->work); 379 usb_serial_port_softint(port);
380} 380}
381 381
382static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int count) 382static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int count)
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 426182ddc42a..9432c7302275 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -408,7 +408,7 @@ static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
408 urb->actual_length, 408 urb->actual_length,
409 urb->transfer_buffer); 409 urb->transfer_buffer);
410 410
411 schedule_work(&port->work); 411 usb_serial_port_softint(port);
412} 412}
413 413
414static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs) 414static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 052b735c4fbd..2cf6ade704e4 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -481,7 +481,7 @@ static void usa2x_outdat_callback(struct urb *urb, struct pt_regs *regs)
481 dbg ("%s - urb %d", __FUNCTION__, urb == p_priv->out_urbs[1]); 481 dbg ("%s - urb %d", __FUNCTION__, urb == p_priv->out_urbs[1]);
482 482
483 if (port->open_count) 483 if (port->open_count)
484 schedule_work(&port->work); 484 usb_serial_port_softint(port);
485} 485}
486 486
487static void usa26_inack_callback(struct urb *urb, struct pt_regs *regs) 487static void usa26_inack_callback(struct urb *urb, struct pt_regs *regs)
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index 78335a5f7743..65d79f630fa4 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -569,8 +569,7 @@ static void klsi_105_write_bulk_callback ( struct urb *urb, struct pt_regs *regs
569 return; 569 return;
570 } 570 }
571 571
572 /* from generic_write_bulk_callback */ 572 usb_serial_port_softint(port);
573 schedule_work(&port->work);
574} /* klsi_105_write_bulk_completion_callback */ 573} /* klsi_105_write_bulk_completion_callback */
575 574
576 575
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 238033a87092..6dcdb5f598b8 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -320,7 +320,7 @@ static void omninet_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
320 return; 320 return;
321 } 321 }
322 322
323 schedule_work(&port->work); 323 usb_serial_port_softint(port);
324} 324}
325 325
326 326
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 5cf2b80add7a..b0861b61bba7 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1,5 +1,5 @@
1/* 1/*
2 Option Card (PCMCIA to) USB to Serial Driver 2 USB Driver for GSM modems
3 3
4 Copyright (C) 2005 Matthias Urlichs <smurf@smurf.noris.de> 4 Copyright (C) 2005 Matthias Urlichs <smurf@smurf.noris.de>
5 5
@@ -28,15 +28,34 @@
28 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard 28 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard
29 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes 29 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes
30 wants to send >2000 bytes. 30 wants to send >2000 bytes.
31 2006-04-10 v0.4.2 fixed two array overrun errors :-/ 31 2006-04-10 v0.5 fixed two array overrun errors :-/
32 2006-04-21 v0.5.1 added support for Sierra Wireless MC8755
33 2006-05-15 v0.6 re-enable multi-port support
34 2006-06-01 v0.6.1 add COBRA
35 2006-06-01 v0.6.2 add backwards-compatibility stuff
36 2006-06-01 v0.6.3 add Novatel Wireless
37 2006-06-01 v0.7 Option => GSM
32 38
33 Work sponsored by: Sigos GmbH, Germany <info@sigos.de> 39 Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
34 40
41 This driver exists because the "normal" serial driver doesn't work too well
42 with GSM modems. Issues:
43 - data loss -- one single Receive URB is not nearly enough
44 - nonstandard flow (Option devices) and multiplex (Sierra) control
45 - controlling the baud rate doesn't make sense
46
47 This driver is named "option" because the most common device it's
48 used for is a PC-Card (with an internal OHCI-USB interface, behind
49 which the GSM interface sits), made by Option Inc.
50
51 Some of the "one port" devices actually exhibit multiple USB instances
52 on the USB bus. This is not a bug, these ports are used for different
53 device features.
35*/ 54*/
36 55
37#define DRIVER_VERSION "v0.4" 56#define DRIVER_VERSION "v0.7.0"
38#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>" 57#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
39#define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver" 58#define DRIVER_DESC "USB Driver for GSM modems"
40 59
41#include <linux/config.h> 60#include <linux/config.h>
42#include <linux/kernel.h> 61#include <linux/kernel.h>
@@ -74,22 +93,45 @@ static int option_tiocmset(struct usb_serial_port *port, struct file *file,
74static int option_send_setup(struct usb_serial_port *port); 93static int option_send_setup(struct usb_serial_port *port);
75 94
76/* Vendor and product IDs */ 95/* Vendor and product IDs */
77#define OPTION_VENDOR_ID 0x0AF0 96#define OPTION_VENDOR_ID 0x0AF0
78#define HUAWEI_VENDOR_ID 0x12D1 97#define HUAWEI_VENDOR_ID 0x12D1
79#define AUDIOVOX_VENDOR_ID 0x0F3D 98#define AUDIOVOX_VENDOR_ID 0x0F3D
80 99#define SIERRAWIRELESS_VENDOR_ID 0x1199
81#define OPTION_PRODUCT_OLD 0x5000 100#define NOVATELWIRELESS_VENDOR_ID 0x1410
82#define OPTION_PRODUCT_FUSION 0x6000 101
83#define OPTION_PRODUCT_FUSION2 0x6300 102#define OPTION_PRODUCT_OLD 0x5000
84#define HUAWEI_PRODUCT_E600 0x1001 103#define OPTION_PRODUCT_FUSION 0x6000
85#define AUDIOVOX_PRODUCT_AIRCARD 0x0112 104#define OPTION_PRODUCT_FUSION2 0x6300
105#define OPTION_PRODUCT_COBRA 0x6500
106#define HUAWEI_PRODUCT_E600 0x1001
107#define AUDIOVOX_PRODUCT_AIRCARD 0x0112
108#define SIERRAWIRELESS_PRODUCT_MC8755 0x6802
109#define NOVATELWIRELESS_PRODUCT_U740 0x1400
86 110
87static struct usb_device_id option_ids[] = { 111static struct usb_device_id option_ids[] = {
88 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, 112 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
89 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) }, 113 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
90 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, 114 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
115 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
91 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, 116 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
92 { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, 117 { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
118 { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) },
119 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
120 { } /* Terminating entry */
121};
122
123static struct usb_device_id option_ids1[] = {
124 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
125 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
126 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
127 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
128 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
129 { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
130 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
131 { } /* Terminating entry */
132};
133static struct usb_device_id option_ids3[] = {
134 { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) },
93 { } /* Terminating entry */ 135 { } /* Terminating entry */
94}; 136};
95 137
@@ -111,12 +153,39 @@ static struct usb_serial_driver option_3port_device = {
111 .owner = THIS_MODULE, 153 .owner = THIS_MODULE,
112 .name = "option", 154 .name = "option",
113 }, 155 },
114 .description = "Option 3G data card", 156 .description = "GSM modem (3-port)",
115 .id_table = option_ids, 157 .id_table = option_ids3,
116 .num_interrupt_in = NUM_DONT_CARE, 158 .num_interrupt_in = NUM_DONT_CARE,
117 .num_bulk_in = NUM_DONT_CARE, 159 .num_bulk_in = NUM_DONT_CARE,
118 .num_bulk_out = NUM_DONT_CARE, 160 .num_bulk_out = NUM_DONT_CARE,
119 .num_ports = 1, /* 3, but the card reports its ports separately */ 161 .num_ports = 3,
162 .open = option_open,
163 .close = option_close,
164 .write = option_write,
165 .write_room = option_write_room,
166 .chars_in_buffer = option_chars_in_buffer,
167 .throttle = option_rx_throttle,
168 .unthrottle = option_rx_unthrottle,
169 .set_termios = option_set_termios,
170 .break_ctl = option_break_ctl,
171 .tiocmget = option_tiocmget,
172 .tiocmset = option_tiocmset,
173 .attach = option_startup,
174 .shutdown = option_shutdown,
175 .read_int_callback = option_instat_callback,
176};
177
178static struct usb_serial_driver option_1port_device = {
179 .driver = {
180 .owner = THIS_MODULE,
181 .name = "option",
182 },
183 .description = "GSM modem (1-port)",
184 .id_table = option_ids1,
185 .num_interrupt_in = NUM_DONT_CARE,
186 .num_bulk_in = NUM_DONT_CARE,
187 .num_bulk_out = NUM_DONT_CARE,
188 .num_ports = 1,
120 .open = option_open, 189 .open = option_open,
121 .close = option_close, 190 .close = option_close,
122 .write = option_write, 191 .write = option_write,
@@ -170,6 +239,9 @@ struct option_port_private {
170static int __init option_init(void) 239static int __init option_init(void)
171{ 240{
172 int retval; 241 int retval;
242 retval = usb_serial_register(&option_1port_device);
243 if (retval)
244 goto failed_1port_device_register;
173 retval = usb_serial_register(&option_3port_device); 245 retval = usb_serial_register(&option_3port_device);
174 if (retval) 246 if (retval)
175 goto failed_3port_device_register; 247 goto failed_3port_device_register;
@@ -184,6 +256,8 @@ static int __init option_init(void)
184failed_driver_register: 256failed_driver_register:
185 usb_serial_deregister (&option_3port_device); 257 usb_serial_deregister (&option_3port_device);
186failed_3port_device_register: 258failed_3port_device_register:
259 usb_serial_deregister (&option_1port_device);
260failed_1port_device_register:
187 return retval; 261 return retval;
188} 262}
189 263
@@ -191,6 +265,7 @@ static void __exit option_exit(void)
191{ 265{
192 usb_deregister (&option_driver); 266 usb_deregister (&option_driver);
193 usb_serial_deregister (&option_3port_device); 267 usb_serial_deregister (&option_3port_device);
268 usb_serial_deregister (&option_1port_device);
194} 269}
195 270
196module_init(option_init); 271module_init(option_init);
@@ -365,8 +440,7 @@ static void option_outdat_callback(struct urb *urb, struct pt_regs *regs)
365 440
366 port = (struct usb_serial_port *) urb->context; 441 port = (struct usb_serial_port *) urb->context;
367 442
368 if (port->open_count) 443 usb_serial_port_softint(port);
369 schedule_work(&port->work);
370} 444}
371 445
372static void option_instat_callback(struct urb *urb, struct pt_regs *regs) 446static void option_instat_callback(struct urb *urb, struct pt_regs *regs)
@@ -573,27 +647,30 @@ static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint,
573/* Setup urbs */ 647/* Setup urbs */
574static void option_setup_urbs(struct usb_serial *serial) 648static void option_setup_urbs(struct usb_serial *serial)
575{ 649{
576 int j; 650 int i,j;
577 struct usb_serial_port *port; 651 struct usb_serial_port *port;
578 struct option_port_private *portdata; 652 struct option_port_private *portdata;
579 653
580 dbg("%s", __FUNCTION__); 654 dbg("%s", __FUNCTION__);
581 655
582 port = serial->port[0]; 656
583 portdata = usb_get_serial_port_data(port); 657 for (i = 0; i < serial->num_ports; i++) {
658 port = serial->port[i];
659 portdata = usb_get_serial_port_data(port);
584 660
585 /* Do indat endpoints first */ 661 /* Do indat endpoints first */
586 for (j = 0; j < N_IN_URB; ++j) { 662 for (j = 0; j < N_IN_URB; ++j) {
587 portdata->in_urbs[j] = option_setup_urb (serial, 663 portdata->in_urbs[j] = option_setup_urb (serial,
588 port->bulk_in_endpointAddress, USB_DIR_IN, port, 664 port->bulk_in_endpointAddress, USB_DIR_IN, port,
589 portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); 665 portdata->in_buffer[j], IN_BUFLEN, option_indat_callback);
590 } 666 }
591 667
592 /* outdat endpoints */ 668 /* outdat endpoints */
593 for (j = 0; j < N_OUT_URB; ++j) { 669 for (j = 0; j < N_OUT_URB; ++j) {
594 portdata->out_urbs[j] = option_setup_urb (serial, 670 portdata->out_urbs[j] = option_setup_urb (serial,
595 port->bulk_out_endpointAddress, USB_DIR_OUT, port, 671 port->bulk_out_endpointAddress, USB_DIR_OUT, port,
596 portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); 672 portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback);
673 }
597 } 674 }
598} 675}
599 676
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index c96714bb1cb8..d88704387202 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -314,7 +314,7 @@ static void pl2303_send(struct usb_serial_port *port)
314 // TODO: reschedule pl2303_send 314 // TODO: reschedule pl2303_send
315 } 315 }
316 316
317 schedule_work(&port->work); 317 usb_serial_port_softint(port);
318} 318}
319 319
320static int pl2303_write_room(struct usb_serial_port *port) 320static int pl2303_write_room(struct usb_serial_port *port)
@@ -600,7 +600,7 @@ static void pl2303_close (struct usb_serial_port *port, struct file *filp)
600 unsigned int c_cflag; 600 unsigned int c_cflag;
601 int bps; 601 int bps;
602 long timeout; 602 long timeout;
603 wait_queue_t wait; \ 603 wait_queue_t wait;
604 604
605 dbg("%s - port %d", __FUNCTION__, port->number); 605 dbg("%s - port %d", __FUNCTION__, port->number);
606 606
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 9c36f0ece20f..a30135c7cfe6 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -162,12 +162,19 @@ static void destroy_serial(struct kref *kref)
162 } 162 }
163 } 163 }
164 164
165 flush_scheduled_work(); /* port->work */
166
165 usb_put_dev(serial->dev); 167 usb_put_dev(serial->dev);
166 168
167 /* free up any memory that we allocated */ 169 /* free up any memory that we allocated */
168 kfree (serial); 170 kfree (serial);
169} 171}
170 172
173void usb_serial_put(struct usb_serial *serial)
174{
175 kref_put(&serial->kref, destroy_serial);
176}
177
171/***************************************************************************** 178/*****************************************************************************
172 * Driver tty interface functions 179 * Driver tty interface functions
173 *****************************************************************************/ 180 *****************************************************************************/
@@ -201,12 +208,12 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
201 208
202 ++port->open_count; 209 ++port->open_count;
203 210
204 if (port->open_count == 1) { 211 /* set up our port structure making the tty driver
212 * remember our port object, and us it */
213 tty->driver_data = port;
214 port->tty = tty;
205 215
206 /* set up our port structure making the tty driver 216 if (port->open_count == 1) {
207 * remember our port object, and us it */
208 tty->driver_data = port;
209 port->tty = tty;
210 217
211 /* lock this module before we call it 218 /* lock this module before we call it
212 * this may fail, which means we must bail out, 219 * this may fail, which means we must bail out,
@@ -230,9 +237,11 @@ bailout_module_put:
230 module_put(serial->type->driver.owner); 237 module_put(serial->type->driver.owner);
231bailout_mutex_unlock: 238bailout_mutex_unlock:
232 port->open_count = 0; 239 port->open_count = 0;
240 tty->driver_data = NULL;
241 port->tty = NULL;
233 mutex_unlock(&port->mutex); 242 mutex_unlock(&port->mutex);
234bailout_kref_put: 243bailout_kref_put:
235 kref_put(&serial->kref, destroy_serial); 244 usb_serial_put(serial);
236 return retval; 245 return retval;
237} 246}
238 247
@@ -268,7 +277,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
268 } 277 }
269 278
270 mutex_unlock(&port->mutex); 279 mutex_unlock(&port->mutex);
271 kref_put(&port->serial->kref, destroy_serial); 280 usb_serial_put(port->serial);
272} 281}
273 282
274static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) 283static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
@@ -276,7 +285,7 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int
276 struct usb_serial_port *port = tty->driver_data; 285 struct usb_serial_port *port = tty->driver_data;
277 int retval = -EINVAL; 286 int retval = -EINVAL;
278 287
279 if (!port) 288 if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED)
280 goto exit; 289 goto exit;
281 290
282 dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); 291 dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);
@@ -296,7 +305,7 @@ exit:
296static int serial_write_room (struct tty_struct *tty) 305static int serial_write_room (struct tty_struct *tty)
297{ 306{
298 struct usb_serial_port *port = tty->driver_data; 307 struct usb_serial_port *port = tty->driver_data;
299 int retval = -EINVAL; 308 int retval = -ENODEV;
300 309
301 if (!port) 310 if (!port)
302 goto exit; 311 goto exit;
@@ -318,7 +327,7 @@ exit:
318static int serial_chars_in_buffer (struct tty_struct *tty) 327static int serial_chars_in_buffer (struct tty_struct *tty)
319{ 328{
320 struct usb_serial_port *port = tty->driver_data; 329 struct usb_serial_port *port = tty->driver_data;
321 int retval = -EINVAL; 330 int retval = -ENODEV;
322 331
323 if (!port) 332 if (!port)
324 goto exit; 333 goto exit;
@@ -473,7 +482,7 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int
473 begin += length; 482 begin += length;
474 length = 0; 483 length = 0;
475 } 484 }
476 kref_put(&serial->kref, destroy_serial); 485 usb_serial_put(serial);
477 } 486 }
478 *eof = 1; 487 *eof = 1;
479done: 488done:
@@ -488,19 +497,18 @@ static int serial_tiocmget (struct tty_struct *tty, struct file *file)
488 struct usb_serial_port *port = tty->driver_data; 497 struct usb_serial_port *port = tty->driver_data;
489 498
490 if (!port) 499 if (!port)
491 goto exit; 500 return -ENODEV;
492 501
493 dbg("%s - port %d", __FUNCTION__, port->number); 502 dbg("%s - port %d", __FUNCTION__, port->number);
494 503
495 if (!port->open_count) { 504 if (!port->open_count) {
496 dbg("%s - port not open", __FUNCTION__); 505 dbg("%s - port not open", __FUNCTION__);
497 goto exit; 506 return -ENODEV;
498 } 507 }
499 508
500 if (port->serial->type->tiocmget) 509 if (port->serial->type->tiocmget)
501 return port->serial->type->tiocmget(port, file); 510 return port->serial->type->tiocmget(port, file);
502 511
503exit:
504 return -EINVAL; 512 return -EINVAL;
505} 513}
506 514
@@ -510,23 +518,32 @@ static int serial_tiocmset (struct tty_struct *tty, struct file *file,
510 struct usb_serial_port *port = tty->driver_data; 518 struct usb_serial_port *port = tty->driver_data;
511 519
512 if (!port) 520 if (!port)
513 goto exit; 521 return -ENODEV;
514 522
515 dbg("%s - port %d", __FUNCTION__, port->number); 523 dbg("%s - port %d", __FUNCTION__, port->number);
516 524
517 if (!port->open_count) { 525 if (!port->open_count) {
518 dbg("%s - port not open", __FUNCTION__); 526 dbg("%s - port not open", __FUNCTION__);
519 goto exit; 527 return -ENODEV;
520 } 528 }
521 529
522 if (port->serial->type->tiocmset) 530 if (port->serial->type->tiocmset)
523 return port->serial->type->tiocmset(port, file, set, clear); 531 return port->serial->type->tiocmset(port, file, set, clear);
524 532
525exit:
526 return -EINVAL; 533 return -EINVAL;
527} 534}
528 535
529void usb_serial_port_softint(void *private) 536/*
537 * We would be calling tty_wakeup here, but unfortunately some line
538 * disciplines have an annoying habit of calling tty->write from
539 * the write wakeup callback (e.g. n_hdlc.c).
540 */
541void usb_serial_port_softint(struct usb_serial_port *port)
542{
543 schedule_work(&port->work);
544}
545
546static void usb_serial_port_work(void *private)
530{ 547{
531 struct usb_serial_port *port = private; 548 struct usb_serial_port *port = private;
532 struct tty_struct *tty; 549 struct tty_struct *tty;
@@ -789,7 +806,7 @@ int usb_serial_probe(struct usb_interface *interface,
789 port->serial = serial; 806 port->serial = serial;
790 spin_lock_init(&port->lock); 807 spin_lock_init(&port->lock);
791 mutex_init(&port->mutex); 808 mutex_init(&port->mutex);
792 INIT_WORK(&port->work, usb_serial_port_softint, port); 809 INIT_WORK(&port->work, usb_serial_port_work, port);
793 serial->port[i] = port; 810 serial->port[i] = port;
794 } 811 }
795 812
@@ -985,6 +1002,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
985 struct device *dev = &interface->dev; 1002 struct device *dev = &interface->dev;
986 struct usb_serial_port *port; 1003 struct usb_serial_port *port;
987 1004
1005 usb_serial_console_disconnect(serial);
988 dbg ("%s", __FUNCTION__); 1006 dbg ("%s", __FUNCTION__);
989 1007
990 usb_set_intfdata (interface, NULL); 1008 usb_set_intfdata (interface, NULL);
@@ -996,7 +1014,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
996 } 1014 }
997 /* let the last holder of this object 1015 /* let the last holder of this object
998 * cause it to be cleaned up */ 1016 * cause it to be cleaned up */
999 kref_put(&serial->kref, destroy_serial); 1017 usb_serial_put(serial);
1000 } 1018 }
1001 dev_info(dev, "device disconnected\n"); 1019 dev_info(dev, "device disconnected\n");
1002} 1020}
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
index dc89d8710460..d53ea9b11e81 100644
--- a/drivers/usb/serial/usb-serial.h
+++ b/drivers/usb/serial/usb-serial.h
@@ -236,7 +236,7 @@ struct usb_serial_driver {
236 236
237extern int usb_serial_register(struct usb_serial_driver *driver); 237extern int usb_serial_register(struct usb_serial_driver *driver);
238extern void usb_serial_deregister(struct usb_serial_driver *driver); 238extern void usb_serial_deregister(struct usb_serial_driver *driver);
239extern void usb_serial_port_softint(void *private); 239extern void usb_serial_port_softint(struct usb_serial_port *port);
240 240
241extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id); 241extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id);
242extern void usb_serial_disconnect(struct usb_interface *iface); 242extern void usb_serial_disconnect(struct usb_interface *iface);
@@ -248,13 +248,16 @@ extern int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit);
248#ifdef CONFIG_USB_SERIAL_CONSOLE 248#ifdef CONFIG_USB_SERIAL_CONSOLE
249extern void usb_serial_console_init (int debug, int minor); 249extern void usb_serial_console_init (int debug, int minor);
250extern void usb_serial_console_exit (void); 250extern void usb_serial_console_exit (void);
251extern void usb_serial_console_disconnect(struct usb_serial *serial);
251#else 252#else
252static inline void usb_serial_console_init (int debug, int minor) { } 253static inline void usb_serial_console_init (int debug, int minor) { }
253static inline void usb_serial_console_exit (void) { } 254static inline void usb_serial_console_exit (void) { }
255static inline void usb_serial_console_disconnect(struct usb_serial *serial) {}
254#endif 256#endif
255 257
256/* Functions needed by other parts of the usbserial core */ 258/* Functions needed by other parts of the usbserial core */
257extern struct usb_serial *usb_serial_get_by_index (unsigned int minor); 259extern struct usb_serial *usb_serial_get_by_index (unsigned int minor);
260extern void usb_serial_put(struct usb_serial *serial);
258extern int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp); 261extern int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp);
259extern int usb_serial_generic_write (struct usb_serial_port *port, const unsigned char *buf, int count); 262extern int usb_serial_generic_write (struct usb_serial_port *port, const unsigned char *buf, int count);
260extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp); 263extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp);
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index f5c3841d4843..9e89b8d54f72 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -480,7 +480,7 @@ static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
480 --priv->outstanding_urbs; 480 --priv->outstanding_urbs;
481 spin_unlock_irqrestore(&priv->lock, flags); 481 spin_unlock_irqrestore(&priv->lock, flags);
482 482
483 schedule_work(&port->work); 483 usb_serial_port_softint(port);
484} 484}
485 485
486 486
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index f806553cd9a4..5b06fa366098 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -388,7 +388,7 @@ static int whiteheat_attach (struct usb_serial *serial)
388 if (ret) { 388 if (ret) {
389 err("%s: Couldn't send command [%d]", serial->type->description, ret); 389 err("%s: Couldn't send command [%d]", serial->type->description, ret);
390 goto no_firmware; 390 goto no_firmware;
391 } else if (alen != sizeof(command)) { 391 } else if (alen != 2) {
392 err("%s: Send command incomplete [%d]", serial->type->description, alen); 392 err("%s: Send command incomplete [%d]", serial->type->description, alen);
393 goto no_firmware; 393 goto no_firmware;
394 } 394 }
@@ -400,7 +400,7 @@ static int whiteheat_attach (struct usb_serial *serial)
400 if (ret) { 400 if (ret) {
401 err("%s: Couldn't get results [%d]", serial->type->description, ret); 401 err("%s: Couldn't get results [%d]", serial->type->description, ret);
402 goto no_firmware; 402 goto no_firmware;
403 } else if (alen != sizeof(result)) { 403 } else if (alen != sizeof(*hw_info) + 1) {
404 err("%s: Get results incomplete [%d]", serial->type->description, alen); 404 err("%s: Get results incomplete [%d]", serial->type->description, alen);
405 goto no_firmware; 405 goto no_firmware;
406 } else if (result[0] != command[0]) { 406 } else if (result[0] != command[0]) {
@@ -1089,9 +1089,7 @@ static void whiteheat_write_callback(struct urb *urb, struct pt_regs *regs)
1089 return; 1089 return;
1090 } 1090 }
1091 1091
1092 usb_serial_port_softint((void *)port); 1092 usb_serial_port_softint(port);
1093
1094 schedule_work(&port->work);
1095} 1093}
1096 1094
1097 1095
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index 55ee2d36d585..026a587eb8dd 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -34,9 +34,8 @@
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/module.h> 36#include <linux/module.h>
37#include <linux/usb.h>
38#include <linux/usb_ch9.h> 37#include <linux/usb_ch9.h>
39#include <linux/usb_input.h> 38#include <linux/usb/input.h>
40#include "usb.h" 39#include "usb.h"
41#include "onetouch.h" 40#include "onetouch.h"
42#include "debug.h" 41#include "debug.h"
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 5f11e19eaae3..5715291ba540 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -286,11 +286,7 @@ static int bus_reset(struct scsi_cmnd *srb)
286 int result; 286 int result;
287 287
288 US_DEBUGP("%s called\n", __FUNCTION__); 288 US_DEBUGP("%s called\n", __FUNCTION__);
289
290 mutex_lock(&(us->dev_mutex));
291 result = usb_stor_port_reset(us); 289 result = usb_stor_port_reset(us);
292 mutex_unlock(&us->dev_mutex);
293
294 return result < 0 ? FAILED : SUCCESS; 290 return result < 0 ? FAILED : SUCCESS;
295} 291}
296 292
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index f2bc5c9e23d5..8fcec01dc622 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -131,28 +131,30 @@ static int usbat_write(struct us_data *us,
131 * Convenience function to perform a bulk read 131 * Convenience function to perform a bulk read
132 */ 132 */
133static int usbat_bulk_read(struct us_data *us, 133static int usbat_bulk_read(struct us_data *us,
134 unsigned char *data, 134 unsigned char *data,
135 unsigned int len) 135 unsigned int len,
136 int use_sg)
136{ 137{
137 if (len == 0) 138 if (len == 0)
138 return USB_STOR_XFER_GOOD; 139 return USB_STOR_XFER_GOOD;
139 140
140 US_DEBUGP("usbat_bulk_read: len = %d\n", len); 141 US_DEBUGP("usbat_bulk_read: len = %d\n", len);
141 return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, data, len, NULL); 142 return usb_stor_bulk_transfer_sg(us, us->recv_bulk_pipe, data, len, use_sg, NULL);
142} 143}
143 144
144/* 145/*
145 * Convenience function to perform a bulk write 146 * Convenience function to perform a bulk write
146 */ 147 */
147static int usbat_bulk_write(struct us_data *us, 148static int usbat_bulk_write(struct us_data *us,
148 unsigned char *data, 149 unsigned char *data,
149 unsigned int len) 150 unsigned int len,
151 int use_sg)
150{ 152{
151 if (len == 0) 153 if (len == 0)
152 return USB_STOR_XFER_GOOD; 154 return USB_STOR_XFER_GOOD;
153 155
154 US_DEBUGP("usbat_bulk_write: len = %d\n", len); 156 US_DEBUGP("usbat_bulk_write: len = %d\n", len);
155 return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, data, len, NULL); 157 return usb_stor_bulk_transfer_sg(us, us->send_bulk_pipe, data, len, use_sg, NULL);
156} 158}
157 159
158/* 160/*
@@ -317,7 +319,8 @@ static int usbat_wait_not_busy(struct us_data *us, int minutes)
317 */ 319 */
318static int usbat_read_block(struct us_data *us, 320static int usbat_read_block(struct us_data *us,
319 unsigned char *content, 321 unsigned char *content,
320 unsigned short len) 322 unsigned short len,
323 int use_sg)
321{ 324{
322 int result; 325 int result;
323 unsigned char *command = us->iobuf; 326 unsigned char *command = us->iobuf;
@@ -338,7 +341,7 @@ static int usbat_read_block(struct us_data *us,
338 if (result != USB_STOR_XFER_GOOD) 341 if (result != USB_STOR_XFER_GOOD)
339 return USB_STOR_TRANSPORT_ERROR; 342 return USB_STOR_TRANSPORT_ERROR;
340 343
341 result = usbat_bulk_read(us, content, len); 344 result = usbat_bulk_read(us, content, len, use_sg);
342 return (result == USB_STOR_XFER_GOOD ? 345 return (result == USB_STOR_XFER_GOOD ?
343 USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR); 346 USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
344} 347}
@@ -350,7 +353,8 @@ static int usbat_write_block(struct us_data *us,
350 unsigned char access, 353 unsigned char access,
351 unsigned char *content, 354 unsigned char *content,
352 unsigned short len, 355 unsigned short len,
353 int minutes) 356 int minutes,
357 int use_sg)
354{ 358{
355 int result; 359 int result;
356 unsigned char *command = us->iobuf; 360 unsigned char *command = us->iobuf;
@@ -372,7 +376,7 @@ static int usbat_write_block(struct us_data *us,
372 if (result != USB_STOR_XFER_GOOD) 376 if (result != USB_STOR_XFER_GOOD)
373 return USB_STOR_TRANSPORT_ERROR; 377 return USB_STOR_TRANSPORT_ERROR;
374 378
375 result = usbat_bulk_write(us, content, len); 379 result = usbat_bulk_write(us, content, len, use_sg);
376 if (result != USB_STOR_XFER_GOOD) 380 if (result != USB_STOR_XFER_GOOD)
377 return USB_STOR_TRANSPORT_ERROR; 381 return USB_STOR_TRANSPORT_ERROR;
378 382
@@ -465,7 +469,7 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us,
465 data[1+(j<<1)] = data_out[j]; 469 data[1+(j<<1)] = data_out[j];
466 } 470 }
467 471
468 result = usbat_bulk_write(us, data, num_registers*2); 472 result = usbat_bulk_write(us, data, num_registers*2, 0);
469 if (result != USB_STOR_XFER_GOOD) 473 if (result != USB_STOR_XFER_GOOD)
470 return USB_STOR_TRANSPORT_ERROR; 474 return USB_STOR_TRANSPORT_ERROR;
471 475
@@ -583,7 +587,7 @@ static int usbat_multiple_write(struct us_data *us,
583 } 587 }
584 588
585 /* Send the data */ 589 /* Send the data */
586 result = usbat_bulk_write(us, data, num_registers*2); 590 result = usbat_bulk_write(us, data, num_registers*2, 0);
587 if (result != USB_STOR_XFER_GOOD) 591 if (result != USB_STOR_XFER_GOOD)
588 return USB_STOR_TRANSPORT_ERROR; 592 return USB_STOR_TRANSPORT_ERROR;
589 593
@@ -606,8 +610,9 @@ static int usbat_multiple_write(struct us_data *us,
606 * other related details) are defined beforehand with _set_shuttle_features(). 610 * other related details) are defined beforehand with _set_shuttle_features().
607 */ 611 */
608static int usbat_read_blocks(struct us_data *us, 612static int usbat_read_blocks(struct us_data *us,
609 unsigned char *buffer, 613 unsigned char *buffer,
610 int len) 614 int len,
615 int use_sg)
611{ 616{
612 int result; 617 int result;
613 unsigned char *command = us->iobuf; 618 unsigned char *command = us->iobuf;
@@ -627,7 +632,7 @@ static int usbat_read_blocks(struct us_data *us,
627 return USB_STOR_TRANSPORT_FAILED; 632 return USB_STOR_TRANSPORT_FAILED;
628 633
629 /* Read the blocks we just asked for */ 634 /* Read the blocks we just asked for */
630 result = usbat_bulk_read(us, buffer, len); 635 result = usbat_bulk_read(us, buffer, len, use_sg);
631 if (result != USB_STOR_XFER_GOOD) 636 if (result != USB_STOR_XFER_GOOD)
632 return USB_STOR_TRANSPORT_FAILED; 637 return USB_STOR_TRANSPORT_FAILED;
633 638
@@ -648,7 +653,8 @@ static int usbat_read_blocks(struct us_data *us,
648 */ 653 */
649static int usbat_write_blocks(struct us_data *us, 654static int usbat_write_blocks(struct us_data *us,
650 unsigned char *buffer, 655 unsigned char *buffer,
651 int len) 656 int len,
657 int use_sg)
652{ 658{
653 int result; 659 int result;
654 unsigned char *command = us->iobuf; 660 unsigned char *command = us->iobuf;
@@ -668,7 +674,7 @@ static int usbat_write_blocks(struct us_data *us,
668 return USB_STOR_TRANSPORT_FAILED; 674 return USB_STOR_TRANSPORT_FAILED;
669 675
670 /* Write the data */ 676 /* Write the data */
671 result = usbat_bulk_write(us, buffer, len); 677 result = usbat_bulk_write(us, buffer, len, use_sg);
672 if (result != USB_STOR_XFER_GOOD) 678 if (result != USB_STOR_XFER_GOOD)
673 return USB_STOR_TRANSPORT_FAILED; 679 return USB_STOR_TRANSPORT_FAILED;
674 680
@@ -887,22 +893,28 @@ static int usbat_identify_device(struct us_data *us,
887 * Set the transport function based on the device type 893 * Set the transport function based on the device type
888 */ 894 */
889static int usbat_set_transport(struct us_data *us, 895static int usbat_set_transport(struct us_data *us,
890 struct usbat_info *info) 896 struct usbat_info *info,
897 int devicetype)
891{ 898{
892 int rc;
893 899
894 if (!info->devicetype) { 900 if (!info->devicetype)
895 rc = usbat_identify_device(us, info); 901 info->devicetype = devicetype;
896 if (rc != USB_STOR_TRANSPORT_GOOD) {
897 US_DEBUGP("usbat_set_transport: Could not identify device\n");
898 return 1;
899 }
900 }
901 902
902 if (usbat_get_device_type(us) == USBAT_DEV_HP8200) 903 if (!info->devicetype)
904 usbat_identify_device(us, info);
905
906 switch (info->devicetype) {
907 default:
908 return USB_STOR_TRANSPORT_ERROR;
909
910 case USBAT_DEV_HP8200:
903 us->transport = usbat_hp8200e_transport; 911 us->transport = usbat_hp8200e_transport;
904 else if (usbat_get_device_type(us) == USBAT_DEV_FLASH) 912 break;
913
914 case USBAT_DEV_FLASH:
905 us->transport = usbat_flash_transport; 915 us->transport = usbat_flash_transport;
916 break;
917 }
906 918
907 return 0; 919 return 0;
908} 920}
@@ -947,7 +959,7 @@ static int usbat_flash_get_sector_count(struct us_data *us,
947 msleep(100); 959 msleep(100);
948 960
949 /* Read the device identification data */ 961 /* Read the device identification data */
950 rc = usbat_read_block(us, reply, 512); 962 rc = usbat_read_block(us, reply, 512, 0);
951 if (rc != USB_STOR_TRANSPORT_GOOD) 963 if (rc != USB_STOR_TRANSPORT_GOOD)
952 goto leave; 964 goto leave;
953 965
@@ -1031,7 +1043,7 @@ static int usbat_flash_read_data(struct us_data *us,
1031 goto leave; 1043 goto leave;
1032 1044
1033 /* Read the data we just requested */ 1045 /* Read the data we just requested */
1034 result = usbat_read_blocks(us, buffer, len); 1046 result = usbat_read_blocks(us, buffer, len, 0);
1035 if (result != USB_STOR_TRANSPORT_GOOD) 1047 if (result != USB_STOR_TRANSPORT_GOOD)
1036 goto leave; 1048 goto leave;
1037 1049
@@ -1125,7 +1137,7 @@ static int usbat_flash_write_data(struct us_data *us,
1125 goto leave; 1137 goto leave;
1126 1138
1127 /* Write the data */ 1139 /* Write the data */
1128 result = usbat_write_blocks(us, buffer, len); 1140 result = usbat_write_blocks(us, buffer, len, 0);
1129 if (result != USB_STOR_TRANSPORT_GOOD) 1141 if (result != USB_STOR_TRANSPORT_GOOD)
1130 goto leave; 1142 goto leave;
1131 1143
@@ -1310,7 +1322,7 @@ static int usbat_select_and_test_registers(struct us_data *us)
1310/* 1322/*
1311 * Initialize the USBAT processor and the storage device 1323 * Initialize the USBAT processor and the storage device
1312 */ 1324 */
1313int init_usbat(struct us_data *us) 1325static int init_usbat(struct us_data *us, int devicetype)
1314{ 1326{
1315 int rc; 1327 int rc;
1316 struct usbat_info *info; 1328 struct usbat_info *info;
@@ -1392,7 +1404,7 @@ int init_usbat(struct us_data *us)
1392 US_DEBUGP("INIT 9\n"); 1404 US_DEBUGP("INIT 9\n");
1393 1405
1394 /* At this point, we need to detect which device we are using */ 1406 /* At this point, we need to detect which device we are using */
1395 if (usbat_set_transport(us, info)) 1407 if (usbat_set_transport(us, info, devicetype))
1396 return USB_STOR_TRANSPORT_ERROR; 1408 return USB_STOR_TRANSPORT_ERROR;
1397 1409
1398 US_DEBUGP("INIT 10\n"); 1410 US_DEBUGP("INIT 10\n");
@@ -1503,10 +1515,10 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us)
1503 * AT SPEED 4 IS UNRELIABLE!!! 1515 * AT SPEED 4 IS UNRELIABLE!!!
1504 */ 1516 */
1505 1517
1506 if ( (result = usbat_write_block(us, 1518 if ((result = usbat_write_block(us,
1507 USBAT_ATA, srb->cmnd, 12, 1519 USBAT_ATA, srb->cmnd, 12,
1508 srb->cmnd[0]==GPCMD_BLANK ? 75 : 10)) != 1520 (srb->cmnd[0]==GPCMD_BLANK ? 75 : 10), 0) !=
1509 USB_STOR_TRANSPORT_GOOD) { 1521 USB_STOR_TRANSPORT_GOOD)) {
1510 return result; 1522 return result;
1511 } 1523 }
1512 1524
@@ -1533,7 +1545,7 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us)
1533 len = *status; 1545 len = *status;
1534 1546
1535 1547
1536 result = usbat_read_block(us, srb->request_buffer, len); 1548 result = usbat_read_block(us, srb->request_buffer, len, srb->use_sg);
1537 1549
1538 /* Debug-print the first 32 bytes of the transfer */ 1550 /* Debug-print the first 32 bytes of the transfer */
1539 1551
@@ -1695,6 +1707,22 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us)
1695 return USB_STOR_TRANSPORT_FAILED; 1707 return USB_STOR_TRANSPORT_FAILED;
1696} 1708}
1697 1709
1710int init_usbat_cd(struct us_data *us)
1711{
1712 return init_usbat(us, USBAT_DEV_HP8200);
1713}
1714
1715
1716int init_usbat_flash(struct us_data *us)
1717{
1718 return init_usbat(us, USBAT_DEV_FLASH);
1719}
1720
1721int init_usbat_probe(struct us_data *us)
1722{
1723 return init_usbat(us, 0);
1724}
1725
1698/* 1726/*
1699 * Default transport function. Attempts to detect which transport function 1727 * Default transport function. Attempts to detect which transport function
1700 * should be called, makes it the new default, and calls it. 1728 * should be called, makes it the new default, and calls it.
@@ -1708,9 +1736,8 @@ int usbat_transport(struct scsi_cmnd *srb, struct us_data *us)
1708{ 1736{
1709 struct usbat_info *info = (struct usbat_info*) (us->extra); 1737 struct usbat_info *info = (struct usbat_info*) (us->extra);
1710 1738
1711 if (usbat_set_transport(us, info)) 1739 if (usbat_set_transport(us, info, 0))
1712 return USB_STOR_TRANSPORT_ERROR; 1740 return USB_STOR_TRANSPORT_ERROR;
1713 1741
1714 return us->transport(srb, us); 1742 return us->transport(srb, us);
1715} 1743}
1716
diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h
index 25e7d8b340b8..3ddf143a1dec 100644
--- a/drivers/usb/storage/shuttle_usbat.h
+++ b/drivers/usb/storage/shuttle_usbat.h
@@ -106,7 +106,9 @@
106#define USBAT_FEAT_ET2 0x01 106#define USBAT_FEAT_ET2 0x01
107 107
108extern int usbat_transport(struct scsi_cmnd *srb, struct us_data *us); 108extern int usbat_transport(struct scsi_cmnd *srb, struct us_data *us);
109extern int init_usbat(struct us_data *us); 109extern int init_usbat_cd(struct us_data *us);
110extern int init_usbat_flash(struct us_data *us);
111extern int init_usbat_probe(struct us_data *us);
110 112
111struct usbat_info { 113struct usbat_info {
112 int devicetype; 114 int devicetype;
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 7ca896a342e3..19b25c5cafd4 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -115,19 +115,6 @@ static void usb_stor_blocking_completion(struct urb *urb, struct pt_regs *regs)
115 115
116 complete(urb_done_ptr); 116 complete(urb_done_ptr);
117} 117}
118
119/* This is the timeout handler which will cancel an URB when its timeout
120 * expires.
121 */
122static void timeout_handler(unsigned long us_)
123{
124 struct us_data *us = (struct us_data *) us_;
125
126 if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->flags)) {
127 US_DEBUGP("Timeout -- cancelling URB\n");
128 usb_unlink_urb(us->current_urb);
129 }
130}
131 118
132/* This is the common part of the URB message submission code 119/* This is the common part of the URB message submission code
133 * 120 *
@@ -138,7 +125,7 @@ static void timeout_handler(unsigned long us_)
138static int usb_stor_msg_common(struct us_data *us, int timeout) 125static int usb_stor_msg_common(struct us_data *us, int timeout)
139{ 126{
140 struct completion urb_done; 127 struct completion urb_done;
141 struct timer_list to_timer; 128 long timeleft;
142 int status; 129 int status;
143 130
144 /* don't submit URBs during abort/disconnect processing */ 131 /* don't submit URBs during abort/disconnect processing */
@@ -185,22 +172,17 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
185 } 172 }
186 } 173 }
187 174
188 /* submit the timeout timer, if a timeout was requested */
189 if (timeout > 0) {
190 init_timer(&to_timer);
191 to_timer.expires = jiffies + timeout;
192 to_timer.function = timeout_handler;
193 to_timer.data = (unsigned long) us;
194 add_timer(&to_timer);
195 }
196
197 /* wait for the completion of the URB */ 175 /* wait for the completion of the URB */
198 wait_for_completion(&urb_done); 176 timeleft = wait_for_completion_interruptible_timeout(
199 clear_bit(US_FLIDX_URB_ACTIVE, &us->flags); 177 &urb_done, timeout ? : MAX_SCHEDULE_TIMEOUT);
200 178
201 /* clean up the timeout timer */ 179 clear_bit(US_FLIDX_URB_ACTIVE, &us->flags);
202 if (timeout > 0) 180
203 del_timer_sync(&to_timer); 181 if (timeleft <= 0) {
182 US_DEBUGP("%s -- cancelling URB\n",
183 timeleft == 0 ? "Timeout" : "Signal");
184 usb_unlink_urb(us->current_urb);
185 }
204 186
205 /* return the URB status */ 187 /* return the URB status */
206 return us->current_urb->status; 188 return us->current_urb->status;
@@ -721,16 +703,19 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
721 * device reset. */ 703 * device reset. */
722 Handle_Errors: 704 Handle_Errors:
723 705
724 /* Let the SCSI layer know we are doing a reset, set the 706 /* Set the RESETTING bit, and clear the ABORTING bit so that
725 * RESETTING bit, and clear the ABORTING bit so that the reset 707 * the reset may proceed. */
726 * may proceed. */
727 scsi_lock(us_to_host(us)); 708 scsi_lock(us_to_host(us));
728 usb_stor_report_bus_reset(us);
729 set_bit(US_FLIDX_RESETTING, &us->flags); 709 set_bit(US_FLIDX_RESETTING, &us->flags);
730 clear_bit(US_FLIDX_ABORTING, &us->flags); 710 clear_bit(US_FLIDX_ABORTING, &us->flags);
731 scsi_unlock(us_to_host(us)); 711 scsi_unlock(us_to_host(us));
732 712
713 /* We must release the device lock because the pre_reset routine
714 * will want to acquire it. */
715 mutex_unlock(&us->dev_mutex);
733 result = usb_stor_port_reset(us); 716 result = usb_stor_port_reset(us);
717 mutex_lock(&us->dev_mutex);
718
734 if (result < 0) { 719 if (result < 0) {
735 scsi_lock(us_to_host(us)); 720 scsi_lock(us_to_host(us));
736 usb_stor_report_device_reset(us); 721 usb_stor_report_device_reset(us);
@@ -1214,31 +1199,30 @@ int usb_stor_Bulk_reset(struct us_data *us)
1214 0, us->ifnum, NULL, 0); 1199 0, us->ifnum, NULL, 0);
1215} 1200}
1216 1201
1217/* Issue a USB port reset to the device. But don't do anything if 1202/* Issue a USB port reset to the device. The caller must not hold
1218 * there's more than one interface in the device, so that other users 1203 * us->dev_mutex.
1219 * are not affected. */ 1204 */
1220int usb_stor_port_reset(struct us_data *us) 1205int usb_stor_port_reset(struct us_data *us)
1221{ 1206{
1222 int result, rc; 1207 int result, rc_lock;
1223 1208
1224 if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { 1209 result = rc_lock =
1225 result = -EIO; 1210 usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
1226 US_DEBUGP("No reset during disconnect\n"); 1211 if (result < 0)
1227 } else if (us->pusb_dev->actconfig->desc.bNumInterfaces != 1) { 1212 US_DEBUGP("unable to lock device for reset: %d\n", result);
1228 result = -EBUSY; 1213 else {
1229 US_DEBUGP("Refusing to reset a multi-interface device\n"); 1214 /* Were we disconnected while waiting for the lock? */
1230 } else { 1215 if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
1231 result = rc = 1216 result = -EIO;
1232 usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf); 1217 US_DEBUGP("No reset during disconnect\n");
1233 if (result < 0) {
1234 US_DEBUGP("unable to lock device for reset: %d\n",
1235 result);
1236 } else { 1218 } else {
1237 result = usb_reset_device(us->pusb_dev); 1219 result = usb_reset_composite_device(
1238 if (rc) 1220 us->pusb_dev, us->pusb_intf);
1239 usb_unlock_device(us->pusb_dev); 1221 US_DEBUGP("usb_reset_composite_device returns %d\n",
1240 US_DEBUGP("usb_reset_device returns %d\n", result); 1222 result);
1241 } 1223 }
1224 if (rc_lock)
1225 usb_unlock_device(us->pusb_dev);
1242 } 1226 }
1243 return result; 1227 return result;
1244} 1228}
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index aec5ea8682d5..543244d421c1 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -78,12 +78,12 @@ UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200,
78UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001, 78UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001,
79 "HP", 79 "HP",
80 "CD-Writer+ 8200e", 80 "CD-Writer+ 8200e",
81 US_SC_8070, US_PR_USBAT, init_usbat, 0), 81 US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
82 82
83UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, 83UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001,
84 "HP", 84 "HP",
85 "CD-Writer+ CD-4e", 85 "CD-Writer+ CD-4e",
86 US_SC_8070, US_PR_USBAT, init_usbat, 0), 86 US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
87#endif 87#endif
88 88
89/* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net> 89/* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net>
@@ -133,6 +133,14 @@ UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100,
133 US_SC_DEVICE, US_PR_DEVICE, NULL, 133 US_SC_DEVICE, US_PR_DEVICE, NULL,
134 US_FL_IGNORE_RESIDUE ), 134 US_FL_IGNORE_RESIDUE ),
135 135
136/* Reported by Jiri Slaby <jirislaby@gmail.com> and
137 * Rene C. Castberg <Rene@Castberg.org> */
138UNUSUAL_DEV( 0x0421, 0x0446, 0x0100, 0x0100,
139 "Nokia",
140 "N80",
141 US_SC_DEVICE, US_PR_DEVICE, NULL,
142 US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
143
136/* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */ 144/* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
137UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, 145UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210,
138 "SMSC", 146 "SMSC",
@@ -216,6 +224,14 @@ UNUSUAL_DEV( 0x04a4, 0x0004, 0x0001, 0x0001,
216 "DVD-CAM DZ-MV100A Camcorder", 224 "DVD-CAM DZ-MV100A Camcorder",
217 US_SC_SCSI, US_PR_CB, NULL, US_FL_SINGLE_LUN), 225 US_SC_SCSI, US_PR_CB, NULL, US_FL_SINGLE_LUN),
218 226
227/* Patch for Nikon coolpix 2000
228 * Submitted by Fabien Cosse <fabien.cosse@wanadoo.fr>*/
229UNUSUAL_DEV( 0x04b0, 0x0301, 0x0010, 0x0010,
230 "NIKON",
231 "NIKON DSC E2000",
232 US_SC_DEVICE, US_PR_DEVICE,NULL,
233 US_FL_NOT_LOCKABLE ),
234
219/* Reported by Andreas Bockhold <andreas@bockionline.de> */ 235/* Reported by Andreas Bockhold <andreas@bockionline.de> */
220UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, 236UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100,
221 "NIKON", 237 "NIKON",
@@ -223,13 +239,12 @@ UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100,
223 US_SC_DEVICE, US_PR_DEVICE, NULL, 239 US_SC_DEVICE, US_PR_DEVICE, NULL,
224 US_FL_FIX_CAPACITY), 240 US_FL_FIX_CAPACITY),
225 241
226/* Patch for Nikon coolpix 2000 242/* Reported by Jamie Kitson <jamie@staberinde.fsnet.co.uk> */
227 * Submitted by Fabien Cosse <fabien.cosse@wanadoo.fr>*/ 243UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100,
228UNUSUAL_DEV( 0x04b0, 0x0301, 0x0010, 0x0010,
229 "NIKON", 244 "NIKON",
230 "NIKON DSC E2000", 245 "NIKON DSC D70s",
231 US_SC_DEVICE, US_PR_DEVICE,NULL, 246 US_SC_DEVICE, US_PR_DEVICE, NULL,
232 US_FL_NOT_LOCKABLE ), 247 US_FL_FIX_CAPACITY),
233 248
234/* BENQ DC5330 249/* BENQ DC5330
235 * Reported by Manuel Fombuena <mfombuena@ya.com> and 250 * Reported by Manuel Fombuena <mfombuena@ya.com> and
@@ -393,7 +408,7 @@ UNUSUAL_DEV( 0x04fc, 0x80c2, 0x0100, 0x0100,
393UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, 408UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999,
394 "Shuttle/SCM", 409 "Shuttle/SCM",
395 "USBAT-02", 410 "USBAT-02",
396 US_SC_SCSI, US_PR_USBAT, init_usbat, 411 US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
397 US_FL_SINGLE_LUN), 412 US_FL_SINGLE_LUN),
398#endif 413#endif
399 414
@@ -797,7 +812,7 @@ UNUSUAL_DEV( 0x0781, 0x0002, 0x0009, 0x0009,
797UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005, 812UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005,
798 "Sandisk", 813 "Sandisk",
799 "ImageMate SDDR-05b", 814 "ImageMate SDDR-05b",
800 US_SC_SCSI, US_PR_USBAT, init_usbat, 815 US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
801 US_FL_SINGLE_LUN ), 816 US_FL_SINGLE_LUN ),
802#endif 817#endif
803 818
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index dd108634348e..e232c7c89909 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -221,6 +221,37 @@ static int storage_resume(struct usb_interface *iface)
221#endif /* CONFIG_PM */ 221#endif /* CONFIG_PM */
222 222
223/* 223/*
224 * The next two routines get called just before and just after
225 * a USB port reset, whether from this driver or a different one.
226 */
227
228static void storage_pre_reset(struct usb_interface *iface)
229{
230 struct us_data *us = usb_get_intfdata(iface);
231
232 US_DEBUGP("%s\n", __FUNCTION__);
233
234 /* Make sure no command runs during the reset */
235 mutex_lock(&us->dev_mutex);
236}
237
238static void storage_post_reset(struct usb_interface *iface)
239{
240 struct us_data *us = usb_get_intfdata(iface);
241
242 US_DEBUGP("%s\n", __FUNCTION__);
243
244 /* Report the reset to the SCSI core */
245 scsi_lock(us_to_host(us));
246 usb_stor_report_bus_reset(us);
247 scsi_unlock(us_to_host(us));
248
249 /* FIXME: Notify the subdrivers that they need to reinitialize
250 * the device */
251 mutex_unlock(&us->dev_mutex);
252}
253
254/*
224 * fill_inquiry_response takes an unsigned char array (which must 255 * fill_inquiry_response takes an unsigned char array (which must
225 * be at least 36 characters) and populates the vendor name, 256 * be at least 36 characters) and populates the vendor name,
226 * product name, and revision fields. Then the array is copied 257 * product name, and revision fields. Then the array is copied
@@ -593,6 +624,15 @@ static int get_transport(struct us_data *us)
593 break; 624 break;
594#endif 625#endif
595 626
627#ifdef CONFIG_USB_STORAGE_ALAUDA
628 case US_PR_ALAUDA:
629 us->transport_name = "Alauda Control/Bulk";
630 us->transport = alauda_transport;
631 us->transport_reset = usb_stor_Bulk_reset;
632 us->max_lun = 1;
633 break;
634#endif
635
596 default: 636 default:
597 return -EIO; 637 return -EIO;
598 } 638 }
@@ -648,15 +688,6 @@ static int get_protocol(struct us_data *us)
648 break; 688 break;
649#endif 689#endif
650 690
651#ifdef CONFIG_USB_STORAGE_ALAUDA
652 case US_PR_ALAUDA:
653 us->transport_name = "Alauda Control/Bulk";
654 us->transport = alauda_transport;
655 us->transport_reset = usb_stor_Bulk_reset;
656 us->max_lun = 1;
657 break;
658#endif
659
660 default: 691 default:
661 return -EIO; 692 return -EIO;
662 } 693 }
@@ -1002,6 +1033,8 @@ static struct usb_driver usb_storage_driver = {
1002 .suspend = storage_suspend, 1033 .suspend = storage_suspend,
1003 .resume = storage_resume, 1034 .resume = storage_resume,
1004#endif 1035#endif
1036 .pre_reset = storage_pre_reset,
1037 .post_reset = storage_post_reset,
1005 .id_table = storage_usb_ids, 1038 .id_table = storage_usb_ids,
1006}; 1039};
1007 1040
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index 989e4d49e5bb..7f939d066a5a 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -313,8 +313,8 @@ static const char __init *mdacon_startup(void)
313 mda_num_columns = 80; 313 mda_num_columns = 80;
314 mda_num_lines = 25; 314 mda_num_lines = 25;
315 315
316 mda_vram_base = VGA_MAP_MEM(0xb0000);
317 mda_vram_len = 0x01000; 316 mda_vram_len = 0x01000;
317 mda_vram_base = VGA_MAP_MEM(0xb0000, mda_vram_len);
318 318
319 mda_index_port = 0x3b4; 319 mda_index_port = 0x3b4;
320 mda_value_port = 0x3b5; 320 mda_value_port = 0x3b5;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index d5a04b68c4d4..e64d42e2449e 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -391,7 +391,7 @@ static const char __init *vgacon_startup(void)
391 static struct resource ega_console_resource = 391 static struct resource ega_console_resource =
392 { "ega", 0x3B0, 0x3BF }; 392 { "ega", 0x3B0, 0x3BF };
393 vga_video_type = VIDEO_TYPE_EGAM; 393 vga_video_type = VIDEO_TYPE_EGAM;
394 vga_vram_end = 0xb8000; 394 vga_vram_size = 0x8000;
395 display_desc = "EGA+"; 395 display_desc = "EGA+";
396 request_resource(&ioport_resource, 396 request_resource(&ioport_resource,
397 &ega_console_resource); 397 &ega_console_resource);
@@ -401,7 +401,7 @@ static const char __init *vgacon_startup(void)
401 static struct resource mda2_console_resource = 401 static struct resource mda2_console_resource =
402 { "mda", 0x3BF, 0x3BF }; 402 { "mda", 0x3BF, 0x3BF };
403 vga_video_type = VIDEO_TYPE_MDA; 403 vga_video_type = VIDEO_TYPE_MDA;
404 vga_vram_end = 0xb2000; 404 vga_vram_size = 0x2000;
405 display_desc = "*MDA"; 405 display_desc = "*MDA";
406 request_resource(&ioport_resource, 406 request_resource(&ioport_resource,
407 &mda1_console_resource); 407 &mda1_console_resource);
@@ -418,7 +418,7 @@ static const char __init *vgacon_startup(void)
418 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { 418 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) {
419 int i; 419 int i;
420 420
421 vga_vram_end = 0xc0000; 421 vga_vram_size = 0x8000;
422 422
423 if (!ORIG_VIDEO_ISVGA) { 423 if (!ORIG_VIDEO_ISVGA) {
424 static struct resource ega_console_resource 424 static struct resource ega_console_resource
@@ -443,7 +443,7 @@ static const char __init *vgacon_startup(void)
443 * and COE=1 isn't necessarily a good idea) 443 * and COE=1 isn't necessarily a good idea)
444 */ 444 */
445 vga_vram_base = 0xa0000; 445 vga_vram_base = 0xa0000;
446 vga_vram_end = 0xb0000; 446 vga_vram_size = 0x10000;
447 outb_p(6, VGA_GFX_I); 447 outb_p(6, VGA_GFX_I);
448 outb_p(6, VGA_GFX_D); 448 outb_p(6, VGA_GFX_D);
449#endif 449#endif
@@ -475,7 +475,7 @@ static const char __init *vgacon_startup(void)
475 static struct resource cga_console_resource = 475 static struct resource cga_console_resource =
476 { "cga", 0x3D4, 0x3D5 }; 476 { "cga", 0x3D4, 0x3D5 };
477 vga_video_type = VIDEO_TYPE_CGA; 477 vga_video_type = VIDEO_TYPE_CGA;
478 vga_vram_end = 0xba000; 478 vga_vram_size = 0x2000;
479 display_desc = "*CGA"; 479 display_desc = "*CGA";
480 request_resource(&ioport_resource, 480 request_resource(&ioport_resource,
481 &cga_console_resource); 481 &cga_console_resource);
@@ -483,9 +483,8 @@ static const char __init *vgacon_startup(void)
483 } 483 }
484 } 484 }
485 485
486 vga_vram_base = VGA_MAP_MEM(vga_vram_base); 486 vga_vram_base = VGA_MAP_MEM(vga_vram_base, vga_vram_size);
487 vga_vram_end = VGA_MAP_MEM(vga_vram_end); 487 vga_vram_end = vga_vram_base + vga_vram_size;
488 vga_vram_size = vga_vram_end - vga_vram_base;
489 488
490 /* 489 /*
491 * Find out if there is a graphics card present. 490 * Find out if there is a graphics card present.
@@ -1020,14 +1019,14 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
1020 char *charmap; 1019 char *charmap;
1021 1020
1022 if (vga_video_type != VIDEO_TYPE_EGAM) { 1021 if (vga_video_type != VIDEO_TYPE_EGAM) {
1023 charmap = (char *) VGA_MAP_MEM(colourmap); 1022 charmap = (char *) VGA_MAP_MEM(colourmap, 0);
1024 beg = 0x0e; 1023 beg = 0x0e;
1025#ifdef VGA_CAN_DO_64KB 1024#ifdef VGA_CAN_DO_64KB
1026 if (vga_video_type == VIDEO_TYPE_VGAC) 1025 if (vga_video_type == VIDEO_TYPE_VGAC)
1027 beg = 0x06; 1026 beg = 0x06;
1028#endif 1027#endif
1029 } else { 1028 } else {
1030 charmap = (char *) VGA_MAP_MEM(blackwmap); 1029 charmap = (char *) VGA_MAP_MEM(blackwmap, 0);
1031 beg = 0x0a; 1030 beg = 0x0a;
1032 } 1031 }
1033 1032
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index f3f16fd9f231..4fd2a272e03d 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -1351,7 +1351,7 @@ static int __init vga16fb_probe(struct device *device)
1351 } 1351 }
1352 1352
1353 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */ 1353 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
1354 info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS); 1354 info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS, 0);
1355 1355
1356 if (!info->screen_base) { 1356 if (!info->screen_base) {
1357 printk(KERN_ERR "vga16fb: unable to map device\n"); 1357 printk(KERN_ERR "vga16fb: unable to map device\n");
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 537893a16014..8a04216e8b4d 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -759,7 +759,6 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
759 759
760 /* Discard our unneeded old files struct */ 760 /* Discard our unneeded old files struct */
761 if (files) { 761 if (files) {
762 steal_locks(files);
763 put_files_struct(files); 762 put_files_struct(files);
764 files = NULL; 763 files = NULL;
765 } 764 }
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index d73d75591a39..599f36fd0f67 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -203,7 +203,6 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
203 goto _error; 203 goto _error;
204 204
205 if (files) { 205 if (files) {
206 steal_locks(files);
207 put_files_struct(files); 206 put_files_struct(files);
208 files = NULL; 207 files = NULL;
209 } 208 }
diff --git a/fs/block_dev.c b/fs/block_dev.c
index f5958f413bd1..44aaba202f78 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -414,21 +414,31 @@ EXPORT_SYMBOL(bdput);
414static struct block_device *bd_acquire(struct inode *inode) 414static struct block_device *bd_acquire(struct inode *inode)
415{ 415{
416 struct block_device *bdev; 416 struct block_device *bdev;
417
417 spin_lock(&bdev_lock); 418 spin_lock(&bdev_lock);
418 bdev = inode->i_bdev; 419 bdev = inode->i_bdev;
419 if (bdev && igrab(bdev->bd_inode)) { 420 if (bdev) {
421 atomic_inc(&bdev->bd_inode->i_count);
420 spin_unlock(&bdev_lock); 422 spin_unlock(&bdev_lock);
421 return bdev; 423 return bdev;
422 } 424 }
423 spin_unlock(&bdev_lock); 425 spin_unlock(&bdev_lock);
426
424 bdev = bdget(inode->i_rdev); 427 bdev = bdget(inode->i_rdev);
425 if (bdev) { 428 if (bdev) {
426 spin_lock(&bdev_lock); 429 spin_lock(&bdev_lock);
427 if (inode->i_bdev) 430 if (!inode->i_bdev) {
428 __bd_forget(inode); 431 /*
429 inode->i_bdev = bdev; 432 * We take an additional bd_inode->i_count for inode,
430 inode->i_mapping = bdev->bd_inode->i_mapping; 433 * and it's released in clear_inode() of inode.
431 list_add(&inode->i_devices, &bdev->bd_inodes); 434 * So, we can access it via ->i_mapping always
435 * without igrab().
436 */
437 atomic_inc(&bdev->bd_inode->i_count);
438 inode->i_bdev = bdev;
439 inode->i_mapping = bdev->bd_inode->i_mapping;
440 list_add(&inode->i_devices, &bdev->bd_inodes);
441 }
432 spin_unlock(&bdev_lock); 442 spin_unlock(&bdev_lock);
433 } 443 }
434 return bdev; 444 return bdev;
@@ -438,10 +448,18 @@ static struct block_device *bd_acquire(struct inode *inode)
438 448
439void bd_forget(struct inode *inode) 449void bd_forget(struct inode *inode)
440{ 450{
451 struct block_device *bdev = NULL;
452
441 spin_lock(&bdev_lock); 453 spin_lock(&bdev_lock);
442 if (inode->i_bdev) 454 if (inode->i_bdev) {
455 if (inode->i_sb != blockdev_superblock)
456 bdev = inode->i_bdev;
443 __bd_forget(inode); 457 __bd_forget(inode);
458 }
444 spin_unlock(&bdev_lock); 459 spin_unlock(&bdev_lock);
460
461 if (bdev)
462 iput(bdev->bd_inode);
445} 463}
446 464
447int bd_claim(struct block_device *bdev, void *holder) 465int bd_claim(struct block_device *bdev, void *holder)
diff --git a/fs/dcache.c b/fs/dcache.c
index 940d188e5d14..59dbc92c2079 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -359,12 +359,13 @@ restart:
359} 359}
360 360
361/* 361/*
362 * Throw away a dentry - free the inode, dput the parent. 362 * Throw away a dentry - free the inode, dput the parent. This requires that
363 * This requires that the LRU list has already been 363 * the LRU list has already been removed.
364 * removed. 364 *
365 * Called with dcache_lock, drops it and then regains. 365 * Called with dcache_lock, drops it and then regains.
366 * Called with dentry->d_lock held, drops it.
366 */ 367 */
367static inline void prune_one_dentry(struct dentry * dentry) 368static void prune_one_dentry(struct dentry * dentry)
368{ 369{
369 struct dentry * parent; 370 struct dentry * parent;
370 371
@@ -382,6 +383,8 @@ static inline void prune_one_dentry(struct dentry * dentry)
382/** 383/**
383 * prune_dcache - shrink the dcache 384 * prune_dcache - shrink the dcache
384 * @count: number of entries to try and free 385 * @count: number of entries to try and free
386 * @sb: if given, ignore dentries for other superblocks
387 * which are being unmounted.
385 * 388 *
386 * Shrink the dcache. This is done when we need 389 * Shrink the dcache. This is done when we need
387 * more memory, or simply when we need to unmount 390 * more memory, or simply when we need to unmount
@@ -392,16 +395,29 @@ static inline void prune_one_dentry(struct dentry * dentry)
392 * all the dentries are in use. 395 * all the dentries are in use.
393 */ 396 */
394 397
395static void prune_dcache(int count) 398static void prune_dcache(int count, struct super_block *sb)
396{ 399{
397 spin_lock(&dcache_lock); 400 spin_lock(&dcache_lock);
398 for (; count ; count--) { 401 for (; count ; count--) {
399 struct dentry *dentry; 402 struct dentry *dentry;
400 struct list_head *tmp; 403 struct list_head *tmp;
404 struct rw_semaphore *s_umount;
401 405
402 cond_resched_lock(&dcache_lock); 406 cond_resched_lock(&dcache_lock);
403 407
404 tmp = dentry_unused.prev; 408 tmp = dentry_unused.prev;
409 if (unlikely(sb)) {
410 /* Try to find a dentry for this sb, but don't try
411 * too hard, if they aren't near the tail they will
412 * be moved down again soon
413 */
414 int skip = count;
415 while (skip && tmp != &dentry_unused &&
416 list_entry(tmp, struct dentry, d_lru)->d_sb != sb) {
417 skip--;
418 tmp = tmp->prev;
419 }
420 }
405 if (tmp == &dentry_unused) 421 if (tmp == &dentry_unused)
406 break; 422 break;
407 list_del_init(tmp); 423 list_del_init(tmp);
@@ -427,7 +443,45 @@ static void prune_dcache(int count)
427 spin_unlock(&dentry->d_lock); 443 spin_unlock(&dentry->d_lock);
428 continue; 444 continue;
429 } 445 }
430 prune_one_dentry(dentry); 446 /*
447 * If the dentry is not DCACHED_REFERENCED, it is time
448 * to remove it from the dcache, provided the super block is
449 * NULL (which means we are trying to reclaim memory)
450 * or this dentry belongs to the same super block that
451 * we want to shrink.
452 */
453 /*
454 * If this dentry is for "my" filesystem, then I can prune it
455 * without taking the s_umount lock (I already hold it).
456 */
457 if (sb && dentry->d_sb == sb) {
458 prune_one_dentry(dentry);
459 continue;
460 }
461 /*
462 * ...otherwise we need to be sure this filesystem isn't being
463 * unmounted, otherwise we could race with
464 * generic_shutdown_super(), and end up holding a reference to
465 * an inode while the filesystem is unmounted.
466 * So we try to get s_umount, and make sure s_root isn't NULL.
467 * (Take a local copy of s_umount to avoid a use-after-free of
468 * `dentry').
469 */
470 s_umount = &dentry->d_sb->s_umount;
471 if (down_read_trylock(s_umount)) {
472 if (dentry->d_sb->s_root != NULL) {
473 prune_one_dentry(dentry);
474 up_read(s_umount);
475 continue;
476 }
477 up_read(s_umount);
478 }
479 spin_unlock(&dentry->d_lock);
480 /* Cannot remove the first dentry, and it isn't appropriate
481 * to move it to the head of the list, so give up, and try
482 * later
483 */
484 break;
431 } 485 }
432 spin_unlock(&dcache_lock); 486 spin_unlock(&dcache_lock);
433} 487}
@@ -630,7 +684,7 @@ void shrink_dcache_parent(struct dentry * parent)
630 int found; 684 int found;
631 685
632 while ((found = select_parent(parent)) != 0) 686 while ((found = select_parent(parent)) != 0)
633 prune_dcache(found); 687 prune_dcache(found, parent->d_sb);
634} 688}
635 689
636/** 690/**
@@ -643,9 +697,10 @@ void shrink_dcache_parent(struct dentry * parent)
643 * done under dcache_lock. 697 * done under dcache_lock.
644 * 698 *
645 */ 699 */
646void shrink_dcache_anon(struct hlist_head *head) 700void shrink_dcache_anon(struct super_block *sb)
647{ 701{
648 struct hlist_node *lp; 702 struct hlist_node *lp;
703 struct hlist_head *head = &sb->s_anon;
649 int found; 704 int found;
650 do { 705 do {
651 found = 0; 706 found = 0;
@@ -668,7 +723,7 @@ void shrink_dcache_anon(struct hlist_head *head)
668 } 723 }
669 } 724 }
670 spin_unlock(&dcache_lock); 725 spin_unlock(&dcache_lock);
671 prune_dcache(found); 726 prune_dcache(found, sb);
672 } while(found); 727 } while(found);
673} 728}
674 729
@@ -689,7 +744,7 @@ static int shrink_dcache_memory(int nr, gfp_t gfp_mask)
689 if (nr) { 744 if (nr) {
690 if (!(gfp_mask & __GFP_FS)) 745 if (!(gfp_mask & __GFP_FS))
691 return -1; 746 return -1;
692 prune_dcache(nr); 747 prune_dcache(nr, NULL);
693 } 748 }
694 return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure; 749 return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure;
695} 750}
diff --git a/fs/exec.c b/fs/exec.c
index d07858c0b7c4..0b88bf646143 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -866,7 +866,6 @@ int flush_old_exec(struct linux_binprm * bprm)
866 bprm->mm = NULL; /* We're using it now */ 866 bprm->mm = NULL; /* We're using it now */
867 867
868 /* This is the point of no return */ 868 /* This is the point of no return */
869 steal_locks(files);
870 put_files_struct(files); 869 put_files_struct(files);
871 870
872 current->sas_ss_sp = current->sas_ss_size = 0; 871 current->sas_ss_sp = current->sas_ss_size = 0;
diff --git a/fs/locks.c b/fs/locks.c
index ab61a8b54829..69435c68c1ed 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2206,63 +2206,6 @@ int lock_may_write(struct inode *inode, loff_t start, unsigned long len)
2206 2206
2207EXPORT_SYMBOL(lock_may_write); 2207EXPORT_SYMBOL(lock_may_write);
2208 2208
2209static inline void __steal_locks(struct file *file, fl_owner_t from)
2210{
2211 struct inode *inode = file->f_dentry->d_inode;
2212 struct file_lock *fl = inode->i_flock;
2213
2214 while (fl) {
2215 if (fl->fl_file == file && fl->fl_owner == from)
2216 fl->fl_owner = current->files;
2217 fl = fl->fl_next;
2218 }
2219}
2220
2221/* When getting ready for executing a binary, we make sure that current
2222 * has a files_struct on its own. Before dropping the old files_struct,
2223 * we take over ownership of all locks for all file descriptors we own.
2224 * Note that we may accidentally steal a lock for a file that a sibling
2225 * has created since the unshare_files() call.
2226 */
2227void steal_locks(fl_owner_t from)
2228{
2229 struct files_struct *files = current->files;
2230 int i, j;
2231 struct fdtable *fdt;
2232
2233 if (from == files)
2234 return;
2235
2236 lock_kernel();
2237 j = 0;
2238
2239 /*
2240 * We are not taking a ref to the file structures, so
2241 * we need to acquire ->file_lock.
2242 */
2243 spin_lock(&files->file_lock);
2244 fdt = files_fdtable(files);
2245 for (;;) {
2246 unsigned long set;
2247 i = j * __NFDBITS;
2248 if (i >= fdt->max_fdset || i >= fdt->max_fds)
2249 break;
2250 set = fdt->open_fds->fds_bits[j++];
2251 while (set) {
2252 if (set & 1) {
2253 struct file *file = fdt->fd[i];
2254 if (file)
2255 __steal_locks(file, from);
2256 }
2257 i++;
2258 set >>= 1;
2259 }
2260 }
2261 spin_unlock(&files->file_lock);
2262 unlock_kernel();
2263}
2264EXPORT_SYMBOL(steal_locks);
2265
2266static int __init filelock_init(void) 2209static int __init filelock_init(void)
2267{ 2210{
2268 filelock_cache = kmem_cache_create("file_lock_cache", 2211 filelock_cache = kmem_cache_create("file_lock_cache",
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index c63a83e8da98..36e1e136bb0c 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -1484,14 +1484,15 @@ static inline void ntfs_flush_dcache_pages(struct page **pages,
1484 unsigned nr_pages) 1484 unsigned nr_pages)
1485{ 1485{
1486 BUG_ON(!nr_pages); 1486 BUG_ON(!nr_pages);
1487 /*
1488 * Warning: Do not do the decrement at the same time as the call to
1489 * flush_dcache_page() because it is a NULL macro on i386 and hence the
1490 * decrement never happens so the loop never terminates.
1491 */
1487 do { 1492 do {
1488 /* 1493 --nr_pages;
1489 * Warning: Do not do the decrement at the same time as the
1490 * call because flush_dcache_page() is a NULL macro on i386
1491 * and hence the decrement never happens.
1492 */
1493 flush_dcache_page(pages[nr_pages]); 1494 flush_dcache_page(pages[nr_pages]);
1494 } while (--nr_pages > 0); 1495 } while (nr_pages > 0);
1495} 1496}
1496 1497
1497/** 1498/**
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 7ef1f094de91..8851b81e7c5a 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -329,6 +329,7 @@ void delete_partition(struct gendisk *disk, int part)
329 p->ios[0] = p->ios[1] = 0; 329 p->ios[0] = p->ios[1] = 0;
330 p->sectors[0] = p->sectors[1] = 0; 330 p->sectors[0] = p->sectors[1] = 0;
331 devfs_remove("%s/part%d", disk->devfs_name, part); 331 devfs_remove("%s/part%d", disk->devfs_name, part);
332 sysfs_remove_link(&p->kobj, "subsystem");
332 if (p->holder_dir) 333 if (p->holder_dir)
333 kobject_unregister(p->holder_dir); 334 kobject_unregister(p->holder_dir);
334 kobject_uevent(&p->kobj, KOBJ_REMOVE); 335 kobject_uevent(&p->kobj, KOBJ_REMOVE);
@@ -363,6 +364,7 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
363 kobject_add(&p->kobj); 364 kobject_add(&p->kobj);
364 if (!disk->part_uevent_suppress) 365 if (!disk->part_uevent_suppress)
365 kobject_uevent(&p->kobj, KOBJ_ADD); 366 kobject_uevent(&p->kobj, KOBJ_ADD);
367 sysfs_create_link(&p->kobj, &block_subsys.kset.kobj, "subsystem");
366 partition_sysfs_add_subdir(p); 368 partition_sysfs_add_subdir(p);
367 disk->part[part-1] = p; 369 disk->part[part-1] = p;
368} 370}
@@ -398,6 +400,7 @@ static void disk_sysfs_symlinks(struct gendisk *disk)
398 kfree(disk_name); 400 kfree(disk_name);
399 } 401 }
400 } 402 }
403 sysfs_create_link(&disk->kobj, &block_subsys.kset.kobj, "subsystem");
401} 404}
402 405
403/* Not exported, helper to add_disk(). */ 406/* Not exported, helper to add_disk(). */
@@ -548,5 +551,6 @@ void del_gendisk(struct gendisk *disk)
548 put_device(disk->driverfs_dev); 551 put_device(disk->driverfs_dev);
549 disk->driverfs_dev = NULL; 552 disk->driverfs_dev = NULL;
550 } 553 }
554 sysfs_remove_link(&disk->kobj, "subsystem");
551 kobject_del(&disk->kobj); 555 kobject_del(&disk->kobj);
552} 556}
diff --git a/fs/super.c b/fs/super.c
index a66f66bb8049..9d5c2add7228 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -231,7 +231,7 @@ void generic_shutdown_super(struct super_block *sb)
231 if (root) { 231 if (root) {
232 sb->s_root = NULL; 232 sb->s_root = NULL;
233 shrink_dcache_parent(root); 233 shrink_dcache_parent(root);
234 shrink_dcache_anon(&sb->s_anon); 234 shrink_dcache_anon(sb);
235 dput(root); 235 dput(root);
236 fsync_super(sb); 236 fsync_super(sb);
237 lock_super(sb); 237 lock_super(sb);
diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig
index bac27d66151d..26b364c9d62c 100644
--- a/fs/xfs/Kconfig
+++ b/fs/xfs/Kconfig
@@ -1,6 +1,5 @@
1config XFS_FS 1config XFS_FS
2 tristate "XFS filesystem support" 2 tristate "XFS filesystem support"
3 select EXPORTFS if NFSD!=n
4 help 3 help
5 XFS is a high performance journaling filesystem which originated 4 XFS is a high performance journaling filesystem which originated
6 on the SGI IRIX platform. It is completely multi-threaded, can 5 on the SGI IRIX platform. It is completely multi-threaded, can
@@ -18,11 +17,6 @@ config XFS_FS
18 system of your root partition is compiled as a module, you'll need 17 system of your root partition is compiled as a module, you'll need
19 to use an initial ramdisk (initrd) to boot. 18 to use an initial ramdisk (initrd) to boot.
20 19
21config XFS_EXPORT
22 bool
23 depends on XFS_FS && EXPORTFS
24 default y
25
26config XFS_QUOTA 20config XFS_QUOTA
27 bool "XFS Quota support" 21 bool "XFS Quota support"
28 depends on XFS_FS 22 depends on XFS_FS
@@ -65,18 +59,19 @@ config XFS_POSIX_ACL
65 If you don't know what Access Control Lists are, say N. 59 If you don't know what Access Control Lists are, say N.
66 60
67config XFS_RT 61config XFS_RT
68 bool "XFS Realtime support (EXPERIMENTAL)" 62 bool "XFS Realtime subvolume support"
69 depends on XFS_FS && EXPERIMENTAL 63 depends on XFS_FS
70 help 64 help
71 If you say Y here you will be able to mount and use XFS filesystems 65 If you say Y here you will be able to mount and use XFS filesystems
72 which contain a realtime subvolume. The realtime subvolume is a 66 which contain a realtime subvolume. The realtime subvolume is a
73 separate area of disk space where only file data is stored. The 67 separate area of disk space where only file data is stored. It was
74 realtime subvolume is designed to provide very deterministic 68 originally designed to provide deterministic data rates suitable
75 data rates suitable for media streaming applications. 69 for media streaming applications, but is also useful as a generic
76 70 mechanism for ensuring data and metadata/log I/Os are completely
77 See the xfs man page in section 5 for a bit more information. 71 separated. Regular file I/Os are isolated to a separate device
72 from all other requests, and this can be done quite transparently
73 to applications via the inherit-realtime directory inode flag.
78 74
79 This feature is unsupported at this time, is not yet fully 75 See the xfs man page in section 5 for additional information.
80 functional, and may cause serious problems.
81 76
82 If unsure, say N. 77 If unsure, say N.
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6
index 5d73eaa1971f..9e7f85986d0d 100644
--- a/fs/xfs/Makefile-linux-2.6
+++ b/fs/xfs/Makefile-linux-2.6
@@ -59,7 +59,6 @@ xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
59xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o 59xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o
60xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o 60xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o
61xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o 61xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o
62xfs-$(CONFIG_XFS_EXPORT) += $(XFS_LINUX)/xfs_export.o
63 62
64 63
65xfs-y += xfs_alloc.o \ 64xfs-y += xfs_alloc.o \
@@ -73,14 +72,12 @@ xfs-y += xfs_alloc.o \
73 xfs_btree.o \ 72 xfs_btree.o \
74 xfs_buf_item.o \ 73 xfs_buf_item.o \
75 xfs_da_btree.o \ 74 xfs_da_btree.o \
76 xfs_dir.o \
77 xfs_dir2.o \ 75 xfs_dir2.o \
78 xfs_dir2_block.o \ 76 xfs_dir2_block.o \
79 xfs_dir2_data.o \ 77 xfs_dir2_data.o \
80 xfs_dir2_leaf.o \ 78 xfs_dir2_leaf.o \
81 xfs_dir2_node.o \ 79 xfs_dir2_node.o \
82 xfs_dir2_sf.o \ 80 xfs_dir2_sf.o \
83 xfs_dir_leaf.o \
84 xfs_error.o \ 81 xfs_error.o \
85 xfs_extfree_item.o \ 82 xfs_extfree_item.o \
86 xfs_fsops.o \ 83 xfs_fsops.o \
@@ -117,6 +114,7 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \
117 kmem.o \ 114 kmem.o \
118 xfs_aops.o \ 115 xfs_aops.o \
119 xfs_buf.o \ 116 xfs_buf.o \
117 xfs_export.o \
120 xfs_file.o \ 118 xfs_file.o \
121 xfs_fs_subr.o \ 119 xfs_fs_subr.o \
122 xfs_globals.o \ 120 xfs_globals.o \
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h
index 2cfd33d4d8aa..939bd84bc7ee 100644
--- a/fs/xfs/linux-2.6/kmem.h
+++ b/fs/xfs/linux-2.6/kmem.h
@@ -23,42 +23,6 @@
23#include <linux/mm.h> 23#include <linux/mm.h>
24 24
25/* 25/*
26 * Process flags handling
27 */
28
29#define PFLAGS_TEST_NOIO() (current->flags & PF_NOIO)
30#define PFLAGS_TEST_FSTRANS() (current->flags & PF_FSTRANS)
31
32#define PFLAGS_SET_NOIO() do { \
33 current->flags |= PF_NOIO; \
34} while (0)
35
36#define PFLAGS_CLEAR_NOIO() do { \
37 current->flags &= ~PF_NOIO; \
38} while (0)
39
40/* these could be nested, so we save state */
41#define PFLAGS_SET_FSTRANS(STATEP) do { \
42 *(STATEP) = current->flags; \
43 current->flags |= PF_FSTRANS; \
44} while (0)
45
46#define PFLAGS_CLEAR_FSTRANS(STATEP) do { \
47 *(STATEP) = current->flags; \
48 current->flags &= ~PF_FSTRANS; \
49} while (0)
50
51/* Restore the PF_FSTRANS state to what was saved in STATEP */
52#define PFLAGS_RESTORE_FSTRANS(STATEP) do { \
53 current->flags = ((current->flags & ~PF_FSTRANS) | \
54 (*(STATEP) & PF_FSTRANS)); \
55} while (0)
56
57#define PFLAGS_DUP(OSTATEP, NSTATEP) do { \
58 *(NSTATEP) = *(OSTATEP); \
59} while (0)
60
61/*
62 * General memory allocation interfaces 26 * General memory allocation interfaces
63 */ 27 */
64 28
@@ -83,7 +47,7 @@ kmem_flags_convert(unsigned int __nocast flags)
83 lflags = GFP_ATOMIC | __GFP_NOWARN; 47 lflags = GFP_ATOMIC | __GFP_NOWARN;
84 } else { 48 } else {
85 lflags = GFP_KERNEL | __GFP_NOWARN; 49 lflags = GFP_KERNEL | __GFP_NOWARN;
86 if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS)) 50 if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS))
87 lflags &= ~__GFP_FS; 51 lflags &= ~__GFP_FS;
88 } 52 }
89 return lflags; 53 return lflags;
diff --git a/fs/xfs/linux-2.6/mrlock.h b/fs/xfs/linux-2.6/mrlock.h
index 1b262b790d9c..32e1ce0f04c9 100644
--- a/fs/xfs/linux-2.6/mrlock.h
+++ b/fs/xfs/linux-2.6/mrlock.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -28,7 +28,7 @@ typedef struct {
28} mrlock_t; 28} mrlock_t;
29 29
30#define mrinit(mrp, name) \ 30#define mrinit(mrp, name) \
31 ( (mrp)->mr_writer = 0, init_rwsem(&(mrp)->mr_lock) ) 31 do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0)
32#define mrlock_init(mrp, t,n,s) mrinit(mrp, n) 32#define mrlock_init(mrp, t,n,s) mrinit(mrp, n)
33#define mrfree(mrp) do { } while (0) 33#define mrfree(mrp) do { } while (0)
34#define mraccess(mrp) mraccessf(mrp, 0) 34#define mraccess(mrp) mraccessf(mrp, 0)
diff --git a/fs/xfs/linux-2.6/sema.h b/fs/xfs/linux-2.6/sema.h
index 194a84490bd1..b25090094cca 100644
--- a/fs/xfs/linux-2.6/sema.h
+++ b/fs/xfs/linux-2.6/sema.h
@@ -34,20 +34,21 @@ typedef struct semaphore sema_t;
34#define initnsema(sp, val, name) sema_init(sp, val) 34#define initnsema(sp, val, name) sema_init(sp, val)
35#define psema(sp, b) down(sp) 35#define psema(sp, b) down(sp)
36#define vsema(sp) up(sp) 36#define vsema(sp) up(sp)
37#define valusema(sp) (atomic_read(&(sp)->count)) 37#define freesema(sema) do { } while (0)
38#define freesema(sema) 38
39static inline int issemalocked(sema_t *sp)
40{
41 return down_trylock(sp) || (up(sp), 0);
42}
39 43
40/* 44/*
41 * Map cpsema (try to get the sema) to down_trylock. We need to switch 45 * Map cpsema (try to get the sema) to down_trylock. We need to switch
42 * the return values since cpsema returns 1 (acquired) 0 (failed) and 46 * the return values since cpsema returns 1 (acquired) 0 (failed) and
43 * down_trylock returns the reverse 0 (acquired) 1 (failed). 47 * down_trylock returns the reverse 0 (acquired) 1 (failed).
44 */ 48 */
45 49static inline int cpsema(sema_t *sp)
46#define cpsema(sp) (down_trylock(sp) ? 0 : 1) 50{
47 51 return down_trylock(sp) ? 0 : 1;
48/* 52}
49 * Didn't do cvsema(sp). Not sure how to map this to up/down/...
50 * It does a vsema if the values is < 0 other wise nothing.
51 */
52 53
53#endif /* __XFS_SUPPORT_SEMA_H__ */ 54#endif /* __XFS_SUPPORT_SEMA_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 4d191ef39b67..3e807b828e22 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -21,7 +21,6 @@
21#include "xfs_inum.h" 21#include "xfs_inum.h"
22#include "xfs_sb.h" 22#include "xfs_sb.h"
23#include "xfs_ag.h" 23#include "xfs_ag.h"
24#include "xfs_dir.h"
25#include "xfs_dir2.h" 24#include "xfs_dir2.h"
26#include "xfs_trans.h" 25#include "xfs_trans.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
@@ -29,7 +28,6 @@
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_alloc_btree.h" 29#include "xfs_alloc_btree.h"
31#include "xfs_ialloc_btree.h" 30#include "xfs_ialloc_btree.h"
32#include "xfs_dir_sf.h"
33#include "xfs_dir2_sf.h" 31#include "xfs_dir2_sf.h"
34#include "xfs_attr_sf.h" 32#include "xfs_attr_sf.h"
35#include "xfs_dinode.h" 33#include "xfs_dinode.h"
@@ -76,7 +74,7 @@ xfs_page_trace(
76 int mask) 74 int mask)
77{ 75{
78 xfs_inode_t *ip; 76 xfs_inode_t *ip;
79 vnode_t *vp = vn_from_inode(inode); 77 bhv_vnode_t *vp = vn_from_inode(inode);
80 loff_t isize = i_size_read(inode); 78 loff_t isize = i_size_read(inode);
81 loff_t offset = page_offset(page); 79 loff_t offset = page_offset(page);
82 int delalloc = -1, unmapped = -1, unwritten = -1; 80 int delalloc = -1, unmapped = -1, unwritten = -1;
@@ -136,9 +134,10 @@ xfs_destroy_ioend(
136 134
137 for (bh = ioend->io_buffer_head; bh; bh = next) { 135 for (bh = ioend->io_buffer_head; bh; bh = next) {
138 next = bh->b_private; 136 next = bh->b_private;
139 bh->b_end_io(bh, ioend->io_uptodate); 137 bh->b_end_io(bh, !ioend->io_error);
140 } 138 }
141 139 if (unlikely(ioend->io_error))
140 vn_ioerror(ioend->io_vnode, ioend->io_error, __FILE__,__LINE__);
142 vn_iowake(ioend->io_vnode); 141 vn_iowake(ioend->io_vnode);
143 mempool_free(ioend, xfs_ioend_pool); 142 mempool_free(ioend, xfs_ioend_pool);
144} 143}
@@ -180,13 +179,12 @@ xfs_end_bio_unwritten(
180 void *data) 179 void *data)
181{ 180{
182 xfs_ioend_t *ioend = data; 181 xfs_ioend_t *ioend = data;
183 vnode_t *vp = ioend->io_vnode; 182 bhv_vnode_t *vp = ioend->io_vnode;
184 xfs_off_t offset = ioend->io_offset; 183 xfs_off_t offset = ioend->io_offset;
185 size_t size = ioend->io_size; 184 size_t size = ioend->io_size;
186 int error;
187 185
188 if (ioend->io_uptodate) 186 if (likely(!ioend->io_error))
189 VOP_BMAP(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL, error); 187 bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL);
190 xfs_destroy_ioend(ioend); 188 xfs_destroy_ioend(ioend);
191} 189}
192 190
@@ -211,7 +209,7 @@ xfs_alloc_ioend(
211 * all the I/O from calling the completion routine too early. 209 * all the I/O from calling the completion routine too early.
212 */ 210 */
213 atomic_set(&ioend->io_remaining, 1); 211 atomic_set(&ioend->io_remaining, 1);
214 ioend->io_uptodate = 1; /* cleared if any I/O fails */ 212 ioend->io_error = 0;
215 ioend->io_list = NULL; 213 ioend->io_list = NULL;
216 ioend->io_type = type; 214 ioend->io_type = type;
217 ioend->io_vnode = vn_from_inode(inode); 215 ioend->io_vnode = vn_from_inode(inode);
@@ -239,10 +237,10 @@ xfs_map_blocks(
239 xfs_iomap_t *mapp, 237 xfs_iomap_t *mapp,
240 int flags) 238 int flags)
241{ 239{
242 vnode_t *vp = vn_from_inode(inode); 240 bhv_vnode_t *vp = vn_from_inode(inode);
243 int error, nmaps = 1; 241 int error, nmaps = 1;
244 242
245 VOP_BMAP(vp, offset, count, flags, mapp, &nmaps, error); 243 error = bhv_vop_bmap(vp, offset, count, flags, mapp, &nmaps);
246 if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE))) 244 if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)))
247 VMODIFY(vp); 245 VMODIFY(vp);
248 return -error; 246 return -error;
@@ -271,16 +269,14 @@ xfs_end_bio(
271 if (bio->bi_size) 269 if (bio->bi_size)
272 return 1; 270 return 1;
273 271
274 ASSERT(ioend);
275 ASSERT(atomic_read(&bio->bi_cnt) >= 1); 272 ASSERT(atomic_read(&bio->bi_cnt) >= 1);
273 ioend->io_error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : error;
276 274
277 /* Toss bio and pass work off to an xfsdatad thread */ 275 /* Toss bio and pass work off to an xfsdatad thread */
278 if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
279 ioend->io_uptodate = 0;
280 bio->bi_private = NULL; 276 bio->bi_private = NULL;
281 bio->bi_end_io = NULL; 277 bio->bi_end_io = NULL;
282
283 bio_put(bio); 278 bio_put(bio);
279
284 xfs_finish_ioend(ioend); 280 xfs_finish_ioend(ioend);
285 return 0; 281 return 0;
286} 282}
@@ -1127,7 +1123,7 @@ xfs_vm_writepage(
1127 * then mark the page dirty again and leave the page 1123 * then mark the page dirty again and leave the page
1128 * as is. 1124 * as is.
1129 */ 1125 */
1130 if (PFLAGS_TEST_FSTRANS() && need_trans) 1126 if (current_test_flags(PF_FSTRANS) && need_trans)
1131 goto out_fail; 1127 goto out_fail;
1132 1128
1133 /* 1129 /*
@@ -1158,6 +1154,18 @@ out_unlock:
1158 return error; 1154 return error;
1159} 1155}
1160 1156
1157STATIC int
1158xfs_vm_writepages(
1159 struct address_space *mapping,
1160 struct writeback_control *wbc)
1161{
1162 struct bhv_vnode *vp = vn_from_inode(mapping->host);
1163
1164 if (VN_TRUNC(vp))
1165 VUNTRUNCATE(vp);
1166 return generic_writepages(mapping, wbc);
1167}
1168
1161/* 1169/*
1162 * Called to move a page into cleanable state - and from there 1170 * Called to move a page into cleanable state - and from there
1163 * to be released. Possibly the page is already clean. We always 1171 * to be released. Possibly the page is already clean. We always
@@ -1204,7 +1212,7 @@ xfs_vm_releasepage(
1204 /* If we are already inside a transaction or the thread cannot 1212 /* If we are already inside a transaction or the thread cannot
1205 * do I/O, we cannot release this page. 1213 * do I/O, we cannot release this page.
1206 */ 1214 */
1207 if (PFLAGS_TEST_FSTRANS()) 1215 if (current_test_flags(PF_FSTRANS))
1208 return 0; 1216 return 0;
1209 1217
1210 /* 1218 /*
@@ -1231,7 +1239,7 @@ __xfs_get_blocks(
1231 int direct, 1239 int direct,
1232 bmapi_flags_t flags) 1240 bmapi_flags_t flags)
1233{ 1241{
1234 vnode_t *vp = vn_from_inode(inode); 1242 bhv_vnode_t *vp = vn_from_inode(inode);
1235 xfs_iomap_t iomap; 1243 xfs_iomap_t iomap;
1236 xfs_off_t offset; 1244 xfs_off_t offset;
1237 ssize_t size; 1245 ssize_t size;
@@ -1241,8 +1249,8 @@ __xfs_get_blocks(
1241 offset = (xfs_off_t)iblock << inode->i_blkbits; 1249 offset = (xfs_off_t)iblock << inode->i_blkbits;
1242 ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); 1250 ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
1243 size = bh_result->b_size; 1251 size = bh_result->b_size;
1244 VOP_BMAP(vp, offset, size, 1252 error = bhv_vop_bmap(vp, offset, size,
1245 create ? flags : BMAPI_READ, &iomap, &niomap, error); 1253 create ? flags : BMAPI_READ, &iomap, &niomap);
1246 if (error) 1254 if (error)
1247 return -error; 1255 return -error;
1248 if (niomap == 0) 1256 if (niomap == 0)
@@ -1370,13 +1378,13 @@ xfs_vm_direct_IO(
1370{ 1378{
1371 struct file *file = iocb->ki_filp; 1379 struct file *file = iocb->ki_filp;
1372 struct inode *inode = file->f_mapping->host; 1380 struct inode *inode = file->f_mapping->host;
1373 vnode_t *vp = vn_from_inode(inode); 1381 bhv_vnode_t *vp = vn_from_inode(inode);
1374 xfs_iomap_t iomap; 1382 xfs_iomap_t iomap;
1375 int maps = 1; 1383 int maps = 1;
1376 int error; 1384 int error;
1377 ssize_t ret; 1385 ssize_t ret;
1378 1386
1379 VOP_BMAP(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps, error); 1387 error = bhv_vop_bmap(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps);
1380 if (error) 1388 if (error)
1381 return -error; 1389 return -error;
1382 1390
@@ -1409,14 +1417,12 @@ xfs_vm_bmap(
1409 sector_t block) 1417 sector_t block)
1410{ 1418{
1411 struct inode *inode = (struct inode *)mapping->host; 1419 struct inode *inode = (struct inode *)mapping->host;
1412 vnode_t *vp = vn_from_inode(inode); 1420 bhv_vnode_t *vp = vn_from_inode(inode);
1413 int error;
1414 1421
1415 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 1422 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
1416 1423 bhv_vop_rwlock(vp, VRWLOCK_READ);
1417 VOP_RWLOCK(vp, VRWLOCK_READ); 1424 bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
1418 VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error); 1425 bhv_vop_rwunlock(vp, VRWLOCK_READ);
1419 VOP_RWUNLOCK(vp, VRWLOCK_READ);
1420 return generic_block_bmap(mapping, block, xfs_get_blocks); 1426 return generic_block_bmap(mapping, block, xfs_get_blocks);
1421} 1427}
1422 1428
@@ -1452,6 +1458,7 @@ struct address_space_operations xfs_address_space_operations = {
1452 .readpage = xfs_vm_readpage, 1458 .readpage = xfs_vm_readpage,
1453 .readpages = xfs_vm_readpages, 1459 .readpages = xfs_vm_readpages,
1454 .writepage = xfs_vm_writepage, 1460 .writepage = xfs_vm_writepage,
1461 .writepages = xfs_vm_writepages,
1455 .sync_page = block_sync_page, 1462 .sync_page = block_sync_page,
1456 .releasepage = xfs_vm_releasepage, 1463 .releasepage = xfs_vm_releasepage,
1457 .invalidatepage = xfs_vm_invalidatepage, 1464 .invalidatepage = xfs_vm_invalidatepage,
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 60716543c68b..706d8c781b8a 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2005 Silicon Graphics, Inc. 2 * Copyright (c) 2005-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -30,9 +30,9 @@ typedef void (*xfs_ioend_func_t)(void *);
30typedef struct xfs_ioend { 30typedef struct xfs_ioend {
31 struct xfs_ioend *io_list; /* next ioend in chain */ 31 struct xfs_ioend *io_list; /* next ioend in chain */
32 unsigned int io_type; /* delalloc / unwritten */ 32 unsigned int io_type; /* delalloc / unwritten */
33 unsigned int io_uptodate; /* I/O status register */ 33 int io_error; /* I/O error code */
34 atomic_t io_remaining; /* hold count */ 34 atomic_t io_remaining; /* hold count */
35 struct vnode *io_vnode; /* file being written to */ 35 struct bhv_vnode *io_vnode; /* file being written to */
36 struct buffer_head *io_buffer_head;/* buffer linked list head */ 36 struct buffer_head *io_buffer_head;/* buffer linked list head */
37 struct buffer_head *io_buffer_tail;/* buffer linked list tail */ 37 struct buffer_head *io_buffer_tail;/* buffer linked list tail */
38 size_t io_size; /* size of the extent */ 38 size_t io_size; /* size of the extent */
@@ -43,4 +43,4 @@ typedef struct xfs_ioend {
43extern struct address_space_operations xfs_address_space_operations; 43extern struct address_space_operations xfs_address_space_operations;
44extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int); 44extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int);
45 45
46#endif /* __XFS_IOPS_H__ */ 46#endif /* __XFS_AOPS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index b768ea910bbe..5fb75d9151f2 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -21,7 +21,6 @@
21#include "xfs_log.h" 21#include "xfs_log.h"
22#include "xfs_trans.h" 22#include "xfs_trans.h"
23#include "xfs_sb.h" 23#include "xfs_sb.h"
24#include "xfs_dir.h"
25#include "xfs_mount.h" 24#include "xfs_mount.h"
26#include "xfs_export.h" 25#include "xfs_export.h"
27 26
@@ -97,7 +96,7 @@ xfs_fs_encode_fh(
97 int len; 96 int len;
98 int is64 = 0; 97 int is64 = 0;
99#if XFS_BIG_INUMS 98#if XFS_BIG_INUMS
100 vfs_t *vfs = vfs_from_sb(inode->i_sb); 99 bhv_vfs_t *vfs = vfs_from_sb(inode->i_sb);
101 100
102 if (!(vfs->vfs_flag & VFS_32BITINODES)) { 101 if (!(vfs->vfs_flag & VFS_32BITINODES)) {
103 /* filesystem may contain 64bit inode numbers */ 102 /* filesystem may contain 64bit inode numbers */
@@ -136,13 +135,13 @@ xfs_fs_get_dentry(
136 struct super_block *sb, 135 struct super_block *sb,
137 void *data) 136 void *data)
138{ 137{
139 vnode_t *vp; 138 bhv_vnode_t *vp;
140 struct inode *inode; 139 struct inode *inode;
141 struct dentry *result; 140 struct dentry *result;
142 vfs_t *vfsp = vfs_from_sb(sb); 141 bhv_vfs_t *vfsp = vfs_from_sb(sb);
143 int error; 142 int error;
144 143
145 VFS_VGET(vfsp, &vp, (fid_t *)data, error); 144 error = bhv_vfs_vget(vfsp, &vp, (fid_t *)data);
146 if (error || vp == NULL) 145 if (error || vp == NULL)
147 return ERR_PTR(-ESTALE) ; 146 return ERR_PTR(-ESTALE) ;
148 147
@@ -160,12 +159,12 @@ xfs_fs_get_parent(
160 struct dentry *child) 159 struct dentry *child)
161{ 160{
162 int error; 161 int error;
163 vnode_t *vp, *cvp; 162 bhv_vnode_t *vp, *cvp;
164 struct dentry *parent; 163 struct dentry *parent;
165 164
166 cvp = NULL; 165 cvp = NULL;
167 vp = vn_from_inode(child->d_inode); 166 vp = vn_from_inode(child->d_inode);
168 VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error); 167 error = bhv_vop_lookup(vp, &dotdot, &cvp, 0, NULL, NULL);
169 if (unlikely(error)) 168 if (unlikely(error))
170 return ERR_PTR(-error); 169 return ERR_PTR(-error);
171 170
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index c847416f6d10..70662371bb11 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -21,7 +21,6 @@
21#include "xfs_inum.h" 21#include "xfs_inum.h"
22#include "xfs_sb.h" 22#include "xfs_sb.h"
23#include "xfs_ag.h" 23#include "xfs_ag.h"
24#include "xfs_dir.h"
25#include "xfs_dir2.h" 24#include "xfs_dir2.h"
26#include "xfs_trans.h" 25#include "xfs_trans.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_alloc.h" 31#include "xfs_alloc.h"
33#include "xfs_btree.h" 32#include "xfs_btree.h"
34#include "xfs_attr_sf.h" 33#include "xfs_attr_sf.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
38#include "xfs_inode.h" 36#include "xfs_inode.h"
@@ -58,15 +56,12 @@ __xfs_file_read(
58{ 56{
59 struct iovec iov = {buf, count}; 57 struct iovec iov = {buf, count};
60 struct file *file = iocb->ki_filp; 58 struct file *file = iocb->ki_filp;
61 vnode_t *vp = vn_from_inode(file->f_dentry->d_inode); 59 bhv_vnode_t *vp = vn_from_inode(file->f_dentry->d_inode);
62 ssize_t rval;
63 60
64 BUG_ON(iocb->ki_pos != pos); 61 BUG_ON(iocb->ki_pos != pos);
65
66 if (unlikely(file->f_flags & O_DIRECT)) 62 if (unlikely(file->f_flags & O_DIRECT))
67 ioflags |= IO_ISDIRECT; 63 ioflags |= IO_ISDIRECT;
68 VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval); 64 return bhv_vop_read(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
69 return rval;
70} 65}
71 66
72STATIC ssize_t 67STATIC ssize_t
@@ -100,15 +95,12 @@ __xfs_file_write(
100 struct iovec iov = {(void __user *)buf, count}; 95 struct iovec iov = {(void __user *)buf, count};
101 struct file *file = iocb->ki_filp; 96 struct file *file = iocb->ki_filp;
102 struct inode *inode = file->f_mapping->host; 97 struct inode *inode = file->f_mapping->host;
103 vnode_t *vp = vn_from_inode(inode); 98 bhv_vnode_t *vp = vn_from_inode(inode);
104 ssize_t rval;
105 99
106 BUG_ON(iocb->ki_pos != pos); 100 BUG_ON(iocb->ki_pos != pos);
107 if (unlikely(file->f_flags & O_DIRECT)) 101 if (unlikely(file->f_flags & O_DIRECT))
108 ioflags |= IO_ISDIRECT; 102 ioflags |= IO_ISDIRECT;
109 103 return bhv_vop_write(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
110 VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
111 return rval;
112} 104}
113 105
114STATIC ssize_t 106STATIC ssize_t
@@ -140,7 +132,7 @@ __xfs_file_readv(
140 loff_t *ppos) 132 loff_t *ppos)
141{ 133{
142 struct inode *inode = file->f_mapping->host; 134 struct inode *inode = file->f_mapping->host;
143 vnode_t *vp = vn_from_inode(inode); 135 bhv_vnode_t *vp = vn_from_inode(inode);
144 struct kiocb kiocb; 136 struct kiocb kiocb;
145 ssize_t rval; 137 ssize_t rval;
146 138
@@ -149,7 +141,8 @@ __xfs_file_readv(
149 141
150 if (unlikely(file->f_flags & O_DIRECT)) 142 if (unlikely(file->f_flags & O_DIRECT))
151 ioflags |= IO_ISDIRECT; 143 ioflags |= IO_ISDIRECT;
152 VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval); 144 rval = bhv_vop_read(vp, &kiocb, iov, nr_segs,
145 &kiocb.ki_pos, ioflags, NULL);
153 146
154 *ppos = kiocb.ki_pos; 147 *ppos = kiocb.ki_pos;
155 return rval; 148 return rval;
@@ -184,7 +177,7 @@ __xfs_file_writev(
184 loff_t *ppos) 177 loff_t *ppos)
185{ 178{
186 struct inode *inode = file->f_mapping->host; 179 struct inode *inode = file->f_mapping->host;
187 vnode_t *vp = vn_from_inode(inode); 180 bhv_vnode_t *vp = vn_from_inode(inode);
188 struct kiocb kiocb; 181 struct kiocb kiocb;
189 ssize_t rval; 182 ssize_t rval;
190 183
@@ -193,7 +186,8 @@ __xfs_file_writev(
193 if (unlikely(file->f_flags & O_DIRECT)) 186 if (unlikely(file->f_flags & O_DIRECT))
194 ioflags |= IO_ISDIRECT; 187 ioflags |= IO_ISDIRECT;
195 188
196 VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval); 189 rval = bhv_vop_write(vp, &kiocb, iov, nr_segs,
190 &kiocb.ki_pos, ioflags, NULL);
197 191
198 *ppos = kiocb.ki_pos; 192 *ppos = kiocb.ki_pos;
199 return rval; 193 return rval;
@@ -227,11 +221,8 @@ xfs_file_sendfile(
227 read_actor_t actor, 221 read_actor_t actor,
228 void *target) 222 void *target)
229{ 223{
230 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); 224 return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
231 ssize_t rval; 225 filp, pos, 0, count, actor, target, NULL);
232
233 VOP_SENDFILE(vp, filp, pos, 0, count, actor, target, NULL, rval);
234 return rval;
235} 226}
236 227
237STATIC ssize_t 228STATIC ssize_t
@@ -242,11 +233,8 @@ xfs_file_sendfile_invis(
242 read_actor_t actor, 233 read_actor_t actor,
243 void *target) 234 void *target)
244{ 235{
245 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); 236 return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
246 ssize_t rval; 237 filp, pos, IO_INVIS, count, actor, target, NULL);
247
248 VOP_SENDFILE(vp, filp, pos, IO_INVIS, count, actor, target, NULL, rval);
249 return rval;
250} 238}
251 239
252STATIC ssize_t 240STATIC ssize_t
@@ -257,11 +245,8 @@ xfs_file_splice_read(
257 size_t len, 245 size_t len,
258 unsigned int flags) 246 unsigned int flags)
259{ 247{
260 vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); 248 return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
261 ssize_t rval; 249 infilp, ppos, pipe, len, flags, 0, NULL);
262
263 VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, 0, NULL, rval);
264 return rval;
265} 250}
266 251
267STATIC ssize_t 252STATIC ssize_t
@@ -272,11 +257,9 @@ xfs_file_splice_read_invis(
272 size_t len, 257 size_t len,
273 unsigned int flags) 258 unsigned int flags)
274{ 259{
275 vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); 260 return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
276 ssize_t rval; 261 infilp, ppos, pipe, len, flags, IO_INVIS,
277 262 NULL);
278 VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, IO_INVIS, NULL, rval);
279 return rval;
280} 263}
281 264
282STATIC ssize_t 265STATIC ssize_t
@@ -287,11 +270,8 @@ xfs_file_splice_write(
287 size_t len, 270 size_t len,
288 unsigned int flags) 271 unsigned int flags)
289{ 272{
290 vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); 273 return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
291 ssize_t rval; 274 pipe, outfilp, ppos, len, flags, 0, NULL);
292
293 VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, 0, NULL, rval);
294 return rval;
295} 275}
296 276
297STATIC ssize_t 277STATIC ssize_t
@@ -302,11 +282,9 @@ xfs_file_splice_write_invis(
302 size_t len, 282 size_t len,
303 unsigned int flags) 283 unsigned int flags)
304{ 284{
305 vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); 285 return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
306 ssize_t rval; 286 pipe, outfilp, ppos, len, flags, IO_INVIS,
307 287 NULL);
308 VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, IO_INVIS, NULL, rval);
309 return rval;
310} 288}
311 289
312STATIC int 290STATIC int
@@ -314,13 +292,17 @@ xfs_file_open(
314 struct inode *inode, 292 struct inode *inode,
315 struct file *filp) 293 struct file *filp)
316{ 294{
317 vnode_t *vp = vn_from_inode(inode);
318 int error;
319
320 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) 295 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
321 return -EFBIG; 296 return -EFBIG;
322 VOP_OPEN(vp, NULL, error); 297 return -bhv_vop_open(vn_from_inode(inode), NULL);
323 return -error; 298}
299
300STATIC int
301xfs_file_close(
302 struct file *filp)
303{
304 return -bhv_vop_close(vn_from_inode(filp->f_dentry->d_inode), 0,
305 file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL);
324} 306}
325 307
326STATIC int 308STATIC int
@@ -328,12 +310,11 @@ xfs_file_release(
328 struct inode *inode, 310 struct inode *inode,
329 struct file *filp) 311 struct file *filp)
330{ 312{
331 vnode_t *vp = vn_from_inode(inode); 313 bhv_vnode_t *vp = vn_from_inode(inode);
332 int error = 0;
333 314
334 if (vp) 315 if (vp)
335 VOP_RELEASE(vp, error); 316 return -bhv_vop_release(vp);
336 return -error; 317 return 0;
337} 318}
338 319
339STATIC int 320STATIC int
@@ -342,15 +323,14 @@ xfs_file_fsync(
342 struct dentry *dentry, 323 struct dentry *dentry,
343 int datasync) 324 int datasync)
344{ 325{
345 struct inode *inode = dentry->d_inode; 326 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
346 vnode_t *vp = vn_from_inode(inode);
347 int error;
348 int flags = FSYNC_WAIT; 327 int flags = FSYNC_WAIT;
349 328
350 if (datasync) 329 if (datasync)
351 flags |= FSYNC_DATA; 330 flags |= FSYNC_DATA;
352 VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error); 331 if (VN_TRUNC(vp))
353 return -error; 332 VUNTRUNCATE(vp);
333 return -bhv_vop_fsync(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1);
354} 334}
355 335
356#ifdef CONFIG_XFS_DMAPI 336#ifdef CONFIG_XFS_DMAPI
@@ -361,16 +341,11 @@ xfs_vm_nopage(
361 int *type) 341 int *type)
362{ 342{
363 struct inode *inode = area->vm_file->f_dentry->d_inode; 343 struct inode *inode = area->vm_file->f_dentry->d_inode;
364 vnode_t *vp = vn_from_inode(inode); 344 bhv_vnode_t *vp = vn_from_inode(inode);
365 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
366 int error;
367 345
368 ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI); 346 ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI);
369 347 if (XFS_SEND_MMAP(XFS_VFSTOM(vp->v_vfsp), area, 0))
370 error = XFS_SEND_MMAP(mp, area, 0);
371 if (error)
372 return NULL; 348 return NULL;
373
374 return filemap_nopage(area, address, type); 349 return filemap_nopage(area, address, type);
375} 350}
376#endif /* CONFIG_XFS_DMAPI */ 351#endif /* CONFIG_XFS_DMAPI */
@@ -382,7 +357,7 @@ xfs_file_readdir(
382 filldir_t filldir) 357 filldir_t filldir)
383{ 358{
384 int error = 0; 359 int error = 0;
385 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); 360 bhv_vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
386 uio_t uio; 361 uio_t uio;
387 iovec_t iov; 362 iovec_t iov;
388 int eof = 0; 363 int eof = 0;
@@ -417,7 +392,7 @@ xfs_file_readdir(
417 392
418 start_offset = uio.uio_offset; 393 start_offset = uio.uio_offset;
419 394
420 VOP_READDIR(vp, &uio, NULL, &eof, error); 395 error = bhv_vop_readdir(vp, &uio, NULL, &eof);
421 if ((uio.uio_offset == start_offset) || error) { 396 if ((uio.uio_offset == start_offset) || error) {
422 size = 0; 397 size = 0;
423 break; 398 break;
@@ -456,38 +431,28 @@ xfs_file_mmap(
456 struct file *filp, 431 struct file *filp,
457 struct vm_area_struct *vma) 432 struct vm_area_struct *vma)
458{ 433{
459 struct inode *ip = filp->f_dentry->d_inode;
460 vnode_t *vp = vn_from_inode(ip);
461 vattr_t vattr;
462 int error;
463
464 vma->vm_ops = &xfs_file_vm_ops; 434 vma->vm_ops = &xfs_file_vm_ops;
465 435
466#ifdef CONFIG_XFS_DMAPI 436#ifdef CONFIG_XFS_DMAPI
467 if (vp->v_vfsp->vfs_flag & VFS_DMI) { 437 if (vn_from_inode(filp->f_dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI)
468 vma->vm_ops = &xfs_dmapi_file_vm_ops; 438 vma->vm_ops = &xfs_dmapi_file_vm_ops;
469 }
470#endif /* CONFIG_XFS_DMAPI */ 439#endif /* CONFIG_XFS_DMAPI */
471 440
472 vattr.va_mask = XFS_AT_UPDATIME; 441 file_accessed(filp);
473 VOP_SETATTR(vp, &vattr, XFS_AT_UPDATIME, NULL, error);
474 if (likely(!error))
475 __vn_revalidate(vp, &vattr); /* update flags */
476 return 0; 442 return 0;
477} 443}
478 444
479
480STATIC long 445STATIC long
481xfs_file_ioctl( 446xfs_file_ioctl(
482 struct file *filp, 447 struct file *filp,
483 unsigned int cmd, 448 unsigned int cmd,
484 unsigned long arg) 449 unsigned long p)
485{ 450{
486 int error; 451 int error;
487 struct inode *inode = filp->f_dentry->d_inode; 452 struct inode *inode = filp->f_dentry->d_inode;
488 vnode_t *vp = vn_from_inode(inode); 453 bhv_vnode_t *vp = vn_from_inode(inode);
489 454
490 VOP_IOCTL(vp, inode, filp, 0, cmd, (void __user *)arg, error); 455 error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p);
491 VMODIFY(vp); 456 VMODIFY(vp);
492 457
493 /* NOTE: some of the ioctl's return positive #'s as a 458 /* NOTE: some of the ioctl's return positive #'s as a
@@ -503,13 +468,13 @@ STATIC long
503xfs_file_ioctl_invis( 468xfs_file_ioctl_invis(
504 struct file *filp, 469 struct file *filp,
505 unsigned int cmd, 470 unsigned int cmd,
506 unsigned long arg) 471 unsigned long p)
507{ 472{
508 struct inode *inode = filp->f_dentry->d_inode;
509 vnode_t *vp = vn_from_inode(inode);
510 int error; 473 int error;
474 struct inode *inode = filp->f_dentry->d_inode;
475 bhv_vnode_t *vp = vn_from_inode(inode);
511 476
512 VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error); 477 error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p);
513 VMODIFY(vp); 478 VMODIFY(vp);
514 479
515 /* NOTE: some of the ioctl's return positive #'s as a 480 /* NOTE: some of the ioctl's return positive #'s as a
@@ -528,7 +493,7 @@ xfs_vm_mprotect(
528 struct vm_area_struct *vma, 493 struct vm_area_struct *vma,
529 unsigned int newflags) 494 unsigned int newflags)
530{ 495{
531 vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode); 496 bhv_vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode);
532 int error = 0; 497 int error = 0;
533 498
534 if (vp->v_vfsp->vfs_flag & VFS_DMI) { 499 if (vp->v_vfsp->vfs_flag & VFS_DMI) {
@@ -554,24 +519,19 @@ STATIC int
554xfs_file_open_exec( 519xfs_file_open_exec(
555 struct inode *inode) 520 struct inode *inode)
556{ 521{
557 vnode_t *vp = vn_from_inode(inode); 522 bhv_vnode_t *vp = vn_from_inode(inode);
558 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
559 int error = 0;
560 xfs_inode_t *ip;
561 523
562 if (vp->v_vfsp->vfs_flag & VFS_DMI) { 524 if (unlikely(vp->v_vfsp->vfs_flag & VFS_DMI)) {
563 ip = xfs_vtoi(vp); 525 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
564 if (!ip) { 526 xfs_inode_t *ip = xfs_vtoi(vp);
565 error = -EINVAL; 527
566 goto open_exec_out; 528 if (!ip)
567 } 529 return -EINVAL;
568 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)) { 530 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ))
569 error = -XFS_SEND_DATA(mp, DM_EVENT_READ, vp, 531 return -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
570 0, 0, 0, NULL); 532 0, 0, 0, NULL);
571 }
572 } 533 }
573open_exec_out: 534 return 0;
574 return error;
575} 535}
576#endif /* HAVE_FOP_OPEN_EXEC */ 536#endif /* HAVE_FOP_OPEN_EXEC */
577 537
@@ -592,6 +552,7 @@ const struct file_operations xfs_file_operations = {
592#endif 552#endif
593 .mmap = xfs_file_mmap, 553 .mmap = xfs_file_mmap,
594 .open = xfs_file_open, 554 .open = xfs_file_open,
555 .flush = xfs_file_close,
595 .release = xfs_file_release, 556 .release = xfs_file_release,
596 .fsync = xfs_file_fsync, 557 .fsync = xfs_file_fsync,
597#ifdef HAVE_FOP_OPEN_EXEC 558#ifdef HAVE_FOP_OPEN_EXEC
@@ -616,6 +577,7 @@ const struct file_operations xfs_invis_file_operations = {
616#endif 577#endif
617 .mmap = xfs_file_mmap, 578 .mmap = xfs_file_mmap,
618 .open = xfs_file_open, 579 .open = xfs_file_open,
580 .flush = xfs_file_close,
619 .release = xfs_file_release, 581 .release = xfs_file_release,
620 .fsync = xfs_file_fsync, 582 .fsync = xfs_file_fsync,
621}; 583};
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index 575f2a790f31..dc0562828e76 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2002,2005-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -15,40 +15,12 @@
15 * along with this program; if not, write the Free Software Foundation, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18
19#include "xfs.h" 18#include "xfs.h"
20 19
21/* 20int fs_noerr(void) { return 0; }
22 * Stub for no-op vnode operations that return error status. 21int fs_nosys(void) { return ENOSYS; }
23 */ 22void fs_noval(void) { return; }
24int
25fs_noerr(void)
26{
27 return 0;
28}
29 23
30/*
31 * Operation unsupported under this file system.
32 */
33int
34fs_nosys(void)
35{
36 return ENOSYS;
37}
38
39/*
40 * Stub for inactive, strategy, and read/write lock/unlock. Does nothing.
41 */
42/* ARGSUSED */
43void
44fs_noval(void)
45{
46}
47
48/*
49 * vnode pcache layer for vnode_tosspages.
50 * 'last' parameter unused but left in for IRIX compatibility
51 */
52void 24void
53fs_tosspages( 25fs_tosspages(
54 bhv_desc_t *bdp, 26 bhv_desc_t *bdp,
@@ -56,18 +28,13 @@ fs_tosspages(
56 xfs_off_t last, 28 xfs_off_t last,
57 int fiopt) 29 int fiopt)
58{ 30{
59 vnode_t *vp = BHV_TO_VNODE(bdp); 31 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
60 struct inode *ip = vn_to_inode(vp); 32 struct inode *ip = vn_to_inode(vp);
61 33
62 if (VN_CACHED(vp)) 34 if (VN_CACHED(vp))
63 truncate_inode_pages(ip->i_mapping, first); 35 truncate_inode_pages(ip->i_mapping, first);
64} 36}
65 37
66
67/*
68 * vnode pcache layer for vnode_flushinval_pages.
69 * 'last' parameter unused but left in for IRIX compatibility
70 */
71void 38void
72fs_flushinval_pages( 39fs_flushinval_pages(
73 bhv_desc_t *bdp, 40 bhv_desc_t *bdp,
@@ -75,20 +42,17 @@ fs_flushinval_pages(
75 xfs_off_t last, 42 xfs_off_t last,
76 int fiopt) 43 int fiopt)
77{ 44{
78 vnode_t *vp = BHV_TO_VNODE(bdp); 45 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
79 struct inode *ip = vn_to_inode(vp); 46 struct inode *ip = vn_to_inode(vp);
80 47
81 if (VN_CACHED(vp)) { 48 if (VN_CACHED(vp)) {
49 if (VN_TRUNC(vp))
50 VUNTRUNCATE(vp);
82 filemap_write_and_wait(ip->i_mapping); 51 filemap_write_and_wait(ip->i_mapping);
83
84 truncate_inode_pages(ip->i_mapping, first); 52 truncate_inode_pages(ip->i_mapping, first);
85 } 53 }
86} 54}
87 55
88/*
89 * vnode pcache layer for vnode_flush_pages.
90 * 'last' parameter unused but left in for IRIX compatibility
91 */
92int 56int
93fs_flush_pages( 57fs_flush_pages(
94 bhv_desc_t *bdp, 58 bhv_desc_t *bdp,
@@ -97,15 +61,16 @@ fs_flush_pages(
97 uint64_t flags, 61 uint64_t flags,
98 int fiopt) 62 int fiopt)
99{ 63{
100 vnode_t *vp = BHV_TO_VNODE(bdp); 64 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
101 struct inode *ip = vn_to_inode(vp); 65 struct inode *ip = vn_to_inode(vp);
102 66
103 if (VN_CACHED(vp)) { 67 if (VN_DIRTY(vp)) {
68 if (VN_TRUNC(vp))
69 VUNTRUNCATE(vp);
104 filemap_fdatawrite(ip->i_mapping); 70 filemap_fdatawrite(ip->i_mapping);
105 if (flags & XFS_B_ASYNC) 71 if (flags & XFS_B_ASYNC)
106 return 0; 72 return 0;
107 filemap_fdatawait(ip->i_mapping); 73 filemap_fdatawait(ip->i_mapping);
108 } 74 }
109
110 return 0; 75 return 0;
111} 76}
diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/linux-2.6/xfs_globals.c
index 6e8085f34635..6c162c3dde7e 100644
--- a/fs/xfs/linux-2.6/xfs_globals.c
+++ b/fs/xfs/linux-2.6/xfs_globals.c
@@ -45,6 +45,7 @@ xfs_param_t xfs_params = {
45 .xfs_buf_age = { 1*100, 15*100, 7200*100}, 45 .xfs_buf_age = { 1*100, 15*100, 7200*100},
46 .inherit_nosym = { 0, 0, 1 }, 46 .inherit_nosym = { 0, 0, 1 },
47 .rotorstep = { 1, 1, 255 }, 47 .rotorstep = { 1, 1, 255 },
48 .inherit_nodfrg = { 0, 1, 1 },
48}; 49};
49 50
50/* 51/*
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 84478491609b..6e52a5dd38d8 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -31,7 +30,6 @@
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_attr_sf.h" 33#include "xfs_attr_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -78,7 +76,7 @@ xfs_find_handle(
78 xfs_handle_t handle; 76 xfs_handle_t handle;
79 xfs_fsop_handlereq_t hreq; 77 xfs_fsop_handlereq_t hreq;
80 struct inode *inode; 78 struct inode *inode;
81 struct vnode *vp; 79 bhv_vnode_t *vp;
82 80
83 if (copy_from_user(&hreq, arg, sizeof(hreq))) 81 if (copy_from_user(&hreq, arg, sizeof(hreq)))
84 return -XFS_ERROR(EFAULT); 82 return -XFS_ERROR(EFAULT);
@@ -192,7 +190,7 @@ xfs_vget_fsop_handlereq(
192 xfs_mount_t *mp, 190 xfs_mount_t *mp,
193 struct inode *parinode, /* parent inode pointer */ 191 struct inode *parinode, /* parent inode pointer */
194 xfs_fsop_handlereq_t *hreq, 192 xfs_fsop_handlereq_t *hreq,
195 vnode_t **vp, 193 bhv_vnode_t **vp,
196 struct inode **inode) 194 struct inode **inode)
197{ 195{
198 void __user *hanp; 196 void __user *hanp;
@@ -202,7 +200,7 @@ xfs_vget_fsop_handlereq(
202 xfs_handle_t handle; 200 xfs_handle_t handle;
203 xfs_inode_t *ip; 201 xfs_inode_t *ip;
204 struct inode *inodep; 202 struct inode *inodep;
205 vnode_t *vpp; 203 bhv_vnode_t *vpp;
206 xfs_ino_t ino; 204 xfs_ino_t ino;
207 __u32 igen; 205 __u32 igen;
208 int error; 206 int error;
@@ -277,7 +275,7 @@ xfs_open_by_handle(
277 struct file *filp; 275 struct file *filp;
278 struct inode *inode; 276 struct inode *inode;
279 struct dentry *dentry; 277 struct dentry *dentry;
280 vnode_t *vp; 278 bhv_vnode_t *vp;
281 xfs_fsop_handlereq_t hreq; 279 xfs_fsop_handlereq_t hreq;
282 280
283 if (!capable(CAP_SYS_ADMIN)) 281 if (!capable(CAP_SYS_ADMIN))
@@ -362,7 +360,7 @@ xfs_readlink_by_handle(
362 struct uio auio; 360 struct uio auio;
363 struct inode *inode; 361 struct inode *inode;
364 xfs_fsop_handlereq_t hreq; 362 xfs_fsop_handlereq_t hreq;
365 vnode_t *vp; 363 bhv_vnode_t *vp;
366 __u32 olen; 364 __u32 olen;
367 365
368 if (!capable(CAP_SYS_ADMIN)) 366 if (!capable(CAP_SYS_ADMIN))
@@ -393,9 +391,11 @@ xfs_readlink_by_handle(
393 auio.uio_segflg = UIO_USERSPACE; 391 auio.uio_segflg = UIO_USERSPACE;
394 auio.uio_resid = olen; 392 auio.uio_resid = olen;
395 393
396 VOP_READLINK(vp, &auio, IO_INVIS, NULL, error); 394 error = bhv_vop_readlink(vp, &auio, IO_INVIS, NULL);
397
398 VN_RELE(vp); 395 VN_RELE(vp);
396 if (error)
397 return -error;
398
399 return (olen - auio.uio_resid); 399 return (olen - auio.uio_resid);
400} 400}
401 401
@@ -411,7 +411,7 @@ xfs_fssetdm_by_handle(
411 xfs_fsop_setdm_handlereq_t dmhreq; 411 xfs_fsop_setdm_handlereq_t dmhreq;
412 struct inode *inode; 412 struct inode *inode;
413 bhv_desc_t *bdp; 413 bhv_desc_t *bdp;
414 vnode_t *vp; 414 bhv_vnode_t *vp;
415 415
416 if (!capable(CAP_MKNOD)) 416 if (!capable(CAP_MKNOD))
417 return -XFS_ERROR(EPERM); 417 return -XFS_ERROR(EPERM);
@@ -452,7 +452,7 @@ xfs_attrlist_by_handle(
452 attrlist_cursor_kern_t *cursor; 452 attrlist_cursor_kern_t *cursor;
453 xfs_fsop_attrlist_handlereq_t al_hreq; 453 xfs_fsop_attrlist_handlereq_t al_hreq;
454 struct inode *inode; 454 struct inode *inode;
455 vnode_t *vp; 455 bhv_vnode_t *vp;
456 char *kbuf; 456 char *kbuf;
457 457
458 if (!capable(CAP_SYS_ADMIN)) 458 if (!capable(CAP_SYS_ADMIN))
@@ -472,8 +472,8 @@ xfs_attrlist_by_handle(
472 goto out_vn_rele; 472 goto out_vn_rele;
473 473
474 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; 474 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
475 VOP_ATTR_LIST(vp, kbuf, al_hreq.buflen, al_hreq.flags, 475 error = bhv_vop_attr_list(vp, kbuf, al_hreq.buflen, al_hreq.flags,
476 cursor, NULL, error); 476 cursor, NULL);
477 if (error) 477 if (error)
478 goto out_kfree; 478 goto out_kfree;
479 479
@@ -490,7 +490,7 @@ xfs_attrlist_by_handle(
490 490
491STATIC int 491STATIC int
492xfs_attrmulti_attr_get( 492xfs_attrmulti_attr_get(
493 struct vnode *vp, 493 bhv_vnode_t *vp,
494 char *name, 494 char *name,
495 char __user *ubuf, 495 char __user *ubuf,
496 __uint32_t *len, 496 __uint32_t *len,
@@ -505,7 +505,7 @@ xfs_attrmulti_attr_get(
505 if (!kbuf) 505 if (!kbuf)
506 return ENOMEM; 506 return ENOMEM;
507 507
508 VOP_ATTR_GET(vp, name, kbuf, len, flags, NULL, error); 508 error = bhv_vop_attr_get(vp, name, kbuf, len, flags, NULL);
509 if (error) 509 if (error)
510 goto out_kfree; 510 goto out_kfree;
511 511
@@ -519,7 +519,7 @@ xfs_attrmulti_attr_get(
519 519
520STATIC int 520STATIC int
521xfs_attrmulti_attr_set( 521xfs_attrmulti_attr_set(
522 struct vnode *vp, 522 bhv_vnode_t *vp,
523 char *name, 523 char *name,
524 const char __user *ubuf, 524 const char __user *ubuf,
525 __uint32_t len, 525 __uint32_t len,
@@ -542,7 +542,7 @@ xfs_attrmulti_attr_set(
542 if (copy_from_user(kbuf, ubuf, len)) 542 if (copy_from_user(kbuf, ubuf, len))
543 goto out_kfree; 543 goto out_kfree;
544 544
545 VOP_ATTR_SET(vp, name, kbuf, len, flags, NULL, error); 545 error = bhv_vop_attr_set(vp, name, kbuf, len, flags, NULL);
546 546
547 out_kfree: 547 out_kfree:
548 kfree(kbuf); 548 kfree(kbuf);
@@ -551,20 +551,15 @@ xfs_attrmulti_attr_set(
551 551
552STATIC int 552STATIC int
553xfs_attrmulti_attr_remove( 553xfs_attrmulti_attr_remove(
554 struct vnode *vp, 554 bhv_vnode_t *vp,
555 char *name, 555 char *name,
556 __uint32_t flags) 556 __uint32_t flags)
557{ 557{
558 int error;
559
560
561 if (IS_RDONLY(&vp->v_inode)) 558 if (IS_RDONLY(&vp->v_inode))
562 return -EROFS; 559 return -EROFS;
563 if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode)) 560 if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
564 return EPERM; 561 return EPERM;
565 562 return bhv_vop_attr_remove(vp, name, flags, NULL);
566 VOP_ATTR_REMOVE(vp, name, flags, NULL, error);
567 return error;
568} 563}
569 564
570STATIC int 565STATIC int
@@ -578,7 +573,7 @@ xfs_attrmulti_by_handle(
578 xfs_attr_multiop_t *ops; 573 xfs_attr_multiop_t *ops;
579 xfs_fsop_attrmulti_handlereq_t am_hreq; 574 xfs_fsop_attrmulti_handlereq_t am_hreq;
580 struct inode *inode; 575 struct inode *inode;
581 vnode_t *vp; 576 bhv_vnode_t *vp;
582 unsigned int i, size; 577 unsigned int i, size;
583 char *attr_name; 578 char *attr_name;
584 579
@@ -658,7 +653,7 @@ xfs_attrmulti_by_handle(
658STATIC int 653STATIC int
659xfs_ioc_space( 654xfs_ioc_space(
660 bhv_desc_t *bdp, 655 bhv_desc_t *bdp,
661 vnode_t *vp, 656 bhv_vnode_t *vp,
662 struct file *filp, 657 struct file *filp,
663 int flags, 658 int flags,
664 unsigned int cmd, 659 unsigned int cmd,
@@ -682,7 +677,7 @@ xfs_ioc_fsgeometry(
682 677
683STATIC int 678STATIC int
684xfs_ioc_xattr( 679xfs_ioc_xattr(
685 vnode_t *vp, 680 bhv_vnode_t *vp,
686 xfs_inode_t *ip, 681 xfs_inode_t *ip,
687 struct file *filp, 682 struct file *filp,
688 unsigned int cmd, 683 unsigned int cmd,
@@ -711,7 +706,7 @@ xfs_ioctl(
711 void __user *arg) 706 void __user *arg)
712{ 707{
713 int error; 708 int error;
714 vnode_t *vp; 709 bhv_vnode_t *vp;
715 xfs_inode_t *ip; 710 xfs_inode_t *ip;
716 xfs_mount_t *mp; 711 xfs_mount_t *mp;
717 712
@@ -962,7 +957,7 @@ xfs_ioctl(
962STATIC int 957STATIC int
963xfs_ioc_space( 958xfs_ioc_space(
964 bhv_desc_t *bdp, 959 bhv_desc_t *bdp,
965 vnode_t *vp, 960 bhv_vnode_t *vp,
966 struct file *filp, 961 struct file *filp,
967 int ioflags, 962 int ioflags,
968 unsigned int cmd, 963 unsigned int cmd,
@@ -1153,14 +1148,14 @@ xfs_di2lxflags(
1153 1148
1154STATIC int 1149STATIC int
1155xfs_ioc_xattr( 1150xfs_ioc_xattr(
1156 vnode_t *vp, 1151 bhv_vnode_t *vp,
1157 xfs_inode_t *ip, 1152 xfs_inode_t *ip,
1158 struct file *filp, 1153 struct file *filp,
1159 unsigned int cmd, 1154 unsigned int cmd,
1160 void __user *arg) 1155 void __user *arg)
1161{ 1156{
1162 struct fsxattr fa; 1157 struct fsxattr fa;
1163 struct vattr *vattr; 1158 struct bhv_vattr *vattr;
1164 int error = 0; 1159 int error = 0;
1165 int attr_flags; 1160 int attr_flags;
1166 unsigned int flags; 1161 unsigned int flags;
@@ -1173,7 +1168,7 @@ xfs_ioc_xattr(
1173 case XFS_IOC_FSGETXATTR: { 1168 case XFS_IOC_FSGETXATTR: {
1174 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ 1169 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
1175 XFS_AT_NEXTENTS | XFS_AT_PROJID; 1170 XFS_AT_NEXTENTS | XFS_AT_PROJID;
1176 VOP_GETATTR(vp, vattr, 0, NULL, error); 1171 error = bhv_vop_getattr(vp, vattr, 0, NULL);
1177 if (unlikely(error)) { 1172 if (unlikely(error)) {
1178 error = -error; 1173 error = -error;
1179 break; 1174 break;
@@ -1206,7 +1201,7 @@ xfs_ioc_xattr(
1206 vattr->va_extsize = fa.fsx_extsize; 1201 vattr->va_extsize = fa.fsx_extsize;
1207 vattr->va_projid = fa.fsx_projid; 1202 vattr->va_projid = fa.fsx_projid;
1208 1203
1209 VOP_SETATTR(vp, vattr, attr_flags, NULL, error); 1204 error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
1210 if (likely(!error)) 1205 if (likely(!error))
1211 __vn_revalidate(vp, vattr); /* update flags */ 1206 __vn_revalidate(vp, vattr); /* update flags */
1212 error = -error; 1207 error = -error;
@@ -1216,7 +1211,7 @@ xfs_ioc_xattr(
1216 case XFS_IOC_FSGETXATTRA: { 1211 case XFS_IOC_FSGETXATTRA: {
1217 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ 1212 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
1218 XFS_AT_ANEXTENTS | XFS_AT_PROJID; 1213 XFS_AT_ANEXTENTS | XFS_AT_PROJID;
1219 VOP_GETATTR(vp, vattr, 0, NULL, error); 1214 error = bhv_vop_getattr(vp, vattr, 0, NULL);
1220 if (unlikely(error)) { 1215 if (unlikely(error)) {
1221 error = -error; 1216 error = -error;
1222 break; 1217 break;
@@ -1262,7 +1257,7 @@ xfs_ioc_xattr(
1262 vattr->va_xflags = xfs_merge_ioc_xflags(flags, 1257 vattr->va_xflags = xfs_merge_ioc_xflags(flags,
1263 xfs_ip2xflags(ip)); 1258 xfs_ip2xflags(ip));
1264 1259
1265 VOP_SETATTR(vp, vattr, attr_flags, NULL, error); 1260 error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
1266 if (likely(!error)) 1261 if (likely(!error))
1267 __vn_revalidate(vp, vattr); /* update flags */ 1262 __vn_revalidate(vp, vattr); /* update flags */
1268 error = -error; 1263 error = -error;
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 251bfe451a3f..601f01c92f7f 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -114,7 +114,7 @@ xfs_compat_ioctl(
114 unsigned long arg) 114 unsigned long arg)
115{ 115{
116 struct inode *inode = file->f_dentry->d_inode; 116 struct inode *inode = file->f_dentry->d_inode;
117 vnode_t *vp = vn_from_inode(inode); 117 bhv_vnode_t *vp = vn_from_inode(inode);
118 int error; 118 int error;
119 119
120 switch (cmd) { 120 switch (cmd) {
@@ -193,7 +193,7 @@ xfs_compat_ioctl(
193 return -ENOIOCTLCMD; 193 return -ENOIOCTLCMD;
194 } 194 }
195 195
196 VOP_IOCTL(vp, inode, file, mode, cmd, (void __user *)arg, error); 196 error = bhv_vop_ioctl(vp, inode, file, mode, cmd, (void __user *)arg);
197 VMODIFY(vp); 197 VMODIFY(vp);
198 198
199 return error; 199 return error;
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 2e2e275c786f..12810baeb5d4 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -61,7 +59,7 @@
61 */ 59 */
62xfs_inode_t * 60xfs_inode_t *
63xfs_vtoi( 61xfs_vtoi(
64 struct vnode *vp) 62 bhv_vnode_t *vp)
65{ 63{
66 bhv_desc_t *bdp; 64 bhv_desc_t *bdp;
67 65
@@ -80,7 +78,7 @@ void
80xfs_synchronize_atime( 78xfs_synchronize_atime(
81 xfs_inode_t *ip) 79 xfs_inode_t *ip)
82{ 80{
83 vnode_t *vp; 81 bhv_vnode_t *vp;
84 82
85 vp = XFS_ITOV_NULL(ip); 83 vp = XFS_ITOV_NULL(ip);
86 if (vp) { 84 if (vp) {
@@ -200,14 +198,10 @@ xfs_ichgtime_fast(
200STATIC void 198STATIC void
201xfs_validate_fields( 199xfs_validate_fields(
202 struct inode *ip, 200 struct inode *ip,
203 struct vattr *vattr) 201 bhv_vattr_t *vattr)
204{ 202{
205 vnode_t *vp = vn_from_inode(ip);
206 int error;
207
208 vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS; 203 vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS;
209 VOP_GETATTR(vp, vattr, ATTR_LAZY, NULL, error); 204 if (!bhv_vop_getattr(vn_from_inode(ip), vattr, ATTR_LAZY, NULL)) {
210 if (likely(!error)) {
211 ip->i_nlink = vattr->va_nlink; 205 ip->i_nlink = vattr->va_nlink;
212 ip->i_blocks = vattr->va_nblocks; 206 ip->i_blocks = vattr->va_nblocks;
213 207
@@ -225,7 +219,7 @@ xfs_validate_fields(
225 */ 219 */
226STATIC int 220STATIC int
227xfs_init_security( 221xfs_init_security(
228 struct vnode *vp, 222 bhv_vnode_t *vp,
229 struct inode *dir) 223 struct inode *dir)
230{ 224{
231 struct inode *ip = vn_to_inode(vp); 225 struct inode *ip = vn_to_inode(vp);
@@ -241,7 +235,7 @@ xfs_init_security(
241 return -error; 235 return -error;
242 } 236 }
243 237
244 VOP_ATTR_SET(vp, name, value, length, ATTR_SECURE, NULL, error); 238 error = bhv_vop_attr_set(vp, name, value, length, ATTR_SECURE, NULL);
245 if (!error) 239 if (!error)
246 VMODIFY(vp); 240 VMODIFY(vp);
247 241
@@ -264,13 +258,12 @@ xfs_has_fs_struct(struct task_struct *task)
264 258
265STATIC inline void 259STATIC inline void
266xfs_cleanup_inode( 260xfs_cleanup_inode(
267 vnode_t *dvp, 261 bhv_vnode_t *dvp,
268 vnode_t *vp, 262 bhv_vnode_t *vp,
269 struct dentry *dentry, 263 struct dentry *dentry,
270 int mode) 264 int mode)
271{ 265{
272 struct dentry teardown = {}; 266 struct dentry teardown = {};
273 int error;
274 267
275 /* Oh, the horror. 268 /* Oh, the horror.
276 * If we can't add the ACL or we fail in 269 * If we can't add the ACL or we fail in
@@ -281,9 +274,9 @@ xfs_cleanup_inode(
281 teardown.d_name = dentry->d_name; 274 teardown.d_name = dentry->d_name;
282 275
283 if (S_ISDIR(mode)) 276 if (S_ISDIR(mode))
284 VOP_RMDIR(dvp, &teardown, NULL, error); 277 bhv_vop_rmdir(dvp, &teardown, NULL);
285 else 278 else
286 VOP_REMOVE(dvp, &teardown, NULL, error); 279 bhv_vop_remove(dvp, &teardown, NULL);
287 VN_RELE(vp); 280 VN_RELE(vp);
288} 281}
289 282
@@ -295,8 +288,8 @@ xfs_vn_mknod(
295 dev_t rdev) 288 dev_t rdev)
296{ 289{
297 struct inode *ip; 290 struct inode *ip;
298 vattr_t vattr = { 0 }; 291 bhv_vattr_t vattr = { 0 };
299 vnode_t *vp = NULL, *dvp = vn_from_inode(dir); 292 bhv_vnode_t *vp = NULL, *dvp = vn_from_inode(dir);
300 xfs_acl_t *default_acl = NULL; 293 xfs_acl_t *default_acl = NULL;
301 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS; 294 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS;
302 int error; 295 int error;
@@ -330,10 +323,10 @@ xfs_vn_mknod(
330 vattr.va_mask |= XFS_AT_RDEV; 323 vattr.va_mask |= XFS_AT_RDEV;
331 /*FALLTHROUGH*/ 324 /*FALLTHROUGH*/
332 case S_IFREG: 325 case S_IFREG:
333 VOP_CREATE(dvp, dentry, &vattr, &vp, NULL, error); 326 error = bhv_vop_create(dvp, dentry, &vattr, &vp, NULL);
334 break; 327 break;
335 case S_IFDIR: 328 case S_IFDIR:
336 VOP_MKDIR(dvp, dentry, &vattr, &vp, NULL, error); 329 error = bhv_vop_mkdir(dvp, dentry, &vattr, &vp, NULL);
337 break; 330 break;
338 default: 331 default:
339 error = EINVAL; 332 error = EINVAL;
@@ -396,14 +389,14 @@ xfs_vn_lookup(
396 struct dentry *dentry, 389 struct dentry *dentry,
397 struct nameidata *nd) 390 struct nameidata *nd)
398{ 391{
399 struct vnode *vp = vn_from_inode(dir), *cvp; 392 bhv_vnode_t *vp = vn_from_inode(dir), *cvp;
400 int error; 393 int error;
401 394
402 if (dentry->d_name.len >= MAXNAMELEN) 395 if (dentry->d_name.len >= MAXNAMELEN)
403 return ERR_PTR(-ENAMETOOLONG); 396 return ERR_PTR(-ENAMETOOLONG);
404 397
405 VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error); 398 error = bhv_vop_lookup(vp, dentry, &cvp, 0, NULL, NULL);
406 if (error) { 399 if (unlikely(error)) {
407 if (unlikely(error != ENOENT)) 400 if (unlikely(error != ENOENT))
408 return ERR_PTR(-error); 401 return ERR_PTR(-error);
409 d_add(dentry, NULL); 402 d_add(dentry, NULL);
@@ -420,9 +413,9 @@ xfs_vn_link(
420 struct dentry *dentry) 413 struct dentry *dentry)
421{ 414{
422 struct inode *ip; /* inode of guy being linked to */ 415 struct inode *ip; /* inode of guy being linked to */
423 vnode_t *tdvp; /* target directory for new name/link */ 416 bhv_vnode_t *tdvp; /* target directory for new name/link */
424 vnode_t *vp; /* vp of name being linked */ 417 bhv_vnode_t *vp; /* vp of name being linked */
425 vattr_t vattr; 418 bhv_vattr_t vattr;
426 int error; 419 int error;
427 420
428 ip = old_dentry->d_inode; /* inode being linked to */ 421 ip = old_dentry->d_inode; /* inode being linked to */
@@ -432,7 +425,7 @@ xfs_vn_link(
432 tdvp = vn_from_inode(dir); 425 tdvp = vn_from_inode(dir);
433 vp = vn_from_inode(ip); 426 vp = vn_from_inode(ip);
434 427
435 VOP_LINK(tdvp, vp, dentry, NULL, error); 428 error = bhv_vop_link(tdvp, vp, dentry, NULL);
436 if (likely(!error)) { 429 if (likely(!error)) {
437 VMODIFY(tdvp); 430 VMODIFY(tdvp);
438 VN_HOLD(vp); 431 VN_HOLD(vp);
@@ -448,14 +441,14 @@ xfs_vn_unlink(
448 struct dentry *dentry) 441 struct dentry *dentry)
449{ 442{
450 struct inode *inode; 443 struct inode *inode;
451 vnode_t *dvp; /* directory containing name to remove */ 444 bhv_vnode_t *dvp; /* directory containing name to remove */
452 vattr_t vattr; 445 bhv_vattr_t vattr;
453 int error; 446 int error;
454 447
455 inode = dentry->d_inode; 448 inode = dentry->d_inode;
456 dvp = vn_from_inode(dir); 449 dvp = vn_from_inode(dir);
457 450
458 VOP_REMOVE(dvp, dentry, NULL, error); 451 error = bhv_vop_remove(dvp, dentry, NULL);
459 if (likely(!error)) { 452 if (likely(!error)) {
460 xfs_validate_fields(dir, &vattr); /* size needs update */ 453 xfs_validate_fields(dir, &vattr); /* size needs update */
461 xfs_validate_fields(inode, &vattr); 454 xfs_validate_fields(inode, &vattr);
@@ -470,27 +463,26 @@ xfs_vn_symlink(
470 const char *symname) 463 const char *symname)
471{ 464{
472 struct inode *ip; 465 struct inode *ip;
473 vattr_t vattr = { 0 }; 466 bhv_vattr_t va = { 0 };
474 vnode_t *dvp; /* directory containing name of symlink */ 467 bhv_vnode_t *dvp; /* directory containing name of symlink */
475 vnode_t *cvp; /* used to lookup symlink to put in dentry */ 468 bhv_vnode_t *cvp; /* used to lookup symlink to put in dentry */
476 int error; 469 int error;
477 470
478 dvp = vn_from_inode(dir); 471 dvp = vn_from_inode(dir);
479 cvp = NULL; 472 cvp = NULL;
480 473
481 vattr.va_mode = S_IFLNK | 474 va.va_mode = S_IFLNK |
482 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO); 475 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO);
483 vattr.va_mask = XFS_AT_TYPE|XFS_AT_MODE; 476 va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
484 477
485 error = 0; 478 error = bhv_vop_symlink(dvp, dentry, &va, (char *)symname, &cvp, NULL);
486 VOP_SYMLINK(dvp, dentry, &vattr, (char *)symname, &cvp, NULL, error);
487 if (likely(!error && cvp)) { 479 if (likely(!error && cvp)) {
488 error = xfs_init_security(cvp, dir); 480 error = xfs_init_security(cvp, dir);
489 if (likely(!error)) { 481 if (likely(!error)) {
490 ip = vn_to_inode(cvp); 482 ip = vn_to_inode(cvp);
491 d_instantiate(dentry, ip); 483 d_instantiate(dentry, ip);
492 xfs_validate_fields(dir, &vattr); 484 xfs_validate_fields(dir, &va);
493 xfs_validate_fields(ip, &vattr); 485 xfs_validate_fields(ip, &va);
494 } else { 486 } else {
495 xfs_cleanup_inode(dvp, cvp, dentry, 0); 487 xfs_cleanup_inode(dvp, cvp, dentry, 0);
496 } 488 }
@@ -504,11 +496,11 @@ xfs_vn_rmdir(
504 struct dentry *dentry) 496 struct dentry *dentry)
505{ 497{
506 struct inode *inode = dentry->d_inode; 498 struct inode *inode = dentry->d_inode;
507 vnode_t *dvp = vn_from_inode(dir); 499 bhv_vnode_t *dvp = vn_from_inode(dir);
508 vattr_t vattr; 500 bhv_vattr_t vattr;
509 int error; 501 int error;
510 502
511 VOP_RMDIR(dvp, dentry, NULL, error); 503 error = bhv_vop_rmdir(dvp, dentry, NULL);
512 if (likely(!error)) { 504 if (likely(!error)) {
513 xfs_validate_fields(inode, &vattr); 505 xfs_validate_fields(inode, &vattr);
514 xfs_validate_fields(dir, &vattr); 506 xfs_validate_fields(dir, &vattr);
@@ -524,15 +516,15 @@ xfs_vn_rename(
524 struct dentry *ndentry) 516 struct dentry *ndentry)
525{ 517{
526 struct inode *new_inode = ndentry->d_inode; 518 struct inode *new_inode = ndentry->d_inode;
527 vnode_t *fvp; /* from directory */ 519 bhv_vnode_t *fvp; /* from directory */
528 vnode_t *tvp; /* target directory */ 520 bhv_vnode_t *tvp; /* target directory */
529 vattr_t vattr; 521 bhv_vattr_t vattr;
530 int error; 522 int error;
531 523
532 fvp = vn_from_inode(odir); 524 fvp = vn_from_inode(odir);
533 tvp = vn_from_inode(ndir); 525 tvp = vn_from_inode(ndir);
534 526
535 VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error); 527 error = bhv_vop_rename(fvp, odentry, tvp, ndentry, NULL);
536 if (likely(!error)) { 528 if (likely(!error)) {
537 if (new_inode) 529 if (new_inode)
538 xfs_validate_fields(new_inode, &vattr); 530 xfs_validate_fields(new_inode, &vattr);
@@ -553,7 +545,7 @@ xfs_vn_follow_link(
553 struct dentry *dentry, 545 struct dentry *dentry,
554 struct nameidata *nd) 546 struct nameidata *nd)
555{ 547{
556 vnode_t *vp; 548 bhv_vnode_t *vp;
557 uio_t *uio; 549 uio_t *uio;
558 iovec_t iov; 550 iovec_t iov;
559 int error; 551 int error;
@@ -586,8 +578,8 @@ xfs_vn_follow_link(
586 uio->uio_resid = MAXPATHLEN; 578 uio->uio_resid = MAXPATHLEN;
587 uio->uio_iovcnt = 1; 579 uio->uio_iovcnt = 1;
588 580
589 VOP_READLINK(vp, uio, 0, NULL, error); 581 error = bhv_vop_readlink(vp, uio, 0, NULL);
590 if (error) { 582 if (unlikely(error)) {
591 kfree(link); 583 kfree(link);
592 link = ERR_PTR(-error); 584 link = ERR_PTR(-error);
593 } else { 585 } else {
@@ -618,12 +610,7 @@ xfs_vn_permission(
618 int mode, 610 int mode,
619 struct nameidata *nd) 611 struct nameidata *nd)
620{ 612{
621 vnode_t *vp = vn_from_inode(inode); 613 return -bhv_vop_access(vn_from_inode(inode), mode << 6, NULL);
622 int error;
623
624 mode <<= 6; /* convert from linux to vnode access bits */
625 VOP_ACCESS(vp, mode, NULL, error);
626 return -error;
627} 614}
628#else 615#else
629#define xfs_vn_permission NULL 616#define xfs_vn_permission NULL
@@ -636,14 +623,14 @@ xfs_vn_getattr(
636 struct kstat *stat) 623 struct kstat *stat)
637{ 624{
638 struct inode *inode = dentry->d_inode; 625 struct inode *inode = dentry->d_inode;
639 vnode_t *vp = vn_from_inode(inode); 626 bhv_vnode_t *vp = vn_from_inode(inode);
640 int error = 0; 627 int error = 0;
641 628
642 if (unlikely(vp->v_flag & VMODIFIED)) 629 if (unlikely(vp->v_flag & VMODIFIED))
643 error = vn_revalidate(vp); 630 error = vn_revalidate(vp);
644 if (!error) 631 if (!error)
645 generic_fillattr(inode, stat); 632 generic_fillattr(inode, stat);
646 return 0; 633 return -error;
647} 634}
648 635
649STATIC int 636STATIC int
@@ -653,8 +640,8 @@ xfs_vn_setattr(
653{ 640{
654 struct inode *inode = dentry->d_inode; 641 struct inode *inode = dentry->d_inode;
655 unsigned int ia_valid = attr->ia_valid; 642 unsigned int ia_valid = attr->ia_valid;
656 vnode_t *vp = vn_from_inode(inode); 643 bhv_vnode_t *vp = vn_from_inode(inode);
657 vattr_t vattr = { 0 }; 644 bhv_vattr_t vattr = { 0 };
658 int flags = 0; 645 int flags = 0;
659 int error; 646 int error;
660 647
@@ -697,7 +684,7 @@ xfs_vn_setattr(
697 flags |= ATTR_NONBLOCK; 684 flags |= ATTR_NONBLOCK;
698#endif 685#endif
699 686
700 VOP_SETATTR(vp, &vattr, flags, NULL, error); 687 error = bhv_vop_setattr(vp, &vattr, flags, NULL);
701 if (likely(!error)) 688 if (likely(!error))
702 __vn_revalidate(vp, &vattr); 689 __vn_revalidate(vp, &vattr);
703 return -error; 690 return -error;
@@ -718,7 +705,7 @@ xfs_vn_setxattr(
718 size_t size, 705 size_t size,
719 int flags) 706 int flags)
720{ 707{
721 vnode_t *vp = vn_from_inode(dentry->d_inode); 708 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
722 char *attr = (char *)name; 709 char *attr = (char *)name;
723 attrnames_t *namesp; 710 attrnames_t *namesp;
724 int xflags = 0; 711 int xflags = 0;
@@ -748,7 +735,7 @@ xfs_vn_getxattr(
748 void *data, 735 void *data,
749 size_t size) 736 size_t size)
750{ 737{
751 vnode_t *vp = vn_from_inode(dentry->d_inode); 738 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
752 char *attr = (char *)name; 739 char *attr = (char *)name;
753 attrnames_t *namesp; 740 attrnames_t *namesp;
754 int xflags = 0; 741 int xflags = 0;
@@ -777,7 +764,7 @@ xfs_vn_listxattr(
777 char *data, 764 char *data,
778 size_t size) 765 size_t size)
779{ 766{
780 vnode_t *vp = vn_from_inode(dentry->d_inode); 767 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
781 int error, xflags = ATTR_KERNAMELS; 768 int error, xflags = ATTR_KERNAMELS;
782 ssize_t result; 769 ssize_t result;
783 770
@@ -796,7 +783,7 @@ xfs_vn_removexattr(
796 struct dentry *dentry, 783 struct dentry *dentry,
797 const char *name) 784 const char *name)
798{ 785{
799 vnode_t *vp = vn_from_inode(dentry->d_inode); 786 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
800 char *attr = (char *)name; 787 char *attr = (char *)name;
801 attrnames_t *namesp; 788 attrnames_t *namesp;
802 int xflags = 0; 789 int xflags = 0;
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index e9fe43d74768..aa26ab906c88 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -134,14 +134,21 @@ BUFFER_FNS(PrivateStart, unwritten);
134#define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val 134#define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val
135#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val 135#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val
136#define xfs_rotorstep xfs_params.rotorstep.val 136#define xfs_rotorstep xfs_params.rotorstep.val
137#define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val
137 138
138#ifndef raw_smp_processor_id 139#define current_cpu() (raw_smp_processor_id())
139#define raw_smp_processor_id() smp_processor_id()
140#endif
141#define current_cpu() raw_smp_processor_id()
142#define current_pid() (current->pid) 140#define current_pid() (current->pid)
143#define current_fsuid(cred) (current->fsuid) 141#define current_fsuid(cred) (current->fsuid)
144#define current_fsgid(cred) (current->fsgid) 142#define current_fsgid(cred) (current->fsgid)
143#define current_set_flags(f) (current->flags |= (f))
144#define current_test_flags(f) (current->flags & (f))
145#define current_clear_flags(f) (current->flags & ~(f))
146#define current_set_flags_nested(sp, f) \
147 (*(sp) = current->flags, current->flags |= (f))
148#define current_clear_flags_nested(sp, f) \
149 (*(sp) = current->flags, current->flags &= ~(f))
150#define current_restore_flags_nested(sp, f) \
151 (current->flags = ((current->flags & ~(f)) | (*(sp) & (f))))
145 152
146#define NBPP PAGE_SIZE 153#define NBPP PAGE_SIZE
147#define DPPSHFT (PAGE_SHIFT - 9) 154#define DPPSHFT (PAGE_SHIFT - 9)
@@ -187,25 +194,9 @@ BUFFER_FNS(PrivateStart, unwritten);
187/* bytes to clicks */ 194/* bytes to clicks */
188#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT) 195#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT)
189 196
190#ifndef ENOATTR
191#define ENOATTR ENODATA /* Attribute not found */ 197#define ENOATTR ENODATA /* Attribute not found */
192#endif 198#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
193 199#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
194/* Note: EWRONGFS never visible outside the kernel */
195#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
196
197/*
198 * XXX EFSCORRUPTED needs a real value in errno.h. asm-i386/errno.h won't
199 * return codes out of its known range in errno.
200 * XXX Also note: needs to be < 1000 and fairly unique on Linux (mustn't
201 * conflict with any code we use already or any code a driver may use)
202 * XXX Some options (currently we do #2):
203 * 1/ New error code ["Filesystem is corrupted", _after_ glibc updated]
204 * 2/ 990 ["Unknown error 990"]
205 * 3/ EUCLEAN ["Structure needs cleaning"]
206 * 4/ Convert EFSCORRUPTED to EIO [just prior to return into userspace]
207 */
208#define EFSCORRUPTED 990 /* Filesystem is corrupted */
209 200
210#define SYNCHRONIZE() barrier() 201#define SYNCHRONIZE() barrier()
211#define __return_address __builtin_return_address(0) 202#define __return_address __builtin_return_address(0)
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 67efe3308980..5d9cfd91ad08 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -206,7 +204,7 @@ xfs_read(
206 xfs_fsize_t n; 204 xfs_fsize_t n;
207 xfs_inode_t *ip; 205 xfs_inode_t *ip;
208 xfs_mount_t *mp; 206 xfs_mount_t *mp;
209 vnode_t *vp; 207 bhv_vnode_t *vp;
210 unsigned long seg; 208 unsigned long seg;
211 209
212 ip = XFS_BHVTOI(bdp); 210 ip = XFS_BHVTOI(bdp);
@@ -258,7 +256,7 @@ xfs_read(
258 256
259 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && 257 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
260 !(ioflags & IO_INVIS)) { 258 !(ioflags & IO_INVIS)) {
261 vrwlock_t locktype = VRWLOCK_READ; 259 bhv_vrwlock_t locktype = VRWLOCK_READ;
262 int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); 260 int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
263 261
264 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, 262 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
@@ -271,7 +269,7 @@ xfs_read(
271 } 269 }
272 270
273 if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp))) 271 if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp)))
274 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(*offset)), 272 bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
275 -1, FI_REMAPF_LOCKED); 273 -1, FI_REMAPF_LOCKED);
276 274
277 xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, 275 xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
@@ -313,7 +311,7 @@ xfs_sendfile(
313 311
314 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && 312 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
315 (!(ioflags & IO_INVIS))) { 313 (!(ioflags & IO_INVIS))) {
316 vrwlock_t locktype = VRWLOCK_READ; 314 bhv_vrwlock_t locktype = VRWLOCK_READ;
317 int error; 315 int error;
318 316
319 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), 317 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
@@ -357,7 +355,7 @@ xfs_splice_read(
357 355
358 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && 356 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
359 (!(ioflags & IO_INVIS))) { 357 (!(ioflags & IO_INVIS))) {
360 vrwlock_t locktype = VRWLOCK_READ; 358 bhv_vrwlock_t locktype = VRWLOCK_READ;
361 int error; 359 int error;
362 360
363 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), 361 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
@@ -401,7 +399,7 @@ xfs_splice_write(
401 399
402 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) && 400 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) &&
403 (!(ioflags & IO_INVIS))) { 401 (!(ioflags & IO_INVIS))) {
404 vrwlock_t locktype = VRWLOCK_WRITE; 402 bhv_vrwlock_t locktype = VRWLOCK_WRITE;
405 int error; 403 int error;
406 404
407 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp), 405 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp),
@@ -458,7 +456,7 @@ xfs_zero_last_block(
458 last_fsb = XFS_B_TO_FSBT(mp, isize); 456 last_fsb = XFS_B_TO_FSBT(mp, isize);
459 nimaps = 1; 457 nimaps = 1;
460 error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap, 458 error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap,
461 &nimaps, NULL); 459 &nimaps, NULL, NULL);
462 if (error) { 460 if (error) {
463 return error; 461 return error;
464 } 462 }
@@ -499,7 +497,7 @@ xfs_zero_last_block(
499 497
500int /* error (positive) */ 498int /* error (positive) */
501xfs_zero_eof( 499xfs_zero_eof(
502 vnode_t *vp, 500 bhv_vnode_t *vp,
503 xfs_iocore_t *io, 501 xfs_iocore_t *io,
504 xfs_off_t offset, /* starting I/O offset */ 502 xfs_off_t offset, /* starting I/O offset */
505 xfs_fsize_t isize, /* current inode size */ 503 xfs_fsize_t isize, /* current inode size */
@@ -510,7 +508,6 @@ xfs_zero_eof(
510 xfs_fileoff_t end_zero_fsb; 508 xfs_fileoff_t end_zero_fsb;
511 xfs_fileoff_t zero_count_fsb; 509 xfs_fileoff_t zero_count_fsb;
512 xfs_fileoff_t last_fsb; 510 xfs_fileoff_t last_fsb;
513 xfs_extlen_t buf_len_fsb;
514 xfs_mount_t *mp = io->io_mount; 511 xfs_mount_t *mp = io->io_mount;
515 int nimaps; 512 int nimaps;
516 int error = 0; 513 int error = 0;
@@ -556,7 +553,7 @@ xfs_zero_eof(
556 nimaps = 1; 553 nimaps = 1;
557 zero_count_fsb = end_zero_fsb - start_zero_fsb + 1; 554 zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
558 error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb, 555 error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb,
559 0, NULL, 0, &imap, &nimaps, NULL); 556 0, NULL, 0, &imap, &nimaps, NULL, NULL);
560 if (error) { 557 if (error) {
561 ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); 558 ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
562 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); 559 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
@@ -579,16 +576,7 @@ xfs_zero_eof(
579 } 576 }
580 577
581 /* 578 /*
582 * There are blocks in the range requested. 579 * There are blocks we need to zero.
583 * Zero them a single write at a time. We actually
584 * don't zero the entire range returned if it is
585 * too big and simply loop around to get the rest.
586 * That is not the most efficient thing to do, but it
587 * is simple and this path should not be exercised often.
588 */
589 buf_len_fsb = XFS_FILBLKS_MIN(imap.br_blockcount,
590 mp->m_writeio_blocks << 8);
591 /*
592 * Drop the inode lock while we're doing the I/O. 580 * Drop the inode lock while we're doing the I/O.
593 * We'll still have the iolock to protect us. 581 * We'll still have the iolock to protect us.
594 */ 582 */
@@ -596,14 +584,13 @@ xfs_zero_eof(
596 584
597 error = xfs_iozero(ip, 585 error = xfs_iozero(ip,
598 XFS_FSB_TO_B(mp, start_zero_fsb), 586 XFS_FSB_TO_B(mp, start_zero_fsb),
599 XFS_FSB_TO_B(mp, buf_len_fsb), 587 XFS_FSB_TO_B(mp, imap.br_blockcount),
600 end_size); 588 end_size);
601
602 if (error) { 589 if (error) {
603 goto out_lock; 590 goto out_lock;
604 } 591 }
605 592
606 start_zero_fsb = imap.br_startoff + buf_len_fsb; 593 start_zero_fsb = imap.br_startoff + imap.br_blockcount;
607 ASSERT(start_zero_fsb <= (end_zero_fsb + 1)); 594 ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
608 595
609 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); 596 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
@@ -637,11 +624,11 @@ xfs_write(
637 ssize_t ret = 0, error = 0; 624 ssize_t ret = 0, error = 0;
638 xfs_fsize_t isize, new_size; 625 xfs_fsize_t isize, new_size;
639 xfs_iocore_t *io; 626 xfs_iocore_t *io;
640 vnode_t *vp; 627 bhv_vnode_t *vp;
641 unsigned long seg; 628 unsigned long seg;
642 int iolock; 629 int iolock;
643 int eventsent = 0; 630 int eventsent = 0;
644 vrwlock_t locktype; 631 bhv_vrwlock_t locktype;
645 size_t ocount = 0, count; 632 size_t ocount = 0, count;
646 loff_t pos; 633 loff_t pos;
647 int need_i_mutex = 1, need_flush = 0; 634 int need_i_mutex = 1, need_flush = 0;
@@ -679,11 +666,11 @@ xfs_write(
679 io = &xip->i_iocore; 666 io = &xip->i_iocore;
680 mp = io->io_mount; 667 mp = io->io_mount;
681 668
669 vfs_wait_for_freeze(vp->v_vfsp, SB_FREEZE_WRITE);
670
682 if (XFS_FORCED_SHUTDOWN(mp)) 671 if (XFS_FORCED_SHUTDOWN(mp))
683 return -EIO; 672 return -EIO;
684 673
685 fs_check_frozen(vp->v_vfsp, SB_FREEZE_WRITE);
686
687 if (ioflags & IO_ISDIRECT) { 674 if (ioflags & IO_ISDIRECT) {
688 xfs_buftarg_t *target = 675 xfs_buftarg_t *target =
689 (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? 676 (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
@@ -814,7 +801,7 @@ retry:
814 if (need_flush) { 801 if (need_flush) {
815 xfs_inval_cached_trace(io, pos, -1, 802 xfs_inval_cached_trace(io, pos, -1,
816 ctooff(offtoct(pos)), -1); 803 ctooff(offtoct(pos)), -1);
817 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(pos)), 804 bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)),
818 -1, FI_REMAPF_LOCKED); 805 -1, FI_REMAPF_LOCKED);
819 } 806 }
820 807
@@ -903,79 +890,9 @@ retry:
903 890
904 /* Handle various SYNC-type writes */ 891 /* Handle various SYNC-type writes */
905 if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { 892 if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
906 /* 893 error = xfs_write_sync_logforce(mp, xip);
907 * If we're treating this as O_DSYNC and we have not updated the 894 if (error)
908 * size, force the log. 895 goto out_unlock_internal;
909 */
910 if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
911 !(xip->i_update_size)) {
912 xfs_inode_log_item_t *iip = xip->i_itemp;
913
914 /*
915 * If an allocation transaction occurred
916 * without extending the size, then we have to force
917 * the log up the proper point to ensure that the
918 * allocation is permanent. We can't count on
919 * the fact that buffered writes lock out direct I/O
920 * writes - the direct I/O write could have extended
921 * the size nontransactionally, then finished before
922 * we started. xfs_write_file will think that the file
923 * didn't grow but the update isn't safe unless the
924 * size change is logged.
925 *
926 * Force the log if we've committed a transaction
927 * against the inode or if someone else has and
928 * the commit record hasn't gone to disk (e.g.
929 * the inode is pinned). This guarantees that
930 * all changes affecting the inode are permanent
931 * when we return.
932 */
933 if (iip && iip->ili_last_lsn) {
934 xfs_log_force(mp, iip->ili_last_lsn,
935 XFS_LOG_FORCE | XFS_LOG_SYNC);
936 } else if (xfs_ipincount(xip) > 0) {
937 xfs_log_force(mp, (xfs_lsn_t)0,
938 XFS_LOG_FORCE | XFS_LOG_SYNC);
939 }
940
941 } else {
942 xfs_trans_t *tp;
943
944 /*
945 * O_SYNC or O_DSYNC _with_ a size update are handled
946 * the same way.
947 *
948 * If the write was synchronous then we need to make
949 * sure that the inode modification time is permanent.
950 * We'll have updated the timestamp above, so here
951 * we use a synchronous transaction to log the inode.
952 * It's not fast, but it's necessary.
953 *
954 * If this a dsync write and the size got changed
955 * non-transactionally, then we need to ensure that
956 * the size change gets logged in a synchronous
957 * transaction.
958 */
959
960 tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
961 if ((error = xfs_trans_reserve(tp, 0,
962 XFS_SWRITE_LOG_RES(mp),
963 0, 0, 0))) {
964 /* Transaction reserve failed */
965 xfs_trans_cancel(tp, 0);
966 } else {
967 /* Transaction reserve successful */
968 xfs_ilock(xip, XFS_ILOCK_EXCL);
969 xfs_trans_ijoin(tp, xip, XFS_ILOCK_EXCL);
970 xfs_trans_ihold(tp, xip);
971 xfs_trans_log_inode(tp, xip, XFS_ILOG_CORE);
972 xfs_trans_set_sync(tp);
973 error = xfs_trans_commit(tp, 0, NULL);
974 xfs_iunlock(xip, XFS_ILOCK_EXCL);
975 }
976 if (error)
977 goto out_unlock_internal;
978 }
979 896
980 xfs_rwunlock(bdp, locktype); 897 xfs_rwunlock(bdp, locktype);
981 if (need_i_mutex) 898 if (need_i_mutex)
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index 8f4539952350..c77e62efb742 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -18,8 +18,8 @@
18#ifndef __XFS_LRW_H__ 18#ifndef __XFS_LRW_H__
19#define __XFS_LRW_H__ 19#define __XFS_LRW_H__
20 20
21struct vnode;
22struct bhv_desc; 21struct bhv_desc;
22struct bhv_vnode;
23struct xfs_mount; 23struct xfs_mount;
24struct xfs_iocore; 24struct xfs_iocore;
25struct xfs_inode; 25struct xfs_inode;
@@ -49,7 +49,7 @@ struct xfs_iomap;
49#define XFS_CTRUNC4 14 49#define XFS_CTRUNC4 14
50#define XFS_CTRUNC5 15 50#define XFS_CTRUNC5 15
51#define XFS_CTRUNC6 16 51#define XFS_CTRUNC6 16
52#define XFS_BUNMAPI 17 52#define XFS_BUNMAP 17
53#define XFS_INVAL_CACHED 18 53#define XFS_INVAL_CACHED 18
54#define XFS_DIORD_ENTER 19 54#define XFS_DIORD_ENTER 19
55#define XFS_DIOWR_ENTER 20 55#define XFS_DIOWR_ENTER 20
@@ -82,7 +82,7 @@ extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *);
82extern int xfs_bdstrat_cb(struct xfs_buf *); 82extern int xfs_bdstrat_cb(struct xfs_buf *);
83extern int xfs_dev_is_read_only(struct xfs_mount *, char *); 83extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
84 84
85extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t, 85extern int xfs_zero_eof(struct bhv_vnode *, struct xfs_iocore *, xfs_off_t,
86 xfs_fsize_t, xfs_fsize_t); 86 xfs_fsize_t, xfs_fsize_t);
87extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *, 87extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
88 const struct iovec *, unsigned int, 88 const struct iovec *, unsigned int,
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 68f4793e8a11..f2a0778536f4 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -151,7 +149,7 @@ xfs_set_inodeops(
151STATIC __inline__ void 149STATIC __inline__ void
152xfs_revalidate_inode( 150xfs_revalidate_inode(
153 xfs_mount_t *mp, 151 xfs_mount_t *mp,
154 vnode_t *vp, 152 bhv_vnode_t *vp,
155 xfs_inode_t *ip) 153 xfs_inode_t *ip)
156{ 154{
157 struct inode *inode = vn_to_inode(vp); 155 struct inode *inode = vn_to_inode(vp);
@@ -206,7 +204,7 @@ xfs_revalidate_inode(
206void 204void
207xfs_initialize_vnode( 205xfs_initialize_vnode(
208 bhv_desc_t *bdp, 206 bhv_desc_t *bdp,
209 vnode_t *vp, 207 bhv_vnode_t *vp,
210 bhv_desc_t *inode_bhv, 208 bhv_desc_t *inode_bhv,
211 int unlock) 209 int unlock)
212{ 210{
@@ -336,7 +334,7 @@ STATIC struct inode *
336xfs_fs_alloc_inode( 334xfs_fs_alloc_inode(
337 struct super_block *sb) 335 struct super_block *sb)
338{ 336{
339 vnode_t *vp; 337 bhv_vnode_t *vp;
340 338
341 vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP); 339 vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP);
342 if (unlikely(!vp)) 340 if (unlikely(!vp))
@@ -359,13 +357,13 @@ xfs_fs_inode_init_once(
359{ 357{
360 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == 358 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
361 SLAB_CTOR_CONSTRUCTOR) 359 SLAB_CTOR_CONSTRUCTOR)
362 inode_init_once(vn_to_inode((vnode_t *)vnode)); 360 inode_init_once(vn_to_inode((bhv_vnode_t *)vnode));
363} 361}
364 362
365STATIC int 363STATIC int
366xfs_init_zones(void) 364xfs_init_zones(void)
367{ 365{
368 xfs_vnode_zone = kmem_zone_init_flags(sizeof(vnode_t), "xfs_vnode_t", 366 xfs_vnode_zone = kmem_zone_init_flags(sizeof(bhv_vnode_t), "xfs_vnode",
369 KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | 367 KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
370 KM_ZONE_SPREAD, 368 KM_ZONE_SPREAD,
371 xfs_fs_inode_init_once); 369 xfs_fs_inode_init_once);
@@ -409,22 +407,17 @@ xfs_fs_write_inode(
409 struct inode *inode, 407 struct inode *inode,
410 int sync) 408 int sync)
411{ 409{
412 vnode_t *vp = vn_from_inode(inode); 410 bhv_vnode_t *vp = vn_from_inode(inode);
413 int error = 0, flags = FLUSH_INODE; 411 int error = 0, flags = FLUSH_INODE;
414 412
415 if (vp) { 413 if (vp) {
416 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 414 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
417 if (sync) 415 if (sync)
418 flags |= FLUSH_SYNC; 416 flags |= FLUSH_SYNC;
419 VOP_IFLUSH(vp, flags, error); 417 error = bhv_vop_iflush(vp, flags);
420 if (error == EAGAIN) { 418 if (error == EAGAIN)
421 if (sync) 419 error = sync? bhv_vop_iflush(vp, flags | FLUSH_LOG) : 0;
422 VOP_IFLUSH(vp, flags | FLUSH_LOG, error);
423 else
424 error = 0;
425 }
426 } 420 }
427
428 return -error; 421 return -error;
429} 422}
430 423
@@ -432,8 +425,7 @@ STATIC void
432xfs_fs_clear_inode( 425xfs_fs_clear_inode(
433 struct inode *inode) 426 struct inode *inode)
434{ 427{
435 vnode_t *vp = vn_from_inode(inode); 428 bhv_vnode_t *vp = vn_from_inode(inode);
436 int error, cache;
437 429
438 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 430 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
439 431
@@ -446,20 +438,18 @@ xfs_fs_clear_inode(
446 * This can happen because xfs_iget_core calls xfs_idestroy if we 438 * This can happen because xfs_iget_core calls xfs_idestroy if we
447 * find an inode with di_mode == 0 but without IGET_CREATE set. 439 * find an inode with di_mode == 0 but without IGET_CREATE set.
448 */ 440 */
449 if (vp->v_fbhv) 441 if (VNHEAD(vp))
450 VOP_INACTIVE(vp, NULL, cache); 442 bhv_vop_inactive(vp, NULL);
451 443
452 VN_LOCK(vp); 444 VN_LOCK(vp);
453 vp->v_flag &= ~VMODIFIED; 445 vp->v_flag &= ~VMODIFIED;
454 VN_UNLOCK(vp, 0); 446 VN_UNLOCK(vp, 0);
455 447
456 if (vp->v_fbhv) { 448 if (VNHEAD(vp))
457 VOP_RECLAIM(vp, error); 449 if (bhv_vop_reclaim(vp))
458 if (error) 450 panic("%s: cannot reclaim 0x%p\n", __FUNCTION__, vp);
459 panic("vn_purge: cannot reclaim");
460 }
461 451
462 ASSERT(vp->v_fbhv == NULL); 452 ASSERT(VNHEAD(vp) == NULL);
463 453
464#ifdef XFS_VNODE_TRACE 454#ifdef XFS_VNODE_TRACE
465 ktrace_free(vp->v_trace); 455 ktrace_free(vp->v_trace);
@@ -475,13 +465,13 @@ xfs_fs_clear_inode(
475 */ 465 */
476STATIC void 466STATIC void
477xfs_syncd_queue_work( 467xfs_syncd_queue_work(
478 struct vfs *vfs, 468 struct bhv_vfs *vfs,
479 void *data, 469 void *data,
480 void (*syncer)(vfs_t *, void *)) 470 void (*syncer)(bhv_vfs_t *, void *))
481{ 471{
482 vfs_sync_work_t *work; 472 struct bhv_vfs_sync_work *work;
483 473
484 work = kmem_alloc(sizeof(struct vfs_sync_work), KM_SLEEP); 474 work = kmem_alloc(sizeof(struct bhv_vfs_sync_work), KM_SLEEP);
485 INIT_LIST_HEAD(&work->w_list); 475 INIT_LIST_HEAD(&work->w_list);
486 work->w_syncer = syncer; 476 work->w_syncer = syncer;
487 work->w_data = data; 477 work->w_data = data;
@@ -500,7 +490,7 @@ xfs_syncd_queue_work(
500 */ 490 */
501STATIC void 491STATIC void
502xfs_flush_inode_work( 492xfs_flush_inode_work(
503 vfs_t *vfs, 493 bhv_vfs_t *vfs,
504 void *inode) 494 void *inode)
505{ 495{
506 filemap_flush(((struct inode *)inode)->i_mapping); 496 filemap_flush(((struct inode *)inode)->i_mapping);
@@ -512,7 +502,7 @@ xfs_flush_inode(
512 xfs_inode_t *ip) 502 xfs_inode_t *ip)
513{ 503{
514 struct inode *inode = vn_to_inode(XFS_ITOV(ip)); 504 struct inode *inode = vn_to_inode(XFS_ITOV(ip));
515 struct vfs *vfs = XFS_MTOVFS(ip->i_mount); 505 struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
516 506
517 igrab(inode); 507 igrab(inode);
518 xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work); 508 xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work);
@@ -525,7 +515,7 @@ xfs_flush_inode(
525 */ 515 */
526STATIC void 516STATIC void
527xfs_flush_device_work( 517xfs_flush_device_work(
528 vfs_t *vfs, 518 bhv_vfs_t *vfs,
529 void *inode) 519 void *inode)
530{ 520{
531 sync_blockdev(vfs->vfs_super->s_bdev); 521 sync_blockdev(vfs->vfs_super->s_bdev);
@@ -537,7 +527,7 @@ xfs_flush_device(
537 xfs_inode_t *ip) 527 xfs_inode_t *ip)
538{ 528{
539 struct inode *inode = vn_to_inode(XFS_ITOV(ip)); 529 struct inode *inode = vn_to_inode(XFS_ITOV(ip));
540 struct vfs *vfs = XFS_MTOVFS(ip->i_mount); 530 struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
541 531
542 igrab(inode); 532 igrab(inode);
543 xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work); 533 xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work);
@@ -545,16 +535,16 @@ xfs_flush_device(
545 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC); 535 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
546} 536}
547 537
548#define SYNCD_FLAGS (SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR|SYNC_REFCACHE)
549STATIC void 538STATIC void
550vfs_sync_worker( 539vfs_sync_worker(
551 vfs_t *vfsp, 540 bhv_vfs_t *vfsp,
552 void *unused) 541 void *unused)
553{ 542{
554 int error; 543 int error;
555 544
556 if (!(vfsp->vfs_flag & VFS_RDONLY)) 545 if (!(vfsp->vfs_flag & VFS_RDONLY))
557 VFS_SYNC(vfsp, SYNCD_FLAGS, NULL, error); 546 error = bhv_vfs_sync(vfsp, SYNC_FSDATA | SYNC_BDFLUSH | \
547 SYNC_ATTR | SYNC_REFCACHE, NULL);
558 vfsp->vfs_sync_seq++; 548 vfsp->vfs_sync_seq++;
559 wmb(); 549 wmb();
560 wake_up(&vfsp->vfs_wait_single_sync_task); 550 wake_up(&vfsp->vfs_wait_single_sync_task);
@@ -565,8 +555,8 @@ xfssyncd(
565 void *arg) 555 void *arg)
566{ 556{
567 long timeleft; 557 long timeleft;
568 vfs_t *vfsp = (vfs_t *) arg; 558 bhv_vfs_t *vfsp = (bhv_vfs_t *) arg;
569 struct vfs_sync_work *work, *n; 559 bhv_vfs_sync_work_t *work, *n;
570 LIST_HEAD (tmp); 560 LIST_HEAD (tmp);
571 561
572 timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10); 562 timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10);
@@ -600,7 +590,7 @@ xfssyncd(
600 list_del(&work->w_list); 590 list_del(&work->w_list);
601 if (work == &vfsp->vfs_sync_work) 591 if (work == &vfsp->vfs_sync_work)
602 continue; 592 continue;
603 kmem_free(work, sizeof(struct vfs_sync_work)); 593 kmem_free(work, sizeof(struct bhv_vfs_sync_work));
604 } 594 }
605 } 595 }
606 596
@@ -609,7 +599,7 @@ xfssyncd(
609 599
610STATIC int 600STATIC int
611xfs_fs_start_syncd( 601xfs_fs_start_syncd(
612 vfs_t *vfsp) 602 bhv_vfs_t *vfsp)
613{ 603{
614 vfsp->vfs_sync_work.w_syncer = vfs_sync_worker; 604 vfsp->vfs_sync_work.w_syncer = vfs_sync_worker;
615 vfsp->vfs_sync_work.w_vfs = vfsp; 605 vfsp->vfs_sync_work.w_vfs = vfsp;
@@ -621,7 +611,7 @@ xfs_fs_start_syncd(
621 611
622STATIC void 612STATIC void
623xfs_fs_stop_syncd( 613xfs_fs_stop_syncd(
624 vfs_t *vfsp) 614 bhv_vfs_t *vfsp)
625{ 615{
626 kthread_stop(vfsp->vfs_sync_task); 616 kthread_stop(vfsp->vfs_sync_task);
627} 617}
@@ -630,35 +620,26 @@ STATIC void
630xfs_fs_put_super( 620xfs_fs_put_super(
631 struct super_block *sb) 621 struct super_block *sb)
632{ 622{
633 vfs_t *vfsp = vfs_from_sb(sb); 623 bhv_vfs_t *vfsp = vfs_from_sb(sb);
634 int error; 624 int error;
635 625
636 xfs_fs_stop_syncd(vfsp); 626 xfs_fs_stop_syncd(vfsp);
637 VFS_SYNC(vfsp, SYNC_ATTR|SYNC_DELWRI, NULL, error); 627 bhv_vfs_sync(vfsp, SYNC_ATTR | SYNC_DELWRI, NULL);
638 if (!error) 628 error = bhv_vfs_unmount(vfsp, 0, NULL);
639 VFS_UNMOUNT(vfsp, 0, NULL, error);
640 if (error) { 629 if (error) {
641 printk("XFS unmount got error %d\n", error); 630 printk("XFS: unmount got error=%d\n", error);
642 printk("%s: vfsp/0x%p left dangling!\n", __FUNCTION__, vfsp); 631 printk("%s: vfs=0x%p left dangling!\n", __FUNCTION__, vfsp);
643 return; 632 } else {
633 vfs_deallocate(vfsp);
644 } 634 }
645
646 vfs_deallocate(vfsp);
647} 635}
648 636
649STATIC void 637STATIC void
650xfs_fs_write_super( 638xfs_fs_write_super(
651 struct super_block *sb) 639 struct super_block *sb)
652{ 640{
653 vfs_t *vfsp = vfs_from_sb(sb); 641 if (!(sb->s_flags & MS_RDONLY))
654 int error; 642 bhv_vfs_sync(vfs_from_sb(sb), SYNC_FSDATA, NULL);
655
656 if (sb->s_flags & MS_RDONLY) {
657 sb->s_dirt = 0; /* paranoia */
658 return;
659 }
660 /* Push the log and superblock a little */
661 VFS_SYNC(vfsp, SYNC_FSDATA, NULL, error);
662 sb->s_dirt = 0; 643 sb->s_dirt = 0;
663} 644}
664 645
@@ -667,16 +648,16 @@ xfs_fs_sync_super(
667 struct super_block *sb, 648 struct super_block *sb,
668 int wait) 649 int wait)
669{ 650{
670 vfs_t *vfsp = vfs_from_sb(sb); 651 bhv_vfs_t *vfsp = vfs_from_sb(sb);
671 int error; 652 int error;
672 int flags = SYNC_FSDATA; 653 int flags;
673 654
674 if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) 655 if (unlikely(sb->s_frozen == SB_FREEZE_WRITE))
675 flags = SYNC_QUIESCE; 656 flags = SYNC_QUIESCE;
676 else 657 else
677 flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); 658 flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);
678 659
679 VFS_SYNC(vfsp, flags, NULL, error); 660 error = bhv_vfs_sync(vfsp, flags, NULL);
680 sb->s_dirt = 0; 661 sb->s_dirt = 0;
681 662
682 if (unlikely(laptop_mode)) { 663 if (unlikely(laptop_mode)) {
@@ -706,11 +687,7 @@ xfs_fs_statfs(
706 struct super_block *sb, 687 struct super_block *sb,
707 struct kstatfs *statp) 688 struct kstatfs *statp)
708{ 689{
709 vfs_t *vfsp = vfs_from_sb(sb); 690 return -bhv_vfs_statvfs(vfs_from_sb(sb), statp, NULL);
710 int error;
711
712 VFS_STATVFS(vfsp, statp, NULL, error);
713 return -error;
714} 691}
715 692
716STATIC int 693STATIC int
@@ -719,13 +696,13 @@ xfs_fs_remount(
719 int *flags, 696 int *flags,
720 char *options) 697 char *options)
721{ 698{
722 vfs_t *vfsp = vfs_from_sb(sb); 699 bhv_vfs_t *vfsp = vfs_from_sb(sb);
723 struct xfs_mount_args *args = xfs_args_allocate(sb, 0); 700 struct xfs_mount_args *args = xfs_args_allocate(sb, 0);
724 int error; 701 int error;
725 702
726 VFS_PARSEARGS(vfsp, options, args, 1, error); 703 error = bhv_vfs_parseargs(vfsp, options, args, 1);
727 if (!error) 704 if (!error)
728 VFS_MNTUPDATE(vfsp, flags, args, error); 705 error = bhv_vfs_mntupdate(vfsp, flags, args);
729 kmem_free(args, sizeof(*args)); 706 kmem_free(args, sizeof(*args));
730 return -error; 707 return -error;
731} 708}
@@ -734,7 +711,7 @@ STATIC void
734xfs_fs_lockfs( 711xfs_fs_lockfs(
735 struct super_block *sb) 712 struct super_block *sb)
736{ 713{
737 VFS_FREEZE(vfs_from_sb(sb)); 714 bhv_vfs_freeze(vfs_from_sb(sb));
738} 715}
739 716
740STATIC int 717STATIC int
@@ -742,11 +719,7 @@ xfs_fs_show_options(
742 struct seq_file *m, 719 struct seq_file *m,
743 struct vfsmount *mnt) 720 struct vfsmount *mnt)
744{ 721{
745 struct vfs *vfsp = vfs_from_sb(mnt->mnt_sb); 722 return -bhv_vfs_showargs(vfs_from_sb(mnt->mnt_sb), m);
746 int error;
747
748 VFS_SHOWARGS(vfsp, m, error);
749 return error;
750} 723}
751 724
752STATIC int 725STATIC int
@@ -754,11 +727,7 @@ xfs_fs_quotasync(
754 struct super_block *sb, 727 struct super_block *sb,
755 int type) 728 int type)
756{ 729{
757 struct vfs *vfsp = vfs_from_sb(sb); 730 return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XQUOTASYNC, 0, NULL);
758 int error;
759
760 VFS_QUOTACTL(vfsp, Q_XQUOTASYNC, 0, (caddr_t)NULL, error);
761 return -error;
762} 731}
763 732
764STATIC int 733STATIC int
@@ -766,11 +735,7 @@ xfs_fs_getxstate(
766 struct super_block *sb, 735 struct super_block *sb,
767 struct fs_quota_stat *fqs) 736 struct fs_quota_stat *fqs)
768{ 737{
769 struct vfs *vfsp = vfs_from_sb(sb); 738 return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
770 int error;
771
772 VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error);
773 return -error;
774} 739}
775 740
776STATIC int 741STATIC int
@@ -779,11 +744,7 @@ xfs_fs_setxstate(
779 unsigned int flags, 744 unsigned int flags,
780 int op) 745 int op)
781{ 746{
782 struct vfs *vfsp = vfs_from_sb(sb); 747 return -bhv_vfs_quotactl(vfs_from_sb(sb), op, 0, (caddr_t)&flags);
783 int error;
784
785 VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error);
786 return -error;
787} 748}
788 749
789STATIC int 750STATIC int
@@ -793,13 +754,10 @@ xfs_fs_getxquota(
793 qid_t id, 754 qid_t id,
794 struct fs_disk_quota *fdq) 755 struct fs_disk_quota *fdq)
795{ 756{
796 struct vfs *vfsp = vfs_from_sb(sb); 757 return -bhv_vfs_quotactl(vfs_from_sb(sb),
797 int error, getmode; 758 (type == USRQUOTA) ? Q_XGETQUOTA :
798 759 ((type == GRPQUOTA) ? Q_XGETGQUOTA :
799 getmode = (type == USRQUOTA) ? Q_XGETQUOTA : 760 Q_XGETPQUOTA), id, (caddr_t)fdq);
800 ((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA);
801 VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
802 return -error;
803} 761}
804 762
805STATIC int 763STATIC int
@@ -809,13 +767,10 @@ xfs_fs_setxquota(
809 qid_t id, 767 qid_t id,
810 struct fs_disk_quota *fdq) 768 struct fs_disk_quota *fdq)
811{ 769{
812 struct vfs *vfsp = vfs_from_sb(sb); 770 return -bhv_vfs_quotactl(vfs_from_sb(sb),
813 int error, setmode; 771 (type == USRQUOTA) ? Q_XSETQLIM :
814 772 ((type == GRPQUOTA) ? Q_XSETGQLIM :
815 setmode = (type == USRQUOTA) ? Q_XSETQLIM : 773 Q_XSETPQLIM), id, (caddr_t)fdq);
816 ((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM);
817 VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
818 return -error;
819} 774}
820 775
821STATIC int 776STATIC int
@@ -824,34 +779,32 @@ xfs_fs_fill_super(
824 void *data, 779 void *data,
825 int silent) 780 int silent)
826{ 781{
827 vnode_t *rootvp; 782 struct bhv_vnode *rootvp;
828 struct vfs *vfsp = vfs_allocate(sb); 783 struct bhv_vfs *vfsp = vfs_allocate(sb);
829 struct xfs_mount_args *args = xfs_args_allocate(sb, silent); 784 struct xfs_mount_args *args = xfs_args_allocate(sb, silent);
830 struct kstatfs statvfs; 785 struct kstatfs statvfs;
831 int error, error2; 786 int error;
832 787
833 bhv_insert_all_vfsops(vfsp); 788 bhv_insert_all_vfsops(vfsp);
834 789
835 VFS_PARSEARGS(vfsp, (char *)data, args, 0, error); 790 error = bhv_vfs_parseargs(vfsp, (char *)data, args, 0);
836 if (error) { 791 if (error) {
837 bhv_remove_all_vfsops(vfsp, 1); 792 bhv_remove_all_vfsops(vfsp, 1);
838 goto fail_vfsop; 793 goto fail_vfsop;
839 } 794 }
840 795
841 sb_min_blocksize(sb, BBSIZE); 796 sb_min_blocksize(sb, BBSIZE);
842#ifdef CONFIG_XFS_EXPORT
843 sb->s_export_op = &xfs_export_operations; 797 sb->s_export_op = &xfs_export_operations;
844#endif
845 sb->s_qcop = &xfs_quotactl_operations; 798 sb->s_qcop = &xfs_quotactl_operations;
846 sb->s_op = &xfs_super_operations; 799 sb->s_op = &xfs_super_operations;
847 800
848 VFS_MOUNT(vfsp, args, NULL, error); 801 error = bhv_vfs_mount(vfsp, args, NULL);
849 if (error) { 802 if (error) {
850 bhv_remove_all_vfsops(vfsp, 1); 803 bhv_remove_all_vfsops(vfsp, 1);
851 goto fail_vfsop; 804 goto fail_vfsop;
852 } 805 }
853 806
854 VFS_STATVFS(vfsp, &statvfs, NULL, error); 807 error = bhv_vfs_statvfs(vfsp, &statvfs, NULL);
855 if (error) 808 if (error)
856 goto fail_unmount; 809 goto fail_unmount;
857 810
@@ -863,7 +816,7 @@ xfs_fs_fill_super(
863 sb->s_time_gran = 1; 816 sb->s_time_gran = 1;
864 set_posix_acl_flag(sb); 817 set_posix_acl_flag(sb);
865 818
866 VFS_ROOT(vfsp, &rootvp, error); 819 error = bhv_vfs_root(vfsp, &rootvp);
867 if (error) 820 if (error)
868 goto fail_unmount; 821 goto fail_unmount;
869 822
@@ -892,7 +845,7 @@ fail_vnrele:
892 } 845 }
893 846
894fail_unmount: 847fail_unmount:
895 VFS_UNMOUNT(vfsp, 0, NULL, error2); 848 bhv_vfs_unmount(vfsp, 0, NULL);
896 849
897fail_vfsop: 850fail_vfsop:
898 vfs_deallocate(vfsp); 851 vfs_deallocate(vfsp);
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index 376b96cb513a..33dd1ca13245 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -105,7 +105,7 @@ struct block_device;
105 105
106extern __uint64_t xfs_max_file_offset(unsigned int); 106extern __uint64_t xfs_max_file_offset(unsigned int);
107 107
108extern void xfs_initialize_vnode(bhv_desc_t *, vnode_t *, bhv_desc_t *, int); 108extern void xfs_initialize_vnode(bhv_desc_t *, bhv_vnode_t *, bhv_desc_t *, int);
109 109
110extern void xfs_flush_inode(struct xfs_inode *); 110extern void xfs_flush_inode(struct xfs_inode *);
111extern void xfs_flush_device(struct xfs_inode *); 111extern void xfs_flush_device(struct xfs_inode *);
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c
index 7079cc837210..4af97682bec8 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.c
+++ b/fs/xfs/linux-2.6/xfs_sysctl.c
@@ -120,6 +120,11 @@ STATIC ctl_table xfs_table[] = {
120 &sysctl_intvec, NULL, 120 &sysctl_intvec, NULL,
121 &xfs_params.rotorstep.min, &xfs_params.rotorstep.max}, 121 &xfs_params.rotorstep.min, &xfs_params.rotorstep.max},
122 122
123 {XFS_INHERIT_NODFRG, "inherit_nodefrag", &xfs_params.inherit_nodfrg.val,
124 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
125 &sysctl_intvec, NULL,
126 &xfs_params.inherit_nodfrg.min, &xfs_params.inherit_nodfrg.max},
127
123 /* please keep this the last entry */ 128 /* please keep this the last entry */
124#ifdef CONFIG_PROC_FS 129#ifdef CONFIG_PROC_FS
125 {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val, 130 {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.h b/fs/xfs/linux-2.6/xfs_sysctl.h
index bc8c11f13722..a631fb8cc5ac 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.h
+++ b/fs/xfs/linux-2.6/xfs_sysctl.h
@@ -46,6 +46,7 @@ typedef struct xfs_param {
46 xfs_sysctl_val_t xfs_buf_age; /* Metadata buffer age before flush. */ 46 xfs_sysctl_val_t xfs_buf_age; /* Metadata buffer age before flush. */
47 xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */ 47 xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */
48 xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */ 48 xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */
49 xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */
49} xfs_param_t; 50} xfs_param_t;
50 51
51/* 52/*
@@ -84,6 +85,7 @@ enum {
84 /* XFS_IO_BYPASS = 18 */ 85 /* XFS_IO_BYPASS = 18 */
85 XFS_INHERIT_NOSYM = 19, 86 XFS_INHERIT_NOSYM = 19,
86 XFS_ROTORSTEP = 20, 87 XFS_ROTORSTEP = 20,
88 XFS_INHERIT_NODFRG = 21,
87}; 89};
88 90
89extern xfs_param_t xfs_params; 91extern xfs_param_t xfs_params;
diff --git a/fs/xfs/linux-2.6/xfs_vfs.c b/fs/xfs/linux-2.6/xfs_vfs.c
index 6f7c9f7a8624..6145e8bd0be2 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.c
+++ b/fs/xfs/linux-2.6/xfs_vfs.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_imap.h" 27#include "xfs_imap.h"
29#include "xfs_alloc.h" 28#include "xfs_alloc.h"
@@ -104,7 +103,7 @@ vfs_mntupdate(
104int 103int
105vfs_root( 104vfs_root(
106 struct bhv_desc *bdp, 105 struct bhv_desc *bdp,
107 struct vnode **vpp) 106 struct bhv_vnode **vpp)
108{ 107{
109 struct bhv_desc *next = bdp; 108 struct bhv_desc *next = bdp;
110 109
@@ -117,15 +116,15 @@ vfs_root(
117int 116int
118vfs_statvfs( 117vfs_statvfs(
119 struct bhv_desc *bdp, 118 struct bhv_desc *bdp,
120 xfs_statfs_t *sp, 119 bhv_statvfs_t *statp,
121 struct vnode *vp) 120 struct bhv_vnode *vp)
122{ 121{
123 struct bhv_desc *next = bdp; 122 struct bhv_desc *next = bdp;
124 123
125 ASSERT(next); 124 ASSERT(next);
126 while (! (bhvtovfsops(next))->vfs_statvfs) 125 while (! (bhvtovfsops(next))->vfs_statvfs)
127 next = BHV_NEXT(next); 126 next = BHV_NEXT(next);
128 return ((*bhvtovfsops(next)->vfs_statvfs)(next, sp, vp)); 127 return ((*bhvtovfsops(next)->vfs_statvfs)(next, statp, vp));
129} 128}
130 129
131int 130int
@@ -145,7 +144,7 @@ vfs_sync(
145int 144int
146vfs_vget( 145vfs_vget(
147 struct bhv_desc *bdp, 146 struct bhv_desc *bdp,
148 struct vnode **vpp, 147 struct bhv_vnode **vpp,
149 struct fid *fidp) 148 struct fid *fidp)
150{ 149{
151 struct bhv_desc *next = bdp; 150 struct bhv_desc *next = bdp;
@@ -187,7 +186,7 @@ vfs_quotactl(
187void 186void
188vfs_init_vnode( 187vfs_init_vnode(
189 struct bhv_desc *bdp, 188 struct bhv_desc *bdp,
190 struct vnode *vp, 189 struct bhv_vnode *vp,
191 struct bhv_desc *bp, 190 struct bhv_desc *bp,
192 int unlock) 191 int unlock)
193{ 192{
@@ -226,13 +225,13 @@ vfs_freeze(
226 ((*bhvtovfsops(next)->vfs_freeze)(next)); 225 ((*bhvtovfsops(next)->vfs_freeze)(next));
227} 226}
228 227
229vfs_t * 228bhv_vfs_t *
230vfs_allocate( 229vfs_allocate(
231 struct super_block *sb) 230 struct super_block *sb)
232{ 231{
233 struct vfs *vfsp; 232 struct bhv_vfs *vfsp;
234 233
235 vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP); 234 vfsp = kmem_zalloc(sizeof(bhv_vfs_t), KM_SLEEP);
236 bhv_head_init(VFS_BHVHEAD(vfsp), "vfs"); 235 bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
237 INIT_LIST_HEAD(&vfsp->vfs_sync_list); 236 INIT_LIST_HEAD(&vfsp->vfs_sync_list);
238 spin_lock_init(&vfsp->vfs_sync_lock); 237 spin_lock_init(&vfsp->vfs_sync_lock);
@@ -247,25 +246,25 @@ vfs_allocate(
247 return vfsp; 246 return vfsp;
248} 247}
249 248
250vfs_t * 249bhv_vfs_t *
251vfs_from_sb( 250vfs_from_sb(
252 struct super_block *sb) 251 struct super_block *sb)
253{ 252{
254 return (vfs_t *)sb->s_fs_info; 253 return (bhv_vfs_t *)sb->s_fs_info;
255} 254}
256 255
257void 256void
258vfs_deallocate( 257vfs_deallocate(
259 struct vfs *vfsp) 258 struct bhv_vfs *vfsp)
260{ 259{
261 bhv_head_destroy(VFS_BHVHEAD(vfsp)); 260 bhv_head_destroy(VFS_BHVHEAD(vfsp));
262 kmem_free(vfsp, sizeof(vfs_t)); 261 kmem_free(vfsp, sizeof(bhv_vfs_t));
263} 262}
264 263
265void 264void
266vfs_insertops( 265vfs_insertops(
267 struct vfs *vfsp, 266 struct bhv_vfs *vfsp,
268 struct bhv_vfsops *vfsops) 267 struct bhv_module_vfsops *vfsops)
269{ 268{
270 struct bhv_desc *bdp; 269 struct bhv_desc *bdp;
271 270
@@ -276,9 +275,9 @@ vfs_insertops(
276 275
277void 276void
278vfs_insertbhv( 277vfs_insertbhv(
279 struct vfs *vfsp, 278 struct bhv_vfs *vfsp,
280 struct bhv_desc *bdp, 279 struct bhv_desc *bdp,
281 struct vfsops *vfsops, 280 struct bhv_vfsops *vfsops,
282 void *mount) 281 void *mount)
283{ 282{
284 bhv_desc_init(bdp, mount, vfsp, vfsops); 283 bhv_desc_init(bdp, mount, vfsp, vfsops);
@@ -287,7 +286,7 @@ vfs_insertbhv(
287 286
288void 287void
289bhv_remove_vfsops( 288bhv_remove_vfsops(
290 struct vfs *vfsp, 289 struct bhv_vfs *vfsp,
291 int pos) 290 int pos)
292{ 291{
293 struct bhv_desc *bhv; 292 struct bhv_desc *bhv;
@@ -301,7 +300,7 @@ bhv_remove_vfsops(
301 300
302void 301void
303bhv_remove_all_vfsops( 302bhv_remove_all_vfsops(
304 struct vfs *vfsp, 303 struct bhv_vfs *vfsp,
305 int freebase) 304 int freebase)
306{ 305{
307 struct xfs_mount *mp; 306 struct xfs_mount *mp;
@@ -317,7 +316,7 @@ bhv_remove_all_vfsops(
317 316
318void 317void
319bhv_insert_all_vfsops( 318bhv_insert_all_vfsops(
320 struct vfs *vfsp) 319 struct bhv_vfs *vfsp)
321{ 320{
322 struct xfs_mount *mp; 321 struct xfs_mount *mp;
323 322
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
index 841200c03092..91fc2c4b3353 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -21,42 +21,40 @@
21#include <linux/vfs.h> 21#include <linux/vfs.h>
22#include "xfs_fs.h" 22#include "xfs_fs.h"
23 23
24struct bhv_vfs;
25struct bhv_vnode;
26
24struct fid; 27struct fid;
25struct vfs;
26struct cred; 28struct cred;
27struct vnode;
28struct kstatfs;
29struct seq_file; 29struct seq_file;
30struct super_block; 30struct super_block;
31struct xfs_mount_args; 31struct xfs_mount_args;
32 32
33typedef struct kstatfs xfs_statfs_t; 33typedef struct kstatfs bhv_statvfs_t;
34 34
35typedef struct vfs_sync_work { 35typedef struct bhv_vfs_sync_work {
36 struct list_head w_list; 36 struct list_head w_list;
37 struct vfs *w_vfs; 37 struct bhv_vfs *w_vfs;
38 void *w_data; /* syncer routine argument */ 38 void *w_data; /* syncer routine argument */
39 void (*w_syncer)(struct vfs *, void *); 39 void (*w_syncer)(struct bhv_vfs *, void *);
40} vfs_sync_work_t; 40} bhv_vfs_sync_work_t;
41 41
42typedef struct vfs { 42typedef struct bhv_vfs {
43 u_int vfs_flag; /* flags */ 43 u_int vfs_flag; /* flags */
44 xfs_fsid_t vfs_fsid; /* file system ID */ 44 xfs_fsid_t vfs_fsid; /* file system ID */
45 xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */ 45 xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */
46 bhv_head_t vfs_bh; /* head of vfs behavior chain */ 46 bhv_head_t vfs_bh; /* head of vfs behavior chain */
47 struct super_block *vfs_super; /* generic superblock pointer */ 47 struct super_block *vfs_super; /* generic superblock pointer */
48 struct task_struct *vfs_sync_task; /* generalised sync thread */ 48 struct task_struct *vfs_sync_task; /* generalised sync thread */
49 vfs_sync_work_t vfs_sync_work; /* work item for VFS_SYNC */ 49 bhv_vfs_sync_work_t vfs_sync_work; /* work item for VFS_SYNC */
50 struct list_head vfs_sync_list; /* sync thread work item list */ 50 struct list_head vfs_sync_list; /* sync thread work item list */
51 spinlock_t vfs_sync_lock; /* work item list lock */ 51 spinlock_t vfs_sync_lock; /* work item list lock */
52 int vfs_sync_seq; /* sync thread generation no. */ 52 int vfs_sync_seq; /* sync thread generation no. */
53 wait_queue_head_t vfs_wait_single_sync_task; 53 wait_queue_head_t vfs_wait_single_sync_task;
54} vfs_t; 54} bhv_vfs_t;
55
56#define vfs_fbhv vfs_bh.bh_first /* 1st on vfs behavior chain */
57 55
58#define bhvtovfs(bdp) ( (struct vfs *)BHV_VOBJ(bdp) ) 56#define bhvtovfs(bdp) ( (struct bhv_vfs *)BHV_VOBJ(bdp) )
59#define bhvtovfsops(bdp) ( (struct vfsops *)BHV_OPS(bdp) ) 57#define bhvtovfsops(bdp) ( (struct bhv_vfsops *)BHV_OPS(bdp) )
60#define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh ) 58#define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh )
61#define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) ) 59#define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) )
62 60
@@ -71,7 +69,7 @@ typedef enum {
71 VFS_BHV_QM, /* quota manager */ 69 VFS_BHV_QM, /* quota manager */
72 VFS_BHV_IO, /* IO path */ 70 VFS_BHV_IO, /* IO path */
73 VFS_BHV_END /* housekeeping end-of-range */ 71 VFS_BHV_END /* housekeeping end-of-range */
74} vfs_bhv_t; 72} bhv_vfs_type_t;
75 73
76#define VFS_POSITION_XFS (BHV_POSITION_BASE) 74#define VFS_POSITION_XFS (BHV_POSITION_BASE)
77#define VFS_POSITION_DM (VFS_POSITION_BASE+10) 75#define VFS_POSITION_DM (VFS_POSITION_BASE+10)
@@ -81,8 +79,9 @@ typedef enum {
81#define VFS_RDONLY 0x0001 /* read-only vfs */ 79#define VFS_RDONLY 0x0001 /* read-only vfs */
82#define VFS_GRPID 0x0002 /* group-ID assigned from directory */ 80#define VFS_GRPID 0x0002 /* group-ID assigned from directory */
83#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */ 81#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
84#define VFS_32BITINODES 0x0008 /* do not use inums above 32 bits */ 82#define VFS_UMOUNT 0x0008 /* unmount in progress */
85#define VFS_END 0x0008 /* max flag */ 83#define VFS_32BITINODES 0x0010 /* do not use inums above 32 bits */
84#define VFS_END 0x0010 /* max flag */
86 85
87#define SYNC_ATTR 0x0001 /* sync attributes */ 86#define SYNC_ATTR 0x0001 /* sync attributes */
88#define SYNC_CLOSE 0x0002 /* close file system down */ 87#define SYNC_CLOSE 0x0002 /* close file system down */
@@ -92,7 +91,14 @@ typedef enum {
92#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ 91#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
93#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ 92#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
94#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ 93#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
95#define SYNC_QUIESCE 0x0100 /* quiesce filesystem for a snapshot */ 94#define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */
95
96#define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */
97#define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */
98#define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */
99#define SHUTDOWN_CORRUPT_INCORE 0x0008 /* corrupt in-memory data structures */
100#define SHUTDOWN_REMOTE_REQ 0x0010 /* shutdown came from remote cell */
101#define SHUTDOWN_DEVICE_REQ 0x0020 /* failed all paths to the device */
96 102
97typedef int (*vfs_mount_t)(bhv_desc_t *, 103typedef int (*vfs_mount_t)(bhv_desc_t *,
98 struct xfs_mount_args *, struct cred *); 104 struct xfs_mount_args *, struct cred *);
@@ -102,18 +108,19 @@ typedef int (*vfs_showargs_t)(bhv_desc_t *, struct seq_file *);
102typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *); 108typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *);
103typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *, 109typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *,
104 struct xfs_mount_args *); 110 struct xfs_mount_args *);
105typedef int (*vfs_root_t)(bhv_desc_t *, struct vnode **); 111typedef int (*vfs_root_t)(bhv_desc_t *, struct bhv_vnode **);
106typedef int (*vfs_statvfs_t)(bhv_desc_t *, xfs_statfs_t *, struct vnode *); 112typedef int (*vfs_statvfs_t)(bhv_desc_t *, bhv_statvfs_t *,
113 struct bhv_vnode *);
107typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *); 114typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *);
108typedef int (*vfs_vget_t)(bhv_desc_t *, struct vnode **, struct fid *); 115typedef int (*vfs_vget_t)(bhv_desc_t *, struct bhv_vnode **, struct fid *);
109typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t); 116typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t);
110typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t); 117typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t);
111typedef void (*vfs_init_vnode_t)(bhv_desc_t *, 118typedef void (*vfs_init_vnode_t)(bhv_desc_t *,
112 struct vnode *, bhv_desc_t *, int); 119 struct bhv_vnode *, bhv_desc_t *, int);
113typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int); 120typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int);
114typedef void (*vfs_freeze_t)(bhv_desc_t *); 121typedef void (*vfs_freeze_t)(bhv_desc_t *);
115 122
116typedef struct vfsops { 123typedef struct bhv_vfsops {
117 bhv_position_t vf_position; /* behavior chain position */ 124 bhv_position_t vf_position; /* behavior chain position */
118 vfs_mount_t vfs_mount; /* mount file system */ 125 vfs_mount_t vfs_mount; /* mount file system */
119 vfs_parseargs_t vfs_parseargs; /* parse mount options */ 126 vfs_parseargs_t vfs_parseargs; /* parse mount options */
@@ -129,82 +136,82 @@ typedef struct vfsops {
129 vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */ 136 vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */
130 vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */ 137 vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */
131 vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */ 138 vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */
132} vfsops_t; 139} bhv_vfsops_t;
133 140
134/* 141/*
135 * VFS's. Operates on vfs structure pointers (starts at bhv head). 142 * Virtual filesystem operations, operating from head bhv.
136 */ 143 */
137#define VHEAD(v) ((v)->vfs_fbhv) 144#define VFSHEAD(v) ((v)->vfs_bh.bh_first)
138#define VFS_MOUNT(v, ma,cr, rv) ((rv) = vfs_mount(VHEAD(v), ma,cr)) 145#define bhv_vfs_mount(v, ma,cr) vfs_mount(VFSHEAD(v), ma,cr)
139#define VFS_PARSEARGS(v, o,ma,f, rv) ((rv) = vfs_parseargs(VHEAD(v), o,ma,f)) 146#define bhv_vfs_parseargs(v, o,ma,f) vfs_parseargs(VFSHEAD(v), o,ma,f)
140#define VFS_SHOWARGS(v, m, rv) ((rv) = vfs_showargs(VHEAD(v), m)) 147#define bhv_vfs_showargs(v, m) vfs_showargs(VFSHEAD(v), m)
141#define VFS_UNMOUNT(v, f, cr, rv) ((rv) = vfs_unmount(VHEAD(v), f,cr)) 148#define bhv_vfs_unmount(v, f,cr) vfs_unmount(VFSHEAD(v), f,cr)
142#define VFS_MNTUPDATE(v, fl, args, rv) ((rv) = vfs_mntupdate(VHEAD(v), fl, args)) 149#define bhv_vfs_mntupdate(v, fl,args) vfs_mntupdate(VFSHEAD(v), fl,args)
143#define VFS_ROOT(v, vpp, rv) ((rv) = vfs_root(VHEAD(v), vpp)) 150#define bhv_vfs_root(v, vpp) vfs_root(VFSHEAD(v), vpp)
144#define VFS_STATVFS(v, sp,vp, rv) ((rv) = vfs_statvfs(VHEAD(v), sp,vp)) 151#define bhv_vfs_statvfs(v, sp,vp) vfs_statvfs(VFSHEAD(v), sp,vp)
145#define VFS_SYNC(v, flag,cr, rv) ((rv) = vfs_sync(VHEAD(v), flag,cr)) 152#define bhv_vfs_sync(v, flag,cr) vfs_sync(VFSHEAD(v), flag,cr)
146#define VFS_VGET(v, vpp,fidp, rv) ((rv) = vfs_vget(VHEAD(v), vpp,fidp)) 153#define bhv_vfs_vget(v, vpp,fidp) vfs_vget(VFSHEAD(v), vpp,fidp)
147#define VFS_DMAPIOPS(v, p, rv) ((rv) = vfs_dmapiops(VHEAD(v), p)) 154#define bhv_vfs_dmapiops(v, p) vfs_dmapiops(VFSHEAD(v), p)
148#define VFS_QUOTACTL(v, c,id,p, rv) ((rv) = vfs_quotactl(VHEAD(v), c,id,p)) 155#define bhv_vfs_quotactl(v, c,id,p) vfs_quotactl(VFSHEAD(v), c,id,p)
149#define VFS_INIT_VNODE(v, vp,b,ul) ( vfs_init_vnode(VHEAD(v), vp,b,ul) ) 156#define bhv_vfs_init_vnode(v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul)
150#define VFS_FORCE_SHUTDOWN(v, fl,f,l) ( vfs_force_shutdown(VHEAD(v), fl,f,l) ) 157#define bhv_vfs_force_shutdown(v,u,f,l) vfs_force_shutdown(VFSHEAD(v), u,f,l)
151#define VFS_FREEZE(v) ( vfs_freeze(VHEAD(v)) ) 158#define bhv_vfs_freeze(v) vfs_freeze(VFSHEAD(v))
152 159
153/* 160/*
154 * PVFS's. Operates on behavior descriptor pointers. 161 * Virtual filesystem operations, operating from next bhv.
155 */ 162 */
156#define PVFS_MOUNT(b, ma,cr, rv) ((rv) = vfs_mount(b, ma,cr)) 163#define bhv_next_vfs_mount(b, ma,cr) vfs_mount(b, ma,cr)
157#define PVFS_PARSEARGS(b, o,ma,f, rv) ((rv) = vfs_parseargs(b, o,ma,f)) 164#define bhv_next_vfs_parseargs(b, o,ma,f) vfs_parseargs(b, o,ma,f)
158#define PVFS_SHOWARGS(b, m, rv) ((rv) = vfs_showargs(b, m)) 165#define bhv_next_vfs_showargs(b, m) vfs_showargs(b, m)
159#define PVFS_UNMOUNT(b, f,cr, rv) ((rv) = vfs_unmount(b, f,cr)) 166#define bhv_next_vfs_unmount(b, f,cr) vfs_unmount(b, f,cr)
160#define PVFS_MNTUPDATE(b, fl, args, rv) ((rv) = vfs_mntupdate(b, fl, args)) 167#define bhv_next_vfs_mntupdate(b, fl,args) vfs_mntupdate(b, fl, args)
161#define PVFS_ROOT(b, vpp, rv) ((rv) = vfs_root(b, vpp)) 168#define bhv_next_vfs_root(b, vpp) vfs_root(b, vpp)
162#define PVFS_STATVFS(b, sp,vp, rv) ((rv) = vfs_statvfs(b, sp,vp)) 169#define bhv_next_vfs_statvfs(b, sp,vp) vfs_statvfs(b, sp,vp)
163#define PVFS_SYNC(b, flag,cr, rv) ((rv) = vfs_sync(b, flag,cr)) 170#define bhv_next_vfs_sync(b, flag,cr) vfs_sync(b, flag,cr)
164#define PVFS_VGET(b, vpp,fidp, rv) ((rv) = vfs_vget(b, vpp,fidp)) 171#define bhv_next_vfs_vget(b, vpp,fidp) vfs_vget(b, vpp,fidp)
165#define PVFS_DMAPIOPS(b, p, rv) ((rv) = vfs_dmapiops(b, p)) 172#define bhv_next_vfs_dmapiops(b, p) vfs_dmapiops(b, p)
166#define PVFS_QUOTACTL(b, c,id,p, rv) ((rv) = vfs_quotactl(b, c,id,p)) 173#define bhv_next_vfs_quotactl(b, c,id,p) vfs_quotactl(b, c,id,p)
167#define PVFS_INIT_VNODE(b, vp,b2,ul) ( vfs_init_vnode(b, vp,b2,ul) ) 174#define bhv_next_vfs_init_vnode(b, vp,b2,ul) vfs_init_vnode(b, vp,b2,ul)
168#define PVFS_FORCE_SHUTDOWN(b, fl,f,l) ( vfs_force_shutdown(b, fl,f,l) ) 175#define bhv_next_force_shutdown(b, fl,f,l) vfs_force_shutdown(b, fl,f,l)
169#define PVFS_FREEZE(b) ( vfs_freeze(b) ) 176#define bhv_next_vfs_freeze(b) vfs_freeze(b)
170 177
171extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *); 178extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *);
172extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int); 179extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
173extern int vfs_showargs(bhv_desc_t *, struct seq_file *); 180extern int vfs_showargs(bhv_desc_t *, struct seq_file *);
174extern int vfs_unmount(bhv_desc_t *, int, struct cred *); 181extern int vfs_unmount(bhv_desc_t *, int, struct cred *);
175extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *); 182extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *);
176extern int vfs_root(bhv_desc_t *, struct vnode **); 183extern int vfs_root(bhv_desc_t *, struct bhv_vnode **);
177extern int vfs_statvfs(bhv_desc_t *, xfs_statfs_t *, struct vnode *); 184extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct bhv_vnode *);
178extern int vfs_sync(bhv_desc_t *, int, struct cred *); 185extern int vfs_sync(bhv_desc_t *, int, struct cred *);
179extern int vfs_vget(bhv_desc_t *, struct vnode **, struct fid *); 186extern int vfs_vget(bhv_desc_t *, struct bhv_vnode **, struct fid *);
180extern int vfs_dmapiops(bhv_desc_t *, caddr_t); 187extern int vfs_dmapiops(bhv_desc_t *, caddr_t);
181extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t); 188extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t);
182extern void vfs_init_vnode(bhv_desc_t *, struct vnode *, bhv_desc_t *, int); 189extern void vfs_init_vnode(bhv_desc_t *, struct bhv_vnode *, bhv_desc_t *, int);
183extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int); 190extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int);
184extern void vfs_freeze(bhv_desc_t *); 191extern void vfs_freeze(bhv_desc_t *);
185 192
186typedef struct bhv_vfsops { 193#define vfs_test_for_freeze(vfs) ((vfs)->vfs_super->s_frozen)
187 struct vfsops bhv_common; 194#define vfs_wait_for_freeze(vfs,l) vfs_check_frozen((vfs)->vfs_super, (l))
195
196typedef struct bhv_module_vfsops {
197 struct bhv_vfsops bhv_common;
188 void * bhv_custom; 198 void * bhv_custom;
189} bhv_vfsops_t; 199} bhv_module_vfsops_t;
190 200
191#define vfs_bhv_lookup(v, id) ( bhv_lookup_range(&(v)->vfs_bh, (id), (id)) ) 201#define vfs_bhv_lookup(v, id) (bhv_lookup_range(&(v)->vfs_bh, (id), (id)))
192#define vfs_bhv_custom(b) ( ((bhv_vfsops_t *)BHV_OPS(b))->bhv_custom ) 202#define vfs_bhv_custom(b) (((bhv_module_vfsops_t*)BHV_OPS(b))->bhv_custom)
193#define vfs_bhv_set_custom(b,o) ( (b)->bhv_custom = (void *)(o)) 203#define vfs_bhv_set_custom(b,o) ((b)->bhv_custom = (void *)(o))
194#define vfs_bhv_clr_custom(b) ( (b)->bhv_custom = NULL ) 204#define vfs_bhv_clr_custom(b) ((b)->bhv_custom = NULL)
195 205
196extern vfs_t *vfs_allocate(struct super_block *); 206extern bhv_vfs_t *vfs_allocate(struct super_block *);
197extern vfs_t *vfs_from_sb(struct super_block *); 207extern bhv_vfs_t *vfs_from_sb(struct super_block *);
198extern void vfs_deallocate(vfs_t *); 208extern void vfs_deallocate(bhv_vfs_t *);
199extern void vfs_insertops(vfs_t *, bhv_vfsops_t *); 209extern void vfs_insertbhv(bhv_vfs_t *, bhv_desc_t *, bhv_vfsops_t *, void *);
200extern void vfs_insertbhv(vfs_t *, bhv_desc_t *, vfsops_t *, void *);
201 210
202extern void bhv_insert_all_vfsops(struct vfs *); 211extern void vfs_insertops(bhv_vfs_t *, bhv_module_vfsops_t *);
203extern void bhv_remove_all_vfsops(struct vfs *, int);
204extern void bhv_remove_vfsops(struct vfs *, int);
205 212
206#define fs_frozen(vfsp) ((vfsp)->vfs_super->s_frozen) 213extern void bhv_insert_all_vfsops(struct bhv_vfs *);
207#define fs_check_frozen(vfsp, level) \ 214extern void bhv_remove_all_vfsops(struct bhv_vfs *, int);
208 vfs_check_frozen(vfsp->vfs_super, level); 215extern void bhv_remove_vfsops(struct bhv_vfs *, int);
209 216
210#endif /* __XFS_VFS_H__ */ 217#endif /* __XFS_VFS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index d27c25b27ccd..6628d96b6fd6 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -39,7 +39,7 @@ vn_init(void)
39 39
40void 40void
41vn_iowait( 41vn_iowait(
42 struct vnode *vp) 42 bhv_vnode_t *vp)
43{ 43{
44 wait_queue_head_t *wq = vptosync(vp); 44 wait_queue_head_t *wq = vptosync(vp);
45 45
@@ -48,17 +48,33 @@ vn_iowait(
48 48
49void 49void
50vn_iowake( 50vn_iowake(
51 struct vnode *vp) 51 bhv_vnode_t *vp)
52{ 52{
53 if (atomic_dec_and_test(&vp->v_iocount)) 53 if (atomic_dec_and_test(&vp->v_iocount))
54 wake_up(vptosync(vp)); 54 wake_up(vptosync(vp));
55} 55}
56 56
57struct vnode * 57/*
58 * Volume managers supporting multiple paths can send back ENODEV when the
59 * final path disappears. In this case continuing to fill the page cache
60 * with dirty data which cannot be written out is evil, so prevent that.
61 */
62void
63vn_ioerror(
64 bhv_vnode_t *vp,
65 int error,
66 char *f,
67 int l)
68{
69 if (unlikely(error == -ENODEV))
70 bhv_vfs_force_shutdown(vp->v_vfsp, SHUTDOWN_DEVICE_REQ, f, l);
71}
72
73bhv_vnode_t *
58vn_initialize( 74vn_initialize(
59 struct inode *inode) 75 struct inode *inode)
60{ 76{
61 struct vnode *vp = vn_from_inode(inode); 77 bhv_vnode_t *vp = vn_from_inode(inode);
62 78
63 XFS_STATS_INC(vn_active); 79 XFS_STATS_INC(vn_active);
64 XFS_STATS_INC(vn_alloc); 80 XFS_STATS_INC(vn_alloc);
@@ -94,8 +110,8 @@ vn_initialize(
94 */ 110 */
95void 111void
96vn_revalidate_core( 112vn_revalidate_core(
97 struct vnode *vp, 113 bhv_vnode_t *vp,
98 vattr_t *vap) 114 bhv_vattr_t *vap)
99{ 115{
100 struct inode *inode = vn_to_inode(vp); 116 struct inode *inode = vn_to_inode(vp);
101 117
@@ -130,14 +146,14 @@ vn_revalidate_core(
130 */ 146 */
131int 147int
132__vn_revalidate( 148__vn_revalidate(
133 struct vnode *vp, 149 bhv_vnode_t *vp,
134 struct vattr *vattr) 150 bhv_vattr_t *vattr)
135{ 151{
136 int error; 152 int error;
137 153
138 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 154 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
139 vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS; 155 vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS;
140 VOP_GETATTR(vp, vattr, 0, NULL, error); 156 error = bhv_vop_getattr(vp, vattr, 0, NULL);
141 if (likely(!error)) { 157 if (likely(!error)) {
142 vn_revalidate_core(vp, vattr); 158 vn_revalidate_core(vp, vattr);
143 VUNMODIFY(vp); 159 VUNMODIFY(vp);
@@ -147,9 +163,9 @@ __vn_revalidate(
147 163
148int 164int
149vn_revalidate( 165vn_revalidate(
150 struct vnode *vp) 166 bhv_vnode_t *vp)
151{ 167{
152 vattr_t vattr; 168 bhv_vattr_t vattr;
153 169
154 return __vn_revalidate(vp, &vattr); 170 return __vn_revalidate(vp, &vattr);
155} 171}
@@ -157,9 +173,9 @@ vn_revalidate(
157/* 173/*
158 * Add a reference to a referenced vnode. 174 * Add a reference to a referenced vnode.
159 */ 175 */
160struct vnode * 176bhv_vnode_t *
161vn_hold( 177vn_hold(
162 struct vnode *vp) 178 bhv_vnode_t *vp)
163{ 179{
164 struct inode *inode; 180 struct inode *inode;
165 181
@@ -192,31 +208,31 @@ vn_hold(
192 * Vnode tracing code. 208 * Vnode tracing code.
193 */ 209 */
194void 210void
195vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra) 211vn_trace_entry(bhv_vnode_t *vp, const char *func, inst_t *ra)
196{ 212{
197 KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra); 213 KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra);
198} 214}
199 215
200void 216void
201vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra) 217vn_trace_exit(bhv_vnode_t *vp, const char *func, inst_t *ra)
202{ 218{
203 KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra); 219 KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra);
204} 220}
205 221
206void 222void
207vn_trace_hold(vnode_t *vp, char *file, int line, inst_t *ra) 223vn_trace_hold(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
208{ 224{
209 KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra); 225 KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra);
210} 226}
211 227
212void 228void
213vn_trace_ref(vnode_t *vp, char *file, int line, inst_t *ra) 229vn_trace_ref(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
214{ 230{
215 KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra); 231 KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra);
216} 232}
217 233
218void 234void
219vn_trace_rele(vnode_t *vp, char *file, int line, inst_t *ra) 235vn_trace_rele(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
220{ 236{
221 KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra); 237 KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra);
222} 238}
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 2a8e16c22353..35c6a01963a7 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -14,57 +14,35 @@
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 * Portions Copyright (c) 1989, 1993
19 * The Regents of the University of California. All rights reserved.
20 *
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
23 * are met:
24 * 1. Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * 3. Neither the name of the University nor the names of its contributors
30 * may be used to endorse or promote products derived from this software
31 * without specific prior written permission.
32 *
33 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE.
44 */ 17 */
45#ifndef __XFS_VNODE_H__ 18#ifndef __XFS_VNODE_H__
46#define __XFS_VNODE_H__ 19#define __XFS_VNODE_H__
47 20
48struct uio; 21struct uio;
49struct file; 22struct file;
50struct vattr; 23struct bhv_vfs;
24struct bhv_vattr;
51struct xfs_iomap; 25struct xfs_iomap;
52struct attrlist_cursor_kern; 26struct attrlist_cursor_kern;
53 27
28typedef struct dentry bhv_vname_t;
29typedef __u64 bhv_vnumber_t;
54 30
55typedef xfs_ino_t vnumber_t; 31typedef enum bhv_vflags {
56typedef struct dentry vname_t; 32 VMODIFIED = 0x08, /* XFS inode state possibly differs */
57typedef bhv_head_t vn_bhv_head_t; 33 /* to the Linux inode state. */
34 VTRUNCATED = 0x40, /* truncated down so flush-on-close */
35} bhv_vflags_t;
58 36
59/* 37/*
60 * MP locking protocols: 38 * MP locking protocols:
61 * v_flag, v_vfsp VN_LOCK/VN_UNLOCK 39 * v_flag, v_vfsp VN_LOCK/VN_UNLOCK
62 */ 40 */
63typedef struct vnode { 41typedef struct bhv_vnode {
64 __u32 v_flag; /* vnode flags (see below) */ 42 bhv_vflags_t v_flag; /* vnode flags (see above) */
65 struct vfs *v_vfsp; /* ptr to containing VFS */ 43 bhv_vfs_t *v_vfsp; /* ptr to containing VFS */
66 vnumber_t v_number; /* in-core vnode number */ 44 bhv_vnumber_t v_number; /* in-core vnode number */
67 vn_bhv_head_t v_bh; /* behavior head */ 45 bhv_head_t v_bh; /* behavior head */
68 spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */ 46 spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */
69 atomic_t v_iocount; /* outstanding I/O count */ 47 atomic_t v_iocount; /* outstanding I/O count */
70#ifdef XFS_VNODE_TRACE 48#ifdef XFS_VNODE_TRACE
@@ -72,7 +50,7 @@ typedef struct vnode {
72#endif 50#endif
73 struct inode v_inode; /* Linux inode */ 51 struct inode v_inode; /* Linux inode */
74 /* inode MUST be last */ 52 /* inode MUST be last */
75} vnode_t; 53} bhv_vnode_t;
76 54
77#define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode) 55#define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode)
78#define VN_ISREG(vp) S_ISREG((vp)->v_inode.i_mode) 56#define VN_ISREG(vp) S_ISREG((vp)->v_inode.i_mode)
@@ -80,9 +58,6 @@ typedef struct vnode {
80#define VN_ISCHR(vp) S_ISCHR((vp)->v_inode.i_mode) 58#define VN_ISCHR(vp) S_ISCHR((vp)->v_inode.i_mode)
81#define VN_ISBLK(vp) S_ISBLK((vp)->v_inode.i_mode) 59#define VN_ISBLK(vp) S_ISBLK((vp)->v_inode.i_mode)
82 60
83#define v_fbhv v_bh.bh_first /* first behavior */
84#define v_fops v_bh.bh_first->bd_ops /* first behavior ops */
85
86#define VNODE_POSITION_BASE BHV_POSITION_BASE /* chain bottom */ 61#define VNODE_POSITION_BASE BHV_POSITION_BASE /* chain bottom */
87#define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */ 62#define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */
88#define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */ 63#define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */
@@ -104,8 +79,8 @@ typedef enum {
104/* 79/*
105 * Macros for dealing with the behavior descriptor inside of the vnode. 80 * Macros for dealing with the behavior descriptor inside of the vnode.
106 */ 81 */
107#define BHV_TO_VNODE(bdp) ((vnode_t *)BHV_VOBJ(bdp)) 82#define BHV_TO_VNODE(bdp) ((bhv_vnode_t *)BHV_VOBJ(bdp))
108#define BHV_TO_VNODE_NULL(bdp) ((vnode_t *)BHV_VOBJNULL(bdp)) 83#define BHV_TO_VNODE_NULL(bdp) ((bhv_vnode_t *)BHV_VOBJNULL(bdp))
109 84
110#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh))) 85#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh)))
111#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name) 86#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name)
@@ -116,35 +91,29 @@ typedef enum {
116/* 91/*
117 * Vnode to Linux inode mapping. 92 * Vnode to Linux inode mapping.
118 */ 93 */
119static inline struct vnode *vn_from_inode(struct inode *inode) 94static inline struct bhv_vnode *vn_from_inode(struct inode *inode)
120{ 95{
121 return (vnode_t *)list_entry(inode, vnode_t, v_inode); 96 return (bhv_vnode_t *)list_entry(inode, bhv_vnode_t, v_inode);
122} 97}
123static inline struct inode *vn_to_inode(struct vnode *vnode) 98static inline struct inode *vn_to_inode(struct bhv_vnode *vnode)
124{ 99{
125 return &vnode->v_inode; 100 return &vnode->v_inode;
126} 101}
127 102
128/* 103/*
129 * Vnode flags. 104 * Values for the vop_rwlock/rwunlock flags parameter.
130 */
131#define VMODIFIED 0x8 /* XFS inode state possibly differs */
132 /* to the Linux inode state. */
133
134/*
135 * Values for the VOP_RWLOCK and VOP_RWUNLOCK flags parameter.
136 */ 105 */
137typedef enum vrwlock { 106typedef enum bhv_vrwlock {
138 VRWLOCK_NONE, 107 VRWLOCK_NONE,
139 VRWLOCK_READ, 108 VRWLOCK_READ,
140 VRWLOCK_WRITE, 109 VRWLOCK_WRITE,
141 VRWLOCK_WRITE_DIRECT, 110 VRWLOCK_WRITE_DIRECT,
142 VRWLOCK_TRY_READ, 111 VRWLOCK_TRY_READ,
143 VRWLOCK_TRY_WRITE 112 VRWLOCK_TRY_WRITE
144} vrwlock_t; 113} bhv_vrwlock_t;
145 114
146/* 115/*
147 * Return values for VOP_INACTIVE. A return value of 116 * Return values for bhv_vop_inactive. A return value of
148 * VN_INACTIVE_NOCACHE implies that the file system behavior 117 * VN_INACTIVE_NOCACHE implies that the file system behavior
149 * has disassociated its state and bhv_desc_t from the vnode. 118 * has disassociated its state and bhv_desc_t from the vnode.
150 */ 119 */
@@ -152,18 +121,20 @@ typedef enum vrwlock {
152#define VN_INACTIVE_NOCACHE 1 121#define VN_INACTIVE_NOCACHE 1
153 122
154/* 123/*
155 * Values for the cmd code given to VOP_VNODE_CHANGE. 124 * Values for the cmd code given to vop_vnode_change.
156 */ 125 */
157typedef enum vchange { 126typedef enum bhv_vchange {
158 VCHANGE_FLAGS_FRLOCKS = 0, 127 VCHANGE_FLAGS_FRLOCKS = 0,
159 VCHANGE_FLAGS_ENF_LOCKING = 1, 128 VCHANGE_FLAGS_ENF_LOCKING = 1,
160 VCHANGE_FLAGS_TRUNCATED = 2, 129 VCHANGE_FLAGS_TRUNCATED = 2,
161 VCHANGE_FLAGS_PAGE_DIRTY = 3, 130 VCHANGE_FLAGS_PAGE_DIRTY = 3,
162 VCHANGE_FLAGS_IOEXCL_COUNT = 4 131 VCHANGE_FLAGS_IOEXCL_COUNT = 4
163} vchange_t; 132} bhv_vchange_t;
164 133
134typedef enum { L_FALSE, L_TRUE } lastclose_t;
165 135
166typedef int (*vop_open_t)(bhv_desc_t *, struct cred *); 136typedef int (*vop_open_t)(bhv_desc_t *, struct cred *);
137typedef int (*vop_close_t)(bhv_desc_t *, int, lastclose_t, struct cred *);
167typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *, 138typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
168 const struct iovec *, unsigned int, 139 const struct iovec *, unsigned int,
169 loff_t *, int, struct cred *); 140 loff_t *, int, struct cred *);
@@ -181,27 +152,27 @@ typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *,
181 struct cred *); 152 struct cred *);
182typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, 153typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
183 int, unsigned int, void __user *); 154 int, unsigned int, void __user *);
184typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int, 155typedef int (*vop_getattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
185 struct cred *); 156 struct cred *);
186typedef int (*vop_setattr_t)(bhv_desc_t *, struct vattr *, int, 157typedef int (*vop_setattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
187 struct cred *); 158 struct cred *);
188typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *); 159typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *);
189typedef int (*vop_lookup_t)(bhv_desc_t *, vname_t *, vnode_t **, 160typedef int (*vop_lookup_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t **,
190 int, vnode_t *, struct cred *); 161 int, bhv_vnode_t *, struct cred *);
191typedef int (*vop_create_t)(bhv_desc_t *, vname_t *, struct vattr *, 162typedef int (*vop_create_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
192 vnode_t **, struct cred *); 163 bhv_vnode_t **, struct cred *);
193typedef int (*vop_remove_t)(bhv_desc_t *, vname_t *, struct cred *); 164typedef int (*vop_remove_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
194typedef int (*vop_link_t)(bhv_desc_t *, vnode_t *, vname_t *, 165typedef int (*vop_link_t)(bhv_desc_t *, bhv_vnode_t *, bhv_vname_t *,
195 struct cred *);
196typedef int (*vop_rename_t)(bhv_desc_t *, vname_t *, vnode_t *, vname_t *,
197 struct cred *); 166 struct cred *);
198typedef int (*vop_mkdir_t)(bhv_desc_t *, vname_t *, struct vattr *, 167typedef int (*vop_rename_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
199 vnode_t **, struct cred *); 168 bhv_vname_t *, struct cred *);
200typedef int (*vop_rmdir_t)(bhv_desc_t *, vname_t *, struct cred *); 169typedef int (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
170 bhv_vnode_t **, struct cred *);
171typedef int (*vop_rmdir_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
201typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *, 172typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *,
202 int *); 173 int *);
203typedef int (*vop_symlink_t)(bhv_desc_t *, vname_t *, struct vattr *, 174typedef int (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*,
204 char *, vnode_t **, struct cred *); 175 char *, bhv_vnode_t **, struct cred *);
205typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int, 176typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int,
206 struct cred *); 177 struct cred *);
207typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *, 178typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
@@ -209,8 +180,8 @@ typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
209typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *); 180typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *);
210typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *); 181typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *);
211typedef int (*vop_release_t)(bhv_desc_t *); 182typedef int (*vop_release_t)(bhv_desc_t *);
212typedef int (*vop_rwlock_t)(bhv_desc_t *, vrwlock_t); 183typedef int (*vop_rwlock_t)(bhv_desc_t *, bhv_vrwlock_t);
213typedef void (*vop_rwunlock_t)(bhv_desc_t *, vrwlock_t); 184typedef void (*vop_rwunlock_t)(bhv_desc_t *, bhv_vrwlock_t);
214typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int, 185typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int,
215 struct xfs_iomap *, int *); 186 struct xfs_iomap *, int *);
216typedef int (*vop_reclaim_t)(bhv_desc_t *); 187typedef int (*vop_reclaim_t)(bhv_desc_t *);
@@ -222,8 +193,8 @@ typedef int (*vop_attr_remove_t)(bhv_desc_t *, const char *,
222 int, struct cred *); 193 int, struct cred *);
223typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int, 194typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
224 struct attrlist_cursor_kern *, struct cred *); 195 struct attrlist_cursor_kern *, struct cred *);
225typedef void (*vop_link_removed_t)(bhv_desc_t *, vnode_t *, int); 196typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int);
226typedef void (*vop_vnode_change_t)(bhv_desc_t *, vchange_t, __psint_t); 197typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t);
227typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); 198typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
228typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); 199typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
229typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, 200typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
@@ -231,9 +202,10 @@ typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
231typedef int (*vop_iflush_t)(bhv_desc_t *, int); 202typedef int (*vop_iflush_t)(bhv_desc_t *, int);
232 203
233 204
234typedef struct vnodeops { 205typedef struct bhv_vnodeops {
235 bhv_position_t vn_position; /* position within behavior chain */ 206 bhv_position_t vn_position; /* position within behavior chain */
236 vop_open_t vop_open; 207 vop_open_t vop_open;
208 vop_close_t vop_close;
237 vop_read_t vop_read; 209 vop_read_t vop_read;
238 vop_write_t vop_write; 210 vop_write_t vop_write;
239 vop_sendfile_t vop_sendfile; 211 vop_sendfile_t vop_sendfile;
@@ -271,103 +243,80 @@ typedef struct vnodeops {
271 vop_pflushvp_t vop_flush_pages; 243 vop_pflushvp_t vop_flush_pages;
272 vop_release_t vop_release; 244 vop_release_t vop_release;
273 vop_iflush_t vop_iflush; 245 vop_iflush_t vop_iflush;
274} vnodeops_t; 246} bhv_vnodeops_t;
275 247
276/* 248/*
277 * VOP's. 249 * Virtual node operations, operating from head bhv.
278 */
279#define _VOP_(op, vp) (*((vnodeops_t *)(vp)->v_fops)->op)
280
281#define VOP_READ(vp,file,iov,segs,offset,ioflags,cr,rv) \
282 rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
283#define VOP_WRITE(vp,file,iov,segs,offset,ioflags,cr,rv) \
284 rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
285#define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \
286 rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr)
287#define VOP_SPLICE_READ(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \
288 rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
289#define VOP_SPLICE_WRITE(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \
290 rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
291#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \
292 rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n)
293#define VOP_OPEN(vp, cr, rv) \
294 rv = _VOP_(vop_open, vp)((vp)->v_fbhv, cr)
295#define VOP_GETATTR(vp, vap, f, cr, rv) \
296 rv = _VOP_(vop_getattr, vp)((vp)->v_fbhv, vap, f, cr)
297#define VOP_SETATTR(vp, vap, f, cr, rv) \
298 rv = _VOP_(vop_setattr, vp)((vp)->v_fbhv, vap, f, cr)
299#define VOP_ACCESS(vp, mode, cr, rv) \
300 rv = _VOP_(vop_access, vp)((vp)->v_fbhv, mode, cr)
301#define VOP_LOOKUP(vp,d,vpp,f,rdir,cr,rv) \
302 rv = _VOP_(vop_lookup, vp)((vp)->v_fbhv,d,vpp,f,rdir,cr)
303#define VOP_CREATE(dvp,d,vap,vpp,cr,rv) \
304 rv = _VOP_(vop_create, dvp)((dvp)->v_fbhv,d,vap,vpp,cr)
305#define VOP_REMOVE(dvp,d,cr,rv) \
306 rv = _VOP_(vop_remove, dvp)((dvp)->v_fbhv,d,cr)
307#define VOP_LINK(tdvp,fvp,d,cr,rv) \
308 rv = _VOP_(vop_link, tdvp)((tdvp)->v_fbhv,fvp,d,cr)
309#define VOP_RENAME(fvp,fnm,tdvp,tnm,cr,rv) \
310 rv = _VOP_(vop_rename, fvp)((fvp)->v_fbhv,fnm,tdvp,tnm,cr)
311#define VOP_MKDIR(dp,d,vap,vpp,cr,rv) \
312 rv = _VOP_(vop_mkdir, dp)((dp)->v_fbhv,d,vap,vpp,cr)
313#define VOP_RMDIR(dp,d,cr,rv) \
314 rv = _VOP_(vop_rmdir, dp)((dp)->v_fbhv,d,cr)
315#define VOP_READDIR(vp,uiop,cr,eofp,rv) \
316 rv = _VOP_(vop_readdir, vp)((vp)->v_fbhv,uiop,cr,eofp)
317#define VOP_SYMLINK(dvp,d,vap,tnm,vpp,cr,rv) \
318 rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr)
319#define VOP_READLINK(vp,uiop,fl,cr,rv) \
320 rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,fl,cr)
321#define VOP_FSYNC(vp,f,cr,b,e,rv) \
322 rv = _VOP_(vop_fsync, vp)((vp)->v_fbhv,f,cr,b,e)
323#define VOP_INACTIVE(vp, cr, rv) \
324 rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr)
325#define VOP_RELEASE(vp, rv) \
326 rv = _VOP_(vop_release, vp)((vp)->v_fbhv)
327#define VOP_FID2(vp, fidp, rv) \
328 rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp)
329#define VOP_RWLOCK(vp,i) \
330 (void)_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
331#define VOP_RWLOCK_TRY(vp,i) \
332 _VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
333#define VOP_RWUNLOCK(vp,i) \
334 (void)_VOP_(vop_rwunlock, vp)((vp)->v_fbhv, i)
335#define VOP_FRLOCK(vp,c,fl,flags,offset,fr,rv) \
336 rv = _VOP_(vop_frlock, vp)((vp)->v_fbhv,c,fl,flags,offset,fr)
337#define VOP_RECLAIM(vp, rv) \
338 rv = _VOP_(vop_reclaim, vp)((vp)->v_fbhv)
339#define VOP_ATTR_GET(vp, name, val, vallenp, fl, cred, rv) \
340 rv = _VOP_(vop_attr_get, vp)((vp)->v_fbhv,name,val,vallenp,fl,cred)
341#define VOP_ATTR_SET(vp, name, val, vallen, fl, cred, rv) \
342 rv = _VOP_(vop_attr_set, vp)((vp)->v_fbhv,name,val,vallen,fl,cred)
343#define VOP_ATTR_REMOVE(vp, name, flags, cred, rv) \
344 rv = _VOP_(vop_attr_remove, vp)((vp)->v_fbhv,name,flags,cred)
345#define VOP_ATTR_LIST(vp, buf, buflen, fl, cursor, cred, rv) \
346 rv = _VOP_(vop_attr_list, vp)((vp)->v_fbhv,buf,buflen,fl,cursor,cred)
347#define VOP_LINK_REMOVED(vp, dvp, linkzero) \
348 (void)_VOP_(vop_link_removed, vp)((vp)->v_fbhv, dvp, linkzero)
349#define VOP_VNODE_CHANGE(vp, cmd, val) \
350 (void)_VOP_(vop_vnode_change, vp)((vp)->v_fbhv,cmd,val)
351/*
352 * These are page cache functions that now go thru VOPs.
353 * 'last' parameter is unused and left in for IRIX compatibility
354 */ 250 */
355#define VOP_TOSS_PAGES(vp, first, last, fiopt) \ 251#define VNHEAD(vp) ((vp)->v_bh.bh_first)
356 _VOP_(vop_tosspages, vp)((vp)->v_fbhv,first, last, fiopt) 252#define VOP(op, vp) (*((bhv_vnodeops_t *)VNHEAD(vp)->bd_ops)->op)
357/* 253#define bhv_vop_open(vp, cr) VOP(vop_open, vp)(VNHEAD(vp),cr)
358 * 'last' parameter is unused and left in for IRIX compatibility 254#define bhv_vop_close(vp, f,last,cr) VOP(vop_close, vp)(VNHEAD(vp),f,last,cr)
359 */ 255#define bhv_vop_read(vp,file,iov,segs,offset,ioflags,cr) \
360#define VOP_FLUSHINVAL_PAGES(vp, first, last, fiopt) \ 256 VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
361 _VOP_(vop_flushinval_pages, vp)((vp)->v_fbhv,first,last,fiopt) 257#define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \
362/* 258 VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
363 * 'last' parameter is unused and left in for IRIX compatibility 259#define bhv_vop_sendfile(vp,f,off,ioflags,cnt,act,targ,cr) \
364 */ 260 VOP(vop_sendfile, vp)(VNHEAD(vp),f,off,ioflags,cnt,act,targ,cr)
365#define VOP_FLUSH_PAGES(vp, first, last, flags, fiopt, rv) \ 261#define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \
366 rv = _VOP_(vop_flush_pages, vp)((vp)->v_fbhv,first,last,flags,fiopt) 262 VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
367#define VOP_IOCTL(vp, inode, filp, fl, cmd, arg, rv) \ 263#define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \
368 rv = _VOP_(vop_ioctl, vp)((vp)->v_fbhv,inode,filp,fl,cmd,arg) 264 VOP(vop_splice_write, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
369#define VOP_IFLUSH(vp, flags, rv) \ 265#define bhv_vop_bmap(vp,of,sz,rw,b,n) \
370 rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags) 266 VOP(vop_bmap, vp)(VNHEAD(vp),of,sz,rw,b,n)
267#define bhv_vop_getattr(vp, vap,f,cr) \
268 VOP(vop_getattr, vp)(VNHEAD(vp), vap,f,cr)
269#define bhv_vop_setattr(vp, vap,f,cr) \
270 VOP(vop_setattr, vp)(VNHEAD(vp), vap,f,cr)
271#define bhv_vop_access(vp, mode,cr) VOP(vop_access, vp)(VNHEAD(vp), mode,cr)
272#define bhv_vop_lookup(vp,d,vpp,f,rdir,cr) \
273 VOP(vop_lookup, vp)(VNHEAD(vp),d,vpp,f,rdir,cr)
274#define bhv_vop_create(dvp,d,vap,vpp,cr) \
275 VOP(vop_create, dvp)(VNHEAD(dvp),d,vap,vpp,cr)
276#define bhv_vop_remove(dvp,d,cr) VOP(vop_remove, dvp)(VNHEAD(dvp),d,cr)
277#define bhv_vop_link(dvp,fvp,d,cr) VOP(vop_link, dvp)(VNHEAD(dvp),fvp,d,cr)
278#define bhv_vop_rename(fvp,fnm,tdvp,tnm,cr) \
279 VOP(vop_rename, fvp)(VNHEAD(fvp),fnm,tdvp,tnm,cr)
280#define bhv_vop_mkdir(dp,d,vap,vpp,cr) \
281 VOP(vop_mkdir, dp)(VNHEAD(dp),d,vap,vpp,cr)
282#define bhv_vop_rmdir(dp,d,cr) VOP(vop_rmdir, dp)(VNHEAD(dp),d,cr)
283#define bhv_vop_readdir(vp,uiop,cr,eofp) \
284 VOP(vop_readdir, vp)(VNHEAD(vp),uiop,cr,eofp)
285#define bhv_vop_symlink(dvp,d,vap,tnm,vpp,cr) \
286 VOP(vop_symlink, dvp)(VNHEAD(dvp),d,vap,tnm,vpp,cr)
287#define bhv_vop_readlink(vp,uiop,fl,cr) \
288 VOP(vop_readlink, vp)(VNHEAD(vp),uiop,fl,cr)
289#define bhv_vop_fsync(vp,f,cr,b,e) VOP(vop_fsync, vp)(VNHEAD(vp),f,cr,b,e)
290#define bhv_vop_inactive(vp,cr) VOP(vop_inactive, vp)(VNHEAD(vp),cr)
291#define bhv_vop_release(vp) VOP(vop_release, vp)(VNHEAD(vp))
292#define bhv_vop_fid2(vp,fidp) VOP(vop_fid2, vp)(VNHEAD(vp),fidp)
293#define bhv_vop_rwlock(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
294#define bhv_vop_rwlock_try(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
295#define bhv_vop_rwunlock(vp,i) VOP(vop_rwunlock, vp)(VNHEAD(vp),i)
296#define bhv_vop_frlock(vp,c,fl,flags,offset,fr) \
297 VOP(vop_frlock, vp)(VNHEAD(vp),c,fl,flags,offset,fr)
298#define bhv_vop_reclaim(vp) VOP(vop_reclaim, vp)(VNHEAD(vp))
299#define bhv_vop_attr_get(vp, name, val, vallenp, fl, cred) \
300 VOP(vop_attr_get, vp)(VNHEAD(vp),name,val,vallenp,fl,cred)
301#define bhv_vop_attr_set(vp, name, val, vallen, fl, cred) \
302 VOP(vop_attr_set, vp)(VNHEAD(vp),name,val,vallen,fl,cred)
303#define bhv_vop_attr_remove(vp, name, flags, cred) \
304 VOP(vop_attr_remove, vp)(VNHEAD(vp),name,flags,cred)
305#define bhv_vop_attr_list(vp, buf, buflen, fl, cursor, cred) \
306 VOP(vop_attr_list, vp)(VNHEAD(vp),buf,buflen,fl,cursor,cred)
307#define bhv_vop_link_removed(vp, dvp, linkzero) \
308 VOP(vop_link_removed, vp)(VNHEAD(vp), dvp, linkzero)
309#define bhv_vop_vnode_change(vp, cmd, val) \
310 VOP(vop_vnode_change, vp)(VNHEAD(vp), cmd, val)
311#define bhv_vop_toss_pages(vp, first, last, fiopt) \
312 VOP(vop_tosspages, vp)(VNHEAD(vp), first, last, fiopt)
313#define bhv_vop_flushinval_pages(vp, first, last, fiopt) \
314 VOP(vop_flushinval_pages, vp)(VNHEAD(vp),first,last,fiopt)
315#define bhv_vop_flush_pages(vp, first, last, flags, fiopt) \
316 VOP(vop_flush_pages, vp)(VNHEAD(vp),first,last,flags,fiopt)
317#define bhv_vop_ioctl(vp, inode, filp, fl, cmd, arg) \
318 VOP(vop_ioctl, vp)(VNHEAD(vp),inode,filp,fl,cmd,arg)
319#define bhv_vop_iflush(vp, flags) VOP(vop_iflush, vp)(VNHEAD(vp), flags)
371 320
372/* 321/*
373 * Flags for read/write calls - same values as IRIX 322 * Flags for read/write calls - same values as IRIX
@@ -377,7 +326,7 @@ typedef struct vnodeops {
377#define IO_INVIS 0x00020 /* don't update inode timestamps */ 326#define IO_INVIS 0x00020 /* don't update inode timestamps */
378 327
379/* 328/*
380 * Flags for VOP_IFLUSH call 329 * Flags for vop_iflush call
381 */ 330 */
382#define FLUSH_SYNC 1 /* wait for flush to complete */ 331#define FLUSH_SYNC 1 /* wait for flush to complete */
383#define FLUSH_INODE 2 /* flush the inode itself */ 332#define FLUSH_INODE 2 /* flush the inode itself */
@@ -385,8 +334,7 @@ typedef struct vnodeops {
385 * this inode out to disk */ 334 * this inode out to disk */
386 335
387/* 336/*
388 * Flush/Invalidate options for VOP_TOSS_PAGES, VOP_FLUSHINVAL_PAGES and 337 * Flush/Invalidate options for vop_toss/flush/flushinval_pages.
389 * VOP_FLUSH_PAGES.
390 */ 338 */
391#define FI_NONE 0 /* none */ 339#define FI_NONE 0 /* none */
392#define FI_REMAPF 1 /* Do a remapf prior to the operation */ 340#define FI_REMAPF 1 /* Do a remapf prior to the operation */
@@ -398,7 +346,7 @@ typedef struct vnodeops {
398 * Vnode attributes. va_mask indicates those attributes the caller 346 * Vnode attributes. va_mask indicates those attributes the caller
399 * wants to set or extract. 347 * wants to set or extract.
400 */ 348 */
401typedef struct vattr { 349typedef struct bhv_vattr {
402 int va_mask; /* bit-mask of attributes present */ 350 int va_mask; /* bit-mask of attributes present */
403 mode_t va_mode; /* file access mode and type */ 351 mode_t va_mode; /* file access mode and type */
404 xfs_nlink_t va_nlink; /* number of references to file */ 352 xfs_nlink_t va_nlink; /* number of references to file */
@@ -418,7 +366,7 @@ typedef struct vattr {
418 u_long va_nextents; /* number of extents in file */ 366 u_long va_nextents; /* number of extents in file */
419 u_long va_anextents; /* number of attr extents in file */ 367 u_long va_anextents; /* number of attr extents in file */
420 prid_t va_projid; /* project id */ 368 prid_t va_projid; /* project id */
421} vattr_t; 369} bhv_vattr_t;
422 370
423/* 371/*
424 * setattr or getattr attributes 372 * setattr or getattr attributes
@@ -492,29 +440,17 @@ typedef struct vattr {
492 (VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID) 440 (VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID)
493 441
494extern void vn_init(void); 442extern void vn_init(void);
495extern vnode_t *vn_initialize(struct inode *); 443extern bhv_vnode_t *vn_initialize(struct inode *);
496 444extern int vn_revalidate(struct bhv_vnode *);
497/* 445extern int __vn_revalidate(struct bhv_vnode *, bhv_vattr_t *);
498 * vnode_map structures _must_ match vn_epoch and vnode structure sizes. 446extern void vn_revalidate_core(struct bhv_vnode *, bhv_vattr_t *);
499 */
500typedef struct vnode_map {
501 vfs_t *v_vfsp;
502 vnumber_t v_number; /* in-core vnode number */
503 xfs_ino_t v_ino; /* inode # */
504} vmap_t;
505
506#define VMAP(vp, vmap) {(vmap).v_vfsp = (vp)->v_vfsp, \
507 (vmap).v_number = (vp)->v_number, \
508 (vmap).v_ino = (vp)->v_inode.i_ino; }
509 447
510extern int vn_revalidate(struct vnode *); 448extern void vn_iowait(struct bhv_vnode *vp);
511extern int __vn_revalidate(struct vnode *, vattr_t *); 449extern void vn_iowake(struct bhv_vnode *vp);
512extern void vn_revalidate_core(struct vnode *, vattr_t *);
513 450
514extern void vn_iowait(struct vnode *vp); 451extern void vn_ioerror(struct bhv_vnode *vp, int error, char *f, int l);
515extern void vn_iowake(struct vnode *vp);
516 452
517static inline int vn_count(struct vnode *vp) 453static inline int vn_count(struct bhv_vnode *vp)
518{ 454{
519 return atomic_read(&vn_to_inode(vp)->i_count); 455 return atomic_read(&vn_to_inode(vp)->i_count);
520} 456}
@@ -522,7 +458,7 @@ static inline int vn_count(struct vnode *vp)
522/* 458/*
523 * Vnode reference counting functions (and macros for compatibility). 459 * Vnode reference counting functions (and macros for compatibility).
524 */ 460 */
525extern vnode_t *vn_hold(struct vnode *); 461extern bhv_vnode_t *vn_hold(struct bhv_vnode *);
526 462
527#if defined(XFS_VNODE_TRACE) 463#if defined(XFS_VNODE_TRACE)
528#define VN_HOLD(vp) \ 464#define VN_HOLD(vp) \
@@ -536,7 +472,7 @@ extern vnode_t *vn_hold(struct vnode *);
536#define VN_RELE(vp) (iput(vn_to_inode(vp))) 472#define VN_RELE(vp) (iput(vn_to_inode(vp)))
537#endif 473#endif
538 474
539static inline struct vnode *vn_grab(struct vnode *vp) 475static inline struct bhv_vnode *vn_grab(struct bhv_vnode *vp)
540{ 476{
541 struct inode *inode = igrab(vn_to_inode(vp)); 477 struct inode *inode = igrab(vn_to_inode(vp));
542 return inode ? vn_from_inode(inode) : NULL; 478 return inode ? vn_from_inode(inode) : NULL;
@@ -554,32 +490,39 @@ static inline struct vnode *vn_grab(struct vnode *vp)
554 */ 490 */
555#define VN_LOCK(vp) mutex_spinlock(&(vp)->v_lock) 491#define VN_LOCK(vp) mutex_spinlock(&(vp)->v_lock)
556#define VN_UNLOCK(vp, s) mutex_spinunlock(&(vp)->v_lock, s) 492#define VN_UNLOCK(vp, s) mutex_spinunlock(&(vp)->v_lock, s)
557#define VN_FLAGSET(vp,b) vn_flagset(vp,b)
558#define VN_FLAGCLR(vp,b) vn_flagclr(vp,b)
559 493
560static __inline__ void vn_flagset(struct vnode *vp, uint flag) 494static __inline__ void vn_flagset(struct bhv_vnode *vp, uint flag)
561{ 495{
562 spin_lock(&vp->v_lock); 496 spin_lock(&vp->v_lock);
563 vp->v_flag |= flag; 497 vp->v_flag |= flag;
564 spin_unlock(&vp->v_lock); 498 spin_unlock(&vp->v_lock);
565} 499}
566 500
567static __inline__ void vn_flagclr(struct vnode *vp, uint flag) 501static __inline__ uint vn_flagclr(struct bhv_vnode *vp, uint flag)
568{ 502{
503 uint cleared;
504
569 spin_lock(&vp->v_lock); 505 spin_lock(&vp->v_lock);
506 cleared = (vp->v_flag & flag);
570 vp->v_flag &= ~flag; 507 vp->v_flag &= ~flag;
571 spin_unlock(&vp->v_lock); 508 spin_unlock(&vp->v_lock);
509 return cleared;
572} 510}
573 511
512#define VMODIFY(vp) vn_flagset(vp, VMODIFIED)
513#define VUNMODIFY(vp) vn_flagclr(vp, VMODIFIED)
514#define VTRUNCATE(vp) vn_flagset(vp, VTRUNCATED)
515#define VUNTRUNCATE(vp) vn_flagclr(vp, VTRUNCATED)
516
574/* 517/*
575 * Dealing with bad inodes 518 * Dealing with bad inodes
576 */ 519 */
577static inline void vn_mark_bad(struct vnode *vp) 520static inline void vn_mark_bad(struct bhv_vnode *vp)
578{ 521{
579 make_bad_inode(vn_to_inode(vp)); 522 make_bad_inode(vn_to_inode(vp));
580} 523}
581 524
582static inline int VN_BAD(struct vnode *vp) 525static inline int VN_BAD(struct bhv_vnode *vp)
583{ 526{
584 return is_bad_inode(vn_to_inode(vp)); 527 return is_bad_inode(vn_to_inode(vp));
585} 528}
@@ -587,18 +530,18 @@ static inline int VN_BAD(struct vnode *vp)
587/* 530/*
588 * Extracting atime values in various formats 531 * Extracting atime values in various formats
589 */ 532 */
590static inline void vn_atime_to_bstime(struct vnode *vp, xfs_bstime_t *bs_atime) 533static inline void vn_atime_to_bstime(bhv_vnode_t *vp, xfs_bstime_t *bs_atime)
591{ 534{
592 bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec; 535 bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec;
593 bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec; 536 bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec;
594} 537}
595 538
596static inline void vn_atime_to_timespec(struct vnode *vp, struct timespec *ts) 539static inline void vn_atime_to_timespec(bhv_vnode_t *vp, struct timespec *ts)
597{ 540{
598 *ts = vp->v_inode.i_atime; 541 *ts = vp->v_inode.i_atime;
599} 542}
600 543
601static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt) 544static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
602{ 545{
603 *tt = vp->v_inode.i_atime.tv_sec; 546 *tt = vp->v_inode.i_atime.tv_sec;
604} 547}
@@ -610,11 +553,10 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
610#define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages) 553#define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages)
611#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \ 554#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \
612 PAGECACHE_TAG_DIRTY) 555 PAGECACHE_TAG_DIRTY)
613#define VMODIFY(vp) VN_FLAGSET(vp, VMODIFIED) 556#define VN_TRUNC(vp) ((vp)->v_flag & VTRUNCATED)
614#define VUNMODIFY(vp) VN_FLAGCLR(vp, VMODIFIED)
615 557
616/* 558/*
617 * Flags to VOP_SETATTR/VOP_GETATTR. 559 * Flags to vop_setattr/getattr.
618 */ 560 */
619#define ATTR_UTIME 0x01 /* non-default utime(2) request */ 561#define ATTR_UTIME 0x01 /* non-default utime(2) request */
620#define ATTR_DMI 0x08 /* invocation from a DMI function */ 562#define ATTR_DMI 0x08 /* invocation from a DMI function */
@@ -624,7 +566,7 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
624#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */ 566#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */
625 567
626/* 568/*
627 * Flags to VOP_FSYNC and VOP_RECLAIM. 569 * Flags to vop_fsync/reclaim.
628 */ 570 */
629#define FSYNC_NOWAIT 0 /* asynchronous flush */ 571#define FSYNC_NOWAIT 0 /* asynchronous flush */
630#define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */ 572#define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */
@@ -643,11 +585,11 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
643#define VNODE_KTRACE_REF 4 585#define VNODE_KTRACE_REF 4
644#define VNODE_KTRACE_RELE 5 586#define VNODE_KTRACE_RELE 5
645 587
646extern void vn_trace_entry(struct vnode *, const char *, inst_t *); 588extern void vn_trace_entry(struct bhv_vnode *, const char *, inst_t *);
647extern void vn_trace_exit(struct vnode *, const char *, inst_t *); 589extern void vn_trace_exit(struct bhv_vnode *, const char *, inst_t *);
648extern void vn_trace_hold(struct vnode *, char *, int, inst_t *); 590extern void vn_trace_hold(struct bhv_vnode *, char *, int, inst_t *);
649extern void vn_trace_ref(struct vnode *, char *, int, inst_t *); 591extern void vn_trace_ref(struct bhv_vnode *, char *, int, inst_t *);
650extern void vn_trace_rele(struct vnode *, char *, int, inst_t *); 592extern void vn_trace_rele(struct bhv_vnode *, char *, int, inst_t *);
651 593
652#define VN_TRACE(vp) \ 594#define VN_TRACE(vp) \
653 vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address) 595 vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address)
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 772ac48329ea..3aa771531856 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -444,7 +442,7 @@ xfs_qm_dqalloc(
444 XFS_BMAPI_METADATA | XFS_BMAPI_WRITE, 442 XFS_BMAPI_METADATA | XFS_BMAPI_WRITE,
445 &firstblock, 443 &firstblock,
446 XFS_QM_DQALLOC_SPACE_RES(mp), 444 XFS_QM_DQALLOC_SPACE_RES(mp),
447 &map, &nmaps, &flist))) { 445 &map, &nmaps, &flist, NULL))) {
448 goto error0; 446 goto error0;
449 } 447 }
450 ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); 448 ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB);
@@ -559,7 +557,7 @@ xfs_qm_dqtobp(
559 error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset, 557 error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset,
560 XFS_DQUOT_CLUSTER_SIZE_FSB, 558 XFS_DQUOT_CLUSTER_SIZE_FSB,
561 XFS_BMAPI_METADATA, 559 XFS_BMAPI_METADATA,
562 NULL, 0, &map, &nmaps, NULL); 560 NULL, 0, &map, &nmaps, NULL, NULL);
563 561
564 xfs_iunlock(quotip, XFS_ILOCK_SHARED); 562 xfs_iunlock(quotip, XFS_ILOCK_SHARED);
565 if (error) 563 if (error)
@@ -1261,7 +1259,7 @@ xfs_qm_dqflush(
1261 1259
1262 if (xfs_qm_dqcheck(&dqp->q_core, be32_to_cpu(ddqp->d_id), 1260 if (xfs_qm_dqcheck(&dqp->q_core, be32_to_cpu(ddqp->d_id),
1263 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) { 1261 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) {
1264 xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE); 1262 xfs_force_shutdown(dqp->q_mount, SHUTDOWN_CORRUPT_INCORE);
1265 return XFS_ERROR(EIO); 1263 return XFS_ERROR(EIO);
1266 } 1264 }
1267 1265
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h
index c0c629663a5c..78d3ab95c5fd 100644
--- a/fs/xfs/quota/xfs_dquot.h
+++ b/fs/xfs/quota/xfs_dquot.h
@@ -119,7 +119,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
119 */ 119 */
120#define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\ 120#define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\
121 (dqp)->dq_flags |= XFS_DQ_FLOCKED; } 121 (dqp)->dq_flags |= XFS_DQ_FLOCKED; }
122#define xfs_dqfunlock(dqp) { ASSERT(valusema(&((dqp)->q_flock)) <= 0); \ 122#define xfs_dqfunlock(dqp) { ASSERT(issemalocked(&((dqp)->q_flock))); \
123 vsema(&((dqp)->q_flock)); \ 123 vsema(&((dqp)->q_flock)); \
124 (dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); } 124 (dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); }
125 125
@@ -128,7 +128,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
128#define XFS_DQ_PINUNLOCK(dqp, s) mutex_spinunlock( \ 128#define XFS_DQ_PINUNLOCK(dqp, s) mutex_spinunlock( \
129 &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s) 129 &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s)
130 130
131#define XFS_DQ_IS_FLUSH_LOCKED(dqp) (valusema(&((dqp)->q_flock)) <= 0) 131#define XFS_DQ_IS_FLUSH_LOCKED(dqp) (issemalocked(&((dqp)->q_flock)))
132#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) 132#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp))
133#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) 133#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY)
134#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) 134#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER)
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
index 546f48af882a..5b2dcc58b244 100644
--- a/fs/xfs/quota/xfs_dquot_item.c
+++ b/fs/xfs/quota/xfs_dquot_item.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -248,7 +246,7 @@ xfs_qm_dquot_logitem_pushbuf(
248 * inode flush completed and the inode was taken off the AIL. 246 * inode flush completed and the inode was taken off the AIL.
249 * So, just get out. 247 * So, just get out.
250 */ 248 */
251 if ((valusema(&(dqp->q_flock)) > 0) || 249 if (!issemalocked(&(dqp->q_flock)) ||
252 ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) { 250 ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) {
253 qip->qli_pushbuf_flag = 0; 251 qip->qli_pushbuf_flag = 0;
254 xfs_dqunlock(dqp); 252 xfs_dqunlock(dqp);
@@ -261,7 +259,7 @@ xfs_qm_dquot_logitem_pushbuf(
261 if (bp != NULL) { 259 if (bp != NULL) {
262 if (XFS_BUF_ISDELAYWRITE(bp)) { 260 if (XFS_BUF_ISDELAYWRITE(bp)) {
263 dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) && 261 dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
264 (valusema(&(dqp->q_flock)) <= 0)); 262 issemalocked(&(dqp->q_flock)));
265 qip->qli_pushbuf_flag = 0; 263 qip->qli_pushbuf_flag = 0;
266 xfs_dqunlock(dqp); 264 xfs_dqunlock(dqp);
267 265
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 7fb5eca9bd50..e23e45535c48 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_alloc.h" 28#include "xfs_alloc.h"
30#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
@@ -33,7 +32,6 @@
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -1603,7 +1601,7 @@ xfs_qm_dqiterate(
1603 maxlblkcnt - lblkno, 1601 maxlblkcnt - lblkno,
1604 XFS_BMAPI_METADATA, 1602 XFS_BMAPI_METADATA,
1605 NULL, 1603 NULL,
1606 0, map, &nmaps, NULL); 1604 0, map, &nmaps, NULL, NULL);
1607 xfs_iunlock(qip, XFS_ILOCK_SHARED); 1605 xfs_iunlock(qip, XFS_ILOCK_SHARED);
1608 if (error) 1606 if (error)
1609 break; 1607 break;
@@ -1905,9 +1903,7 @@ xfs_qm_quotacheck(
1905 */ 1903 */
1906 if ((error = xfs_bulkstat(mp, &lastino, &count, 1904 if ((error = xfs_bulkstat(mp, &lastino, &count,
1907 xfs_qm_dqusage_adjust, NULL, 1905 xfs_qm_dqusage_adjust, NULL,
1908 structsz, NULL, 1906 structsz, NULL, BULKSTAT_FG_IGET, &done)))
1909 BULKSTAT_FG_IGET|BULKSTAT_FG_VFSLOCKED,
1910 &done)))
1911 break; 1907 break;
1912 1908
1913 } while (! done); 1909 } while (! done);
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index 6838b36d95a9..e95e99f7168f 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_alloc.h" 28#include "xfs_alloc.h"
30#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
@@ -33,7 +32,6 @@
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -129,7 +127,7 @@ xfs_qm_parseargs(
129 return XFS_ERROR(EINVAL); 127 return XFS_ERROR(EINVAL);
130 } 128 }
131 129
132 PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error); 130 error = bhv_next_vfs_parseargs(BHV_NEXT(bhv), options, args, update);
133 if (!error && !referenced) 131 if (!error && !referenced)
134 bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); 132 bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
135 return error; 133 return error;
@@ -140,9 +138,8 @@ xfs_qm_showargs(
140 struct bhv_desc *bhv, 138 struct bhv_desc *bhv,
141 struct seq_file *m) 139 struct seq_file *m)
142{ 140{
143 struct vfs *vfsp = bhvtovfs(bhv); 141 struct bhv_vfs *vfsp = bhvtovfs(bhv);
144 struct xfs_mount *mp = XFS_VFSTOM(vfsp); 142 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
145 int error;
146 143
147 if (mp->m_qflags & XFS_UQUOTA_ACCT) { 144 if (mp->m_qflags & XFS_UQUOTA_ACCT) {
148 (mp->m_qflags & XFS_UQUOTA_ENFD) ? 145 (mp->m_qflags & XFS_UQUOTA_ENFD) ?
@@ -165,8 +162,7 @@ xfs_qm_showargs(
165 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) 162 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
166 seq_puts(m, "," MNTOPT_NOQUOTA); 163 seq_puts(m, "," MNTOPT_NOQUOTA);
167 164
168 PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); 165 return bhv_next_vfs_showargs(BHV_NEXT(bhv), m);
169 return error;
170} 166}
171 167
172STATIC int 168STATIC int
@@ -175,14 +171,67 @@ xfs_qm_mount(
175 struct xfs_mount_args *args, 171 struct xfs_mount_args *args,
176 struct cred *cr) 172 struct cred *cr)
177{ 173{
178 struct vfs *vfsp = bhvtovfs(bhv); 174 struct bhv_vfs *vfsp = bhvtovfs(bhv);
179 struct xfs_mount *mp = XFS_VFSTOM(vfsp); 175 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
180 int error;
181 176
182 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA)) 177 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
183 xfs_qm_mount_quotainit(mp, args->flags); 178 xfs_qm_mount_quotainit(mp, args->flags);
184 PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); 179 return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr);
185 return error; 180}
181
182/*
183 * Directory tree accounting is implemented using project quotas, where
184 * the project identifier is inherited from parent directories.
185 * A statvfs (df, etc.) of a directory that is using project quota should
186 * return a statvfs of the project, not the entire filesystem.
187 * This makes such trees appear as if they are filesystems in themselves.
188 */
189STATIC int
190xfs_qm_statvfs(
191 struct bhv_desc *bhv,
192 bhv_statvfs_t *statp,
193 struct bhv_vnode *vnode)
194{
195 xfs_mount_t *mp;
196 xfs_inode_t *ip;
197 xfs_dquot_t *dqp;
198 xfs_disk_dquot_t *dp;
199 __uint64_t limit;
200 int error;
201
202 error = bhv_next_vfs_statvfs(BHV_NEXT(bhv), statp, vnode);
203 if (error || !vnode)
204 return error;
205
206 mp = XFS_BHVTOM(bhv);
207 ip = xfs_vtoi(vnode);
208
209 if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
210 return 0;
211 if (!(mp->m_qflags & XFS_PQUOTA_ACCT))
212 return 0;
213 if (!(mp->m_qflags & XFS_OQUOTA_ENFD))
214 return 0;
215
216 if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp))
217 return 0;
218 dp = &dqp->q_core;
219
220 limit = dp->d_blk_softlimit ? dp->d_blk_softlimit : dp->d_blk_hardlimit;
221 if (limit && statp->f_blocks > limit) {
222 statp->f_blocks = limit;
223 statp->f_bfree = (statp->f_blocks > dp->d_bcount) ?
224 (statp->f_blocks - dp->d_bcount) : 0;
225 }
226 limit = dp->d_ino_softlimit ? dp->d_ino_softlimit : dp->d_ino_hardlimit;
227 if (limit && statp->f_files > limit) {
228 statp->f_files = limit;
229 statp->f_ffree = (statp->f_files > dp->d_icount) ?
230 (statp->f_ffree - dp->d_icount) : 0;
231 }
232
233 xfs_qm_dqput(dqp);
234 return 0;
186} 235}
187 236
188STATIC int 237STATIC int
@@ -191,7 +240,7 @@ xfs_qm_syncall(
191 int flags, 240 int flags,
192 cred_t *credp) 241 cred_t *credp)
193{ 242{
194 struct vfs *vfsp = bhvtovfs(bhv); 243 struct bhv_vfs *vfsp = bhvtovfs(bhv);
195 struct xfs_mount *mp = XFS_VFSTOM(vfsp); 244 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
196 int error; 245 int error;
197 246
@@ -210,8 +259,7 @@ xfs_qm_syncall(
210 } 259 }
211 } 260 }
212 } 261 }
213 PVFS_SYNC(BHV_NEXT(bhv), flags, credp, error); 262 return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp);
214 return error;
215} 263}
216 264
217STATIC int 265STATIC int
@@ -346,11 +394,12 @@ STATIC struct xfs_qmops xfs_qmcore_xfs = {
346 .xfs_dqtrxops = &xfs_trans_dquot_ops, 394 .xfs_dqtrxops = &xfs_trans_dquot_ops,
347}; 395};
348 396
349struct bhv_vfsops xfs_qmops = { { 397struct bhv_module_vfsops xfs_qmops = { {
350 BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM), 398 BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM),
351 .vfs_parseargs = xfs_qm_parseargs, 399 .vfs_parseargs = xfs_qm_parseargs,
352 .vfs_showargs = xfs_qm_showargs, 400 .vfs_showargs = xfs_qm_showargs,
353 .vfs_mount = xfs_qm_mount, 401 .vfs_mount = xfs_qm_mount,
402 .vfs_statvfs = xfs_qm_statvfs,
354 .vfs_sync = xfs_qm_syncall, 403 .vfs_sync = xfs_qm_syncall,
355 .vfs_quotactl = xfs_qm_quotactl, }, 404 .vfs_quotactl = xfs_qm_quotactl, },
356}; 405};
diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/quota/xfs_qm_stats.c
index 0570f7733550..6f858fb81a36 100644
--- a/fs/xfs/quota/xfs_qm_stats.c
+++ b/fs/xfs/quota/xfs_qm_stats.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index c55db463bbf2..ed620c4d1594 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -26,7 +26,6 @@
26#include "xfs_trans.h" 26#include "xfs_trans.h"
27#include "xfs_sb.h" 27#include "xfs_sb.h"
28#include "xfs_ag.h" 28#include "xfs_ag.h"
29#include "xfs_dir.h"
30#include "xfs_dir2.h" 29#include "xfs_dir2.h"
31#include "xfs_alloc.h" 30#include "xfs_alloc.h"
32#include "xfs_dmapi.h" 31#include "xfs_dmapi.h"
@@ -35,7 +34,6 @@
35#include "xfs_bmap_btree.h" 34#include "xfs_bmap_btree.h"
36#include "xfs_alloc_btree.h" 35#include "xfs_alloc_btree.h"
37#include "xfs_ialloc_btree.h" 36#include "xfs_ialloc_btree.h"
38#include "xfs_dir_sf.h"
39#include "xfs_dir2_sf.h" 37#include "xfs_dir2_sf.h"
40#include "xfs_attr_sf.h" 38#include "xfs_attr_sf.h"
41#include "xfs_dinode.h" 39#include "xfs_dinode.h"
@@ -91,8 +89,8 @@ xfs_qm_quotactl(
91 xfs_caddr_t addr) 89 xfs_caddr_t addr)
92{ 90{
93 xfs_mount_t *mp; 91 xfs_mount_t *mp;
92 bhv_vfs_t *vfsp;
94 int error; 93 int error;
95 struct vfs *vfsp;
96 94
97 vfsp = bhvtovfs(bdp); 95 vfsp = bhvtovfs(bdp);
98 mp = XFS_VFSTOM(vfsp); 96 mp = XFS_VFSTOM(vfsp);
@@ -1035,7 +1033,7 @@ xfs_qm_dqrele_all_inodes(
1035{ 1033{
1036 xfs_inode_t *ip, *topino; 1034 xfs_inode_t *ip, *topino;
1037 uint ireclaims; 1035 uint ireclaims;
1038 vnode_t *vp; 1036 bhv_vnode_t *vp;
1039 boolean_t vnode_refd; 1037 boolean_t vnode_refd;
1040 1038
1041 ASSERT(mp->m_quotainfo); 1039 ASSERT(mp->m_quotainfo);
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index 9168918db252..0242e9666e8e 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -33,7 +32,6 @@
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
39#include "xfs_inode.h" 37#include "xfs_inode.h"
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index b08b3d9345b7..36fbeccdc722 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -47,7 +47,7 @@ cmn_err(register int level, char *fmt, ...)
47 va_start(ap, fmt); 47 va_start(ap, fmt);
48 if (*fmt == '!') fp++; 48 if (*fmt == '!') fp++;
49 len = vsprintf(message, fp, ap); 49 len = vsprintf(message, fp, ap);
50 if (message[len-1] != '\n') 50 if (level != CE_DEBUG && message[len-1] != '\n')
51 strcat(message, "\n"); 51 strcat(message, "\n");
52 printk("%s%s", err_level[level], message); 52 printk("%s%s", err_level[level], message);
53 va_end(ap); 53 va_end(ap);
@@ -68,7 +68,7 @@ icmn_err(register int level, char *fmt, va_list ap)
68 level = XFS_MAX_ERR_LEVEL; 68 level = XFS_MAX_ERR_LEVEL;
69 spin_lock_irqsave(&xfs_err_lock,flags); 69 spin_lock_irqsave(&xfs_err_lock,flags);
70 len = vsprintf(message, fmt, ap); 70 len = vsprintf(message, fmt, ap);
71 if (message[len-1] != '\n') 71 if (level != CE_DEBUG && message[len-1] != '\n')
72 strcat(message, "\n"); 72 strcat(message, "\n");
73 spin_unlock_irqrestore(&xfs_err_lock,flags); 73 spin_unlock_irqrestore(&xfs_err_lock,flags);
74 printk("%s%s", err_level[level], message); 74 printk("%s%s", err_level[level], message);
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h
index e3bf58112e7e..4f54dca662a8 100644
--- a/fs/xfs/support/debug.h
+++ b/fs/xfs/support/debug.h
@@ -33,9 +33,6 @@ extern void cmn_err(int, char *, ...)
33 __attribute__ ((format (printf, 2, 3))); 33 __attribute__ ((format (printf, 2, 3)));
34extern void assfail(char *expr, char *f, int l); 34extern void assfail(char *expr, char *f, int l);
35 35
36#define prdev(fmt,targ,args...) \
37 printk("Device %s - " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)
38
39#define ASSERT_ALWAYS(expr) \ 36#define ASSERT_ALWAYS(expr) \
40 (unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) 37 (unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
41 38
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 2539af34eb63..4b0cb474be4c 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -21,12 +21,10 @@
21#include "xfs_bit.h" 21#include "xfs_bit.h"
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_ag.h" 23#include "xfs_ag.h"
24#include "xfs_dir.h"
25#include "xfs_dir2.h" 24#include "xfs_dir2.h"
26#include "xfs_bmap_btree.h" 25#include "xfs_bmap_btree.h"
27#include "xfs_alloc_btree.h" 26#include "xfs_alloc_btree.h"
28#include "xfs_ialloc_btree.h" 27#include "xfs_ialloc_btree.h"
29#include "xfs_dir_sf.h"
30#include "xfs_dir2_sf.h" 28#include "xfs_dir2_sf.h"
31#include "xfs_attr_sf.h" 29#include "xfs_attr_sf.h"
32#include "xfs_dinode.h" 30#include "xfs_dinode.h"
@@ -39,15 +37,15 @@
39#include <linux/capability.h> 37#include <linux/capability.h>
40#include <linux/posix_acl_xattr.h> 38#include <linux/posix_acl_xattr.h>
41 39
42STATIC int xfs_acl_setmode(vnode_t *, xfs_acl_t *, int *); 40STATIC int xfs_acl_setmode(bhv_vnode_t *, xfs_acl_t *, int *);
43STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *); 41STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *);
44STATIC void xfs_acl_get_endian(xfs_acl_t *); 42STATIC void xfs_acl_get_endian(xfs_acl_t *);
45STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *); 43STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *);
46STATIC int xfs_acl_invalid(xfs_acl_t *); 44STATIC int xfs_acl_invalid(xfs_acl_t *);
47STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *); 45STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *);
48STATIC void xfs_acl_get_attr(vnode_t *, xfs_acl_t *, int, int, int *); 46STATIC void xfs_acl_get_attr(bhv_vnode_t *, xfs_acl_t *, int, int, int *);
49STATIC void xfs_acl_set_attr(vnode_t *, xfs_acl_t *, int, int *); 47STATIC void xfs_acl_set_attr(bhv_vnode_t *, xfs_acl_t *, int, int *);
50STATIC int xfs_acl_allow_set(vnode_t *, int); 48STATIC int xfs_acl_allow_set(bhv_vnode_t *, int);
51 49
52kmem_zone_t *xfs_acl_zone; 50kmem_zone_t *xfs_acl_zone;
53 51
@@ -57,7 +55,7 @@ kmem_zone_t *xfs_acl_zone;
57 */ 55 */
58int 56int
59xfs_acl_vhasacl_access( 57xfs_acl_vhasacl_access(
60 vnode_t *vp) 58 bhv_vnode_t *vp)
61{ 59{
62 int error; 60 int error;
63 61
@@ -70,7 +68,7 @@ xfs_acl_vhasacl_access(
70 */ 68 */
71int 69int
72xfs_acl_vhasacl_default( 70xfs_acl_vhasacl_default(
73 vnode_t *vp) 71 bhv_vnode_t *vp)
74{ 72{
75 int error; 73 int error;
76 74
@@ -209,7 +207,7 @@ posix_acl_xfs_to_xattr(
209 207
210int 208int
211xfs_acl_vget( 209xfs_acl_vget(
212 vnode_t *vp, 210 bhv_vnode_t *vp,
213 void *acl, 211 void *acl,
214 size_t size, 212 size_t size,
215 int kind) 213 int kind)
@@ -241,10 +239,10 @@ xfs_acl_vget(
241 goto out; 239 goto out;
242 } 240 }
243 if (kind == _ACL_TYPE_ACCESS) { 241 if (kind == _ACL_TYPE_ACCESS) {
244 vattr_t va; 242 bhv_vattr_t va;
245 243
246 va.va_mask = XFS_AT_MODE; 244 va.va_mask = XFS_AT_MODE;
247 VOP_GETATTR(vp, &va, 0, sys_cred, error); 245 error = bhv_vop_getattr(vp, &va, 0, sys_cred);
248 if (error) 246 if (error)
249 goto out; 247 goto out;
250 xfs_acl_sync_mode(va.va_mode, xfs_acl); 248 xfs_acl_sync_mode(va.va_mode, xfs_acl);
@@ -260,7 +258,7 @@ out:
260 258
261int 259int
262xfs_acl_vremove( 260xfs_acl_vremove(
263 vnode_t *vp, 261 bhv_vnode_t *vp,
264 int kind) 262 int kind)
265{ 263{
266 int error; 264 int error;
@@ -268,9 +266,9 @@ xfs_acl_vremove(
268 VN_HOLD(vp); 266 VN_HOLD(vp);
269 error = xfs_acl_allow_set(vp, kind); 267 error = xfs_acl_allow_set(vp, kind);
270 if (!error) { 268 if (!error) {
271 VOP_ATTR_REMOVE(vp, kind == _ACL_TYPE_DEFAULT? 269 error = bhv_vop_attr_remove(vp, kind == _ACL_TYPE_DEFAULT?
272 SGI_ACL_DEFAULT: SGI_ACL_FILE, 270 SGI_ACL_DEFAULT: SGI_ACL_FILE,
273 ATTR_ROOT, sys_cred, error); 271 ATTR_ROOT, sys_cred);
274 if (error == ENOATTR) 272 if (error == ENOATTR)
275 error = 0; /* 'scool */ 273 error = 0; /* 'scool */
276 } 274 }
@@ -280,7 +278,7 @@ xfs_acl_vremove(
280 278
281int 279int
282xfs_acl_vset( 280xfs_acl_vset(
283 vnode_t *vp, 281 bhv_vnode_t *vp,
284 void *acl, 282 void *acl,
285 size_t size, 283 size_t size,
286 int kind) 284 int kind)
@@ -370,10 +368,10 @@ xfs_acl_iaccess(
370 368
371STATIC int 369STATIC int
372xfs_acl_allow_set( 370xfs_acl_allow_set(
373 vnode_t *vp, 371 bhv_vnode_t *vp,
374 int kind) 372 int kind)
375{ 373{
376 vattr_t va; 374 bhv_vattr_t va;
377 int error; 375 int error;
378 376
379 if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND)) 377 if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
@@ -383,7 +381,7 @@ xfs_acl_allow_set(
383 if (vp->v_vfsp->vfs_flag & VFS_RDONLY) 381 if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
384 return EROFS; 382 return EROFS;
385 va.va_mask = XFS_AT_UID; 383 va.va_mask = XFS_AT_UID;
386 VOP_GETATTR(vp, &va, 0, NULL, error); 384 error = bhv_vop_getattr(vp, &va, 0, NULL);
387 if (error) 385 if (error)
388 return error; 386 return error;
389 if (va.va_uid != current->fsuid && !capable(CAP_FOWNER)) 387 if (va.va_uid != current->fsuid && !capable(CAP_FOWNER))
@@ -606,7 +604,7 @@ xfs_acl_get_endian(
606 */ 604 */
607STATIC void 605STATIC void
608xfs_acl_get_attr( 606xfs_acl_get_attr(
609 vnode_t *vp, 607 bhv_vnode_t *vp,
610 xfs_acl_t *aclp, 608 xfs_acl_t *aclp,
611 int kind, 609 int kind,
612 int flags, 610 int flags,
@@ -616,9 +614,9 @@ xfs_acl_get_attr(
616 614
617 ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1); 615 ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1);
618 flags |= ATTR_ROOT; 616 flags |= ATTR_ROOT;
619 VOP_ATTR_GET(vp, 617 *error = bhv_vop_attr_get(vp, kind == _ACL_TYPE_ACCESS ?
620 kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE : SGI_ACL_DEFAULT, 618 SGI_ACL_FILE : SGI_ACL_DEFAULT,
621 (char *)aclp, &len, flags, sys_cred, *error); 619 (char *)aclp, &len, flags, sys_cred);
622 if (*error || (flags & ATTR_KERNOVAL)) 620 if (*error || (flags & ATTR_KERNOVAL))
623 return; 621 return;
624 xfs_acl_get_endian(aclp); 622 xfs_acl_get_endian(aclp);
@@ -629,7 +627,7 @@ xfs_acl_get_attr(
629 */ 627 */
630STATIC void 628STATIC void
631xfs_acl_set_attr( 629xfs_acl_set_attr(
632 vnode_t *vp, 630 bhv_vnode_t *vp,
633 xfs_acl_t *aclp, 631 xfs_acl_t *aclp,
634 int kind, 632 int kind,
635 int *error) 633 int *error)
@@ -654,19 +652,19 @@ xfs_acl_set_attr(
654 INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm); 652 INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm);
655 } 653 }
656 INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt); 654 INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt);
657 VOP_ATTR_SET(vp, 655 *error = bhv_vop_attr_set(vp, kind == _ACL_TYPE_ACCESS ?
658 kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE: SGI_ACL_DEFAULT, 656 SGI_ACL_FILE: SGI_ACL_DEFAULT,
659 (char *)newacl, len, ATTR_ROOT, sys_cred, *error); 657 (char *)newacl, len, ATTR_ROOT, sys_cred);
660 _ACL_FREE(newacl); 658 _ACL_FREE(newacl);
661} 659}
662 660
663int 661int
664xfs_acl_vtoacl( 662xfs_acl_vtoacl(
665 vnode_t *vp, 663 bhv_vnode_t *vp,
666 xfs_acl_t *access_acl, 664 xfs_acl_t *access_acl,
667 xfs_acl_t *default_acl) 665 xfs_acl_t *default_acl)
668{ 666{
669 vattr_t va; 667 bhv_vattr_t va;
670 int error = 0; 668 int error = 0;
671 669
672 if (access_acl) { 670 if (access_acl) {
@@ -678,7 +676,7 @@ xfs_acl_vtoacl(
678 if (!error) { 676 if (!error) {
679 /* Got the ACL, need the mode... */ 677 /* Got the ACL, need the mode... */
680 va.va_mask = XFS_AT_MODE; 678 va.va_mask = XFS_AT_MODE;
681 VOP_GETATTR(vp, &va, 0, sys_cred, error); 679 error = bhv_vop_getattr(vp, &va, 0, sys_cred);
682 } 680 }
683 681
684 if (error) 682 if (error)
@@ -701,8 +699,8 @@ xfs_acl_vtoacl(
701 */ 699 */
702int 700int
703xfs_acl_inherit( 701xfs_acl_inherit(
704 vnode_t *vp, 702 bhv_vnode_t *vp,
705 vattr_t *vap, 703 bhv_vattr_t *vap,
706 xfs_acl_t *pdaclp) 704 xfs_acl_t *pdaclp)
707{ 705{
708 xfs_acl_t *cacl; 706 xfs_acl_t *cacl;
@@ -757,11 +755,11 @@ xfs_acl_inherit(
757 */ 755 */
758STATIC int 756STATIC int
759xfs_acl_setmode( 757xfs_acl_setmode(
760 vnode_t *vp, 758 bhv_vnode_t *vp,
761 xfs_acl_t *acl, 759 xfs_acl_t *acl,
762 int *basicperms) 760 int *basicperms)
763{ 761{
764 vattr_t va; 762 bhv_vattr_t va;
765 xfs_acl_entry_t *ap; 763 xfs_acl_entry_t *ap;
766 xfs_acl_entry_t *gap = NULL; 764 xfs_acl_entry_t *gap = NULL;
767 int i, error, nomask = 1; 765 int i, error, nomask = 1;
@@ -776,7 +774,7 @@ xfs_acl_setmode(
776 * mode. The m:: bits take precedence over the g:: bits. 774 * mode. The m:: bits take precedence over the g:: bits.
777 */ 775 */
778 va.va_mask = XFS_AT_MODE; 776 va.va_mask = XFS_AT_MODE;
779 VOP_GETATTR(vp, &va, 0, sys_cred, error); 777 error = bhv_vop_getattr(vp, &va, 0, sys_cred);
780 if (error) 778 if (error)
781 return error; 779 return error;
782 780
@@ -810,8 +808,7 @@ xfs_acl_setmode(
810 if (gap && nomask) 808 if (gap && nomask)
811 va.va_mode |= gap->ae_perm << 3; 809 va.va_mode |= gap->ae_perm << 3;
812 810
813 VOP_SETATTR(vp, &va, 0, sys_cred, error); 811 return bhv_vop_setattr(vp, &va, 0, sys_cred);
814 return error;
815} 812}
816 813
817/* 814/*
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index 538d0d65b04c..f853cf1a6270 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -50,7 +50,7 @@ typedef struct xfs_acl {
50#ifdef CONFIG_XFS_POSIX_ACL 50#ifdef CONFIG_XFS_POSIX_ACL
51 51
52struct vattr; 52struct vattr;
53struct vnode; 53struct bhv_vnode;
54struct xfs_inode; 54struct xfs_inode;
55 55
56extern struct kmem_zone *xfs_acl_zone; 56extern struct kmem_zone *xfs_acl_zone;
@@ -58,14 +58,14 @@ extern struct kmem_zone *xfs_acl_zone;
58 (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name)) 58 (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name))
59#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone) 59#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone)
60 60
61extern int xfs_acl_inherit(struct vnode *, struct vattr *, xfs_acl_t *); 61extern int xfs_acl_inherit(struct bhv_vnode *, struct bhv_vattr *, xfs_acl_t *);
62extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *); 62extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *);
63extern int xfs_acl_vtoacl(struct vnode *, xfs_acl_t *, xfs_acl_t *); 63extern int xfs_acl_vtoacl(struct bhv_vnode *, xfs_acl_t *, xfs_acl_t *);
64extern int xfs_acl_vhasacl_access(struct vnode *); 64extern int xfs_acl_vhasacl_access(struct bhv_vnode *);
65extern int xfs_acl_vhasacl_default(struct vnode *); 65extern int xfs_acl_vhasacl_default(struct bhv_vnode *);
66extern int xfs_acl_vset(struct vnode *, void *, size_t, int); 66extern int xfs_acl_vset(struct bhv_vnode *, void *, size_t, int);
67extern int xfs_acl_vget(struct vnode *, void *, size_t, int); 67extern int xfs_acl_vget(struct bhv_vnode *, void *, size_t, int);
68extern int xfs_acl_vremove(struct vnode *vp, int); 68extern int xfs_acl_vremove(struct bhv_vnode *, int);
69 69
70#define _ACL_TYPE_ACCESS 1 70#define _ACL_TYPE_ACCESS 1
71#define _ACL_TYPE_DEFAULT 2 71#define _ACL_TYPE_DEFAULT 2
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 8558226281c4..eef6763f3a67 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -1862,7 +1860,7 @@ xfs_alloc_fix_freelist(
1862 (pag->pagf_longest - delta) : 1860 (pag->pagf_longest - delta) :
1863 (pag->pagf_flcount > 0 || pag->pagf_longest > 0); 1861 (pag->pagf_flcount > 0 || pag->pagf_longest > 0);
1864 if (args->minlen + args->alignment + args->minalignslop - 1 > longest || 1862 if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
1865 (args->minleft && 1863 (!(flags & XFS_ALLOC_FLAG_FREEING) &&
1866 (int)(pag->pagf_freeblks + pag->pagf_flcount - 1864 (int)(pag->pagf_freeblks + pag->pagf_flcount -
1867 need - args->total) < 1865 need - args->total) <
1868 (int)args->minleft)) { 1866 (int)args->minleft)) {
@@ -1898,7 +1896,7 @@ xfs_alloc_fix_freelist(
1898 longest = (longest > delta) ? (longest - delta) : 1896 longest = (longest > delta) ? (longest - delta) :
1899 (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); 1897 (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0);
1900 if (args->minlen + args->alignment + args->minalignslop - 1 > longest || 1898 if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
1901 (args->minleft && 1899 (!(flags & XFS_ALLOC_FLAG_FREEING) &&
1902 (int)(be32_to_cpu(agf->agf_freeblks) + 1900 (int)(be32_to_cpu(agf->agf_freeblks) +
1903 be32_to_cpu(agf->agf_flcount) - need - args->total) < 1901 be32_to_cpu(agf->agf_flcount) - need - args->total) <
1904 (int)args->minleft)) { 1902 (int)args->minleft)) {
@@ -1951,8 +1949,14 @@ xfs_alloc_fix_freelist(
1951 * the restrictions correctly. Can happen for free calls 1949 * the restrictions correctly. Can happen for free calls
1952 * on a completely full ag. 1950 * on a completely full ag.
1953 */ 1951 */
1954 if (targs.agbno == NULLAGBLOCK) 1952 if (targs.agbno == NULLAGBLOCK) {
1953 if (!(flags & XFS_ALLOC_FLAG_FREEING)) {
1954 xfs_trans_brelse(tp, agflbp);
1955 args->agbp = NULL;
1956 return 0;
1957 }
1955 break; 1958 break;
1959 }
1956 /* 1960 /*
1957 * Put each allocated block on the list. 1961 * Put each allocated block on the list.
1958 */ 1962 */
@@ -2360,8 +2364,19 @@ xfs_alloc_vextent(
2360 if (args->agno == sagno && 2364 if (args->agno == sagno &&
2361 type == XFS_ALLOCTYPE_START_BNO) 2365 type == XFS_ALLOCTYPE_START_BNO)
2362 args->type = XFS_ALLOCTYPE_THIS_AG; 2366 args->type = XFS_ALLOCTYPE_THIS_AG;
2363 if (++(args->agno) == mp->m_sb.sb_agcount) 2367 /*
2364 args->agno = 0; 2368 * For the first allocation, we can try any AG to get
2369 * space. However, if we already have allocated a
2370 * block, we don't want to try AGs whose number is below
2371 * sagno. Otherwise, we may end up with out-of-order
2372 * locking of AGF, which might cause deadlock.
2373 */
2374 if (++(args->agno) == mp->m_sb.sb_agcount) {
2375 if (args->firstblock != NULLFSBLOCK)
2376 args->agno = sagno;
2377 else
2378 args->agno = 0;
2379 }
2365 /* 2380 /*
2366 * Reached the starting a.g., must either be done 2381 * Reached the starting a.g., must either be done
2367 * or switch to non-trylock mode. 2382 * or switch to non-trylock mode.
@@ -2443,7 +2458,7 @@ xfs_free_extent(
2443 args.minlen = args.minleft = args.minalignslop = 0; 2458 args.minlen = args.minleft = args.minalignslop = 0;
2444 down_read(&args.mp->m_peraglock); 2459 down_read(&args.mp->m_peraglock);
2445 args.pag = &args.mp->m_perag[args.agno]; 2460 args.pag = &args.mp->m_perag[args.agno];
2446 if ((error = xfs_alloc_fix_freelist(&args, 0))) 2461 if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING)))
2447 goto error0; 2462 goto error0;
2448#ifdef DEBUG 2463#ifdef DEBUG
2449 ASSERT(args.agbp != NULL); 2464 ASSERT(args.agbp != NULL);
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
index 2d1f8928b267..650591f999ae 100644
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -41,6 +41,7 @@ typedef enum xfs_alloctype
41 * Flags for xfs_alloc_fix_freelist. 41 * Flags for xfs_alloc_fix_freelist.
42 */ 42 */
43#define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */ 43#define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */
44#define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/
44 45
45/* 46/*
46 * Argument structure for xfs_alloc routines. 47 * Argument structure for xfs_alloc routines.
@@ -70,6 +71,7 @@ typedef struct xfs_alloc_arg {
70 char wasfromfl; /* set if allocation is from freelist */ 71 char wasfromfl; /* set if allocation is from freelist */
71 char isfl; /* set if is freelist blocks - !acctg */ 72 char isfl; /* set if is freelist blocks - !acctg */
72 char userdata; /* set if this is user data */ 73 char userdata; /* set if this is user data */
74 xfs_fsblock_t firstblock; /* io first block allocated */
73} xfs_alloc_arg_t; 75} xfs_alloc_arg_t;
74 76
75/* 77/*
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index a1d92da86ccd..7446556e8021 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index b6e1e02bbb28..1a2101043275 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -27,7 +27,6 @@
27#include "xfs_trans.h" 27#include "xfs_trans.h"
28#include "xfs_sb.h" 28#include "xfs_sb.h"
29#include "xfs_ag.h" 29#include "xfs_ag.h"
30#include "xfs_dir.h"
31#include "xfs_dir2.h" 30#include "xfs_dir2.h"
32#include "xfs_dmapi.h" 31#include "xfs_dmapi.h"
33#include "xfs_mount.h" 32#include "xfs_mount.h"
@@ -35,7 +34,6 @@
35#include "xfs_bmap_btree.h" 34#include "xfs_bmap_btree.h"
36#include "xfs_alloc_btree.h" 35#include "xfs_alloc_btree.h"
37#include "xfs_ialloc_btree.h" 36#include "xfs_ialloc_btree.h"
38#include "xfs_dir_sf.h"
39#include "xfs_dir2_sf.h" 37#include "xfs_dir2_sf.h"
40#include "xfs_attr_sf.h" 38#include "xfs_attr_sf.h"
41#include "xfs_dinode.h" 39#include "xfs_dinode.h"
@@ -1910,7 +1908,7 @@ xfs_attr_rmtval_get(xfs_da_args_t *args)
1910 error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno, 1908 error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno,
1911 args->rmtblkcnt, 1909 args->rmtblkcnt,
1912 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 1910 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
1913 NULL, 0, map, &nmap, NULL); 1911 NULL, 0, map, &nmap, NULL, NULL);
1914 if (error) 1912 if (error)
1915 return(error); 1913 return(error);
1916 ASSERT(nmap >= 1); 1914 ASSERT(nmap >= 1);
@@ -1988,7 +1986,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
1988 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA | 1986 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA |
1989 XFS_BMAPI_WRITE, 1987 XFS_BMAPI_WRITE,
1990 args->firstblock, args->total, &map, &nmap, 1988 args->firstblock, args->total, &map, &nmap,
1991 args->flist); 1989 args->flist, NULL);
1992 if (!error) { 1990 if (!error) {
1993 error = xfs_bmap_finish(&args->trans, args->flist, 1991 error = xfs_bmap_finish(&args->trans, args->flist,
1994 *args->firstblock, &committed); 1992 *args->firstblock, &committed);
@@ -2039,7 +2037,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
2039 error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno, 2037 error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno,
2040 args->rmtblkcnt, 2038 args->rmtblkcnt,
2041 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2039 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2042 args->firstblock, 0, &map, &nmap, NULL); 2040 args->firstblock, 0, &map, &nmap,
2041 NULL, NULL);
2043 if (error) { 2042 if (error) {
2044 return(error); 2043 return(error);
2045 } 2044 }
@@ -2104,7 +2103,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
2104 args->rmtblkcnt, 2103 args->rmtblkcnt,
2105 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2104 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2106 args->firstblock, 0, &map, &nmap, 2105 args->firstblock, 0, &map, &nmap,
2107 args->flist); 2106 args->flist, NULL);
2108 if (error) { 2107 if (error) {
2109 return(error); 2108 return(error);
2110 } 2109 }
@@ -2142,7 +2141,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
2142 XFS_BMAP_INIT(args->flist, args->firstblock); 2141 XFS_BMAP_INIT(args->flist, args->firstblock);
2143 error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, 2142 error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,
2144 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2143 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2145 1, args->firstblock, args->flist, &done); 2144 1, args->firstblock, args->flist,
2145 NULL, &done);
2146 if (!error) { 2146 if (!error) {
2147 error = xfs_bmap_finish(&args->trans, args->flist, 2147 error = xfs_bmap_finish(&args->trans, args->flist,
2148 *args->firstblock, &committed); 2148 *args->firstblock, &committed);
@@ -2322,56 +2322,56 @@ xfs_attr_trace_enter(int type, char *where,
2322 2322
2323STATIC int 2323STATIC int
2324posix_acl_access_set( 2324posix_acl_access_set(
2325 vnode_t *vp, char *name, void *data, size_t size, int xflags) 2325 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2326{ 2326{
2327 return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS); 2327 return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS);
2328} 2328}
2329 2329
2330STATIC int 2330STATIC int
2331posix_acl_access_remove( 2331posix_acl_access_remove(
2332 struct vnode *vp, char *name, int xflags) 2332 bhv_vnode_t *vp, char *name, int xflags)
2333{ 2333{
2334 return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS); 2334 return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
2335} 2335}
2336 2336
2337STATIC int 2337STATIC int
2338posix_acl_access_get( 2338posix_acl_access_get(
2339 vnode_t *vp, char *name, void *data, size_t size, int xflags) 2339 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2340{ 2340{
2341 return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS); 2341 return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
2342} 2342}
2343 2343
2344STATIC int 2344STATIC int
2345posix_acl_access_exists( 2345posix_acl_access_exists(
2346 vnode_t *vp) 2346 bhv_vnode_t *vp)
2347{ 2347{
2348 return xfs_acl_vhasacl_access(vp); 2348 return xfs_acl_vhasacl_access(vp);
2349} 2349}
2350 2350
2351STATIC int 2351STATIC int
2352posix_acl_default_set( 2352posix_acl_default_set(
2353 vnode_t *vp, char *name, void *data, size_t size, int xflags) 2353 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2354{ 2354{
2355 return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT); 2355 return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT);
2356} 2356}
2357 2357
2358STATIC int 2358STATIC int
2359posix_acl_default_get( 2359posix_acl_default_get(
2360 vnode_t *vp, char *name, void *data, size_t size, int xflags) 2360 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2361{ 2361{
2362 return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT); 2362 return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
2363} 2363}
2364 2364
2365STATIC int 2365STATIC int
2366posix_acl_default_remove( 2366posix_acl_default_remove(
2367 struct vnode *vp, char *name, int xflags) 2367 bhv_vnode_t *vp, char *name, int xflags)
2368{ 2368{
2369 return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT); 2369 return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
2370} 2370}
2371 2371
2372STATIC int 2372STATIC int
2373posix_acl_default_exists( 2373posix_acl_default_exists(
2374 vnode_t *vp) 2374 bhv_vnode_t *vp)
2375{ 2375{
2376 return xfs_acl_vhasacl_default(vp); 2376 return xfs_acl_vhasacl_default(vp);
2377} 2377}
@@ -2404,21 +2404,18 @@ STATIC struct attrnames *attr_system_names[] =
2404 2404
2405STATIC int 2405STATIC int
2406attr_generic_set( 2406attr_generic_set(
2407 struct vnode *vp, char *name, void *data, size_t size, int xflags) 2407 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2408{ 2408{
2409 int error; 2409 return -bhv_vop_attr_set(vp, name, data, size, xflags, NULL);
2410
2411 VOP_ATTR_SET(vp, name, data, size, xflags, NULL, error);
2412 return -error;
2413} 2410}
2414 2411
2415STATIC int 2412STATIC int
2416attr_generic_get( 2413attr_generic_get(
2417 struct vnode *vp, char *name, void *data, size_t size, int xflags) 2414 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2418{ 2415{
2419 int error, asize = size; 2416 int error, asize = size;
2420 2417
2421 VOP_ATTR_GET(vp, name, data, &asize, xflags, NULL, error); 2418 error = bhv_vop_attr_get(vp, name, data, &asize, xflags, NULL);
2422 if (!error) 2419 if (!error)
2423 return asize; 2420 return asize;
2424 return -error; 2421 return -error;
@@ -2426,12 +2423,9 @@ attr_generic_get(
2426 2423
2427STATIC int 2424STATIC int
2428attr_generic_remove( 2425attr_generic_remove(
2429 struct vnode *vp, char *name, int xflags) 2426 bhv_vnode_t *vp, char *name, int xflags)
2430{ 2427{
2431 int error; 2428 return -bhv_vop_attr_remove(vp, name, xflags, NULL);
2432
2433 VOP_ATTR_REMOVE(vp, name, xflags, NULL, error);
2434 return -error;
2435} 2429}
2436 2430
2437STATIC int 2431STATIC int
@@ -2459,7 +2453,7 @@ attr_generic_listadd(
2459 2453
2460STATIC int 2454STATIC int
2461attr_system_list( 2455attr_system_list(
2462 struct vnode *vp, 2456 bhv_vnode_t *vp,
2463 void *data, 2457 void *data,
2464 size_t size, 2458 size_t size,
2465 ssize_t *result) 2459 ssize_t *result)
@@ -2481,12 +2475,12 @@ attr_system_list(
2481 2475
2482int 2476int
2483attr_generic_list( 2477attr_generic_list(
2484 struct vnode *vp, void *data, size_t size, int xflags, ssize_t *result) 2478 bhv_vnode_t *vp, void *data, size_t size, int xflags, ssize_t *result)
2485{ 2479{
2486 attrlist_cursor_kern_t cursor = { 0 }; 2480 attrlist_cursor_kern_t cursor = { 0 };
2487 int error; 2481 int error;
2488 2482
2489 VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error); 2483 error = bhv_vop_attr_list(vp, data, size, xflags, &cursor, NULL);
2490 if (error > 0) 2484 if (error > 0)
2491 return -error; 2485 return -error;
2492 *result = -error; 2486 *result = -error;
@@ -2514,7 +2508,7 @@ attr_lookup_namespace(
2514 */ 2508 */
2515STATIC int 2509STATIC int
2516attr_user_capable( 2510attr_user_capable(
2517 struct vnode *vp, 2511 bhv_vnode_t *vp,
2518 cred_t *cred) 2512 cred_t *cred)
2519{ 2513{
2520 struct inode *inode = vn_to_inode(vp); 2514 struct inode *inode = vn_to_inode(vp);
@@ -2532,7 +2526,7 @@ attr_user_capable(
2532 2526
2533STATIC int 2527STATIC int
2534attr_trusted_capable( 2528attr_trusted_capable(
2535 struct vnode *vp, 2529 bhv_vnode_t *vp,
2536 cred_t *cred) 2530 cred_t *cred)
2537{ 2531{
2538 struct inode *inode = vn_to_inode(vp); 2532 struct inode *inode = vn_to_inode(vp);
@@ -2546,7 +2540,7 @@ attr_trusted_capable(
2546 2540
2547STATIC int 2541STATIC int
2548attr_secure_capable( 2542attr_secure_capable(
2549 struct vnode *vp, 2543 bhv_vnode_t *vp,
2550 cred_t *cred) 2544 cred_t *cred)
2551{ 2545{
2552 return -ENOSECURITY; 2546 return -ENOSECURITY;
@@ -2554,7 +2548,7 @@ attr_secure_capable(
2554 2548
2555STATIC int 2549STATIC int
2556attr_system_set( 2550attr_system_set(
2557 struct vnode *vp, char *name, void *data, size_t size, int xflags) 2551 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2558{ 2552{
2559 attrnames_t *namesp; 2553 attrnames_t *namesp;
2560 int error; 2554 int error;
@@ -2573,7 +2567,7 @@ attr_system_set(
2573 2567
2574STATIC int 2568STATIC int
2575attr_system_get( 2569attr_system_get(
2576 struct vnode *vp, char *name, void *data, size_t size, int xflags) 2570 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2577{ 2571{
2578 attrnames_t *namesp; 2572 attrnames_t *namesp;
2579 2573
@@ -2585,7 +2579,7 @@ attr_system_get(
2585 2579
2586STATIC int 2580STATIC int
2587attr_system_remove( 2581attr_system_remove(
2588 struct vnode *vp, char *name, int xflags) 2582 bhv_vnode_t *vp, char *name, int xflags)
2589{ 2583{
2590 attrnames_t *namesp; 2584 attrnames_t *namesp;
2591 2585
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index b2c7b9fcded3..981633f6c077 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -36,13 +36,13 @@
36 *========================================================================*/ 36 *========================================================================*/
37 37
38struct cred; 38struct cred;
39struct vnode; 39struct bhv_vnode;
40 40
41typedef int (*attrset_t)(struct vnode *, char *, void *, size_t, int); 41typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int);
42typedef int (*attrget_t)(struct vnode *, char *, void *, size_t, int); 42typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int);
43typedef int (*attrremove_t)(struct vnode *, char *, int); 43typedef int (*attrremove_t)(struct bhv_vnode *, char *, int);
44typedef int (*attrexists_t)(struct vnode *); 44typedef int (*attrexists_t)(struct bhv_vnode *);
45typedef int (*attrcapable_t)(struct vnode *, struct cred *); 45typedef int (*attrcapable_t)(struct bhv_vnode *, struct cred *);
46 46
47typedef struct attrnames { 47typedef struct attrnames {
48 char * attr_name; 48 char * attr_name;
@@ -63,7 +63,7 @@ extern struct attrnames attr_trusted;
63extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; 63extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
64 64
65extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); 65extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
66extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *); 66extern int attr_generic_list(struct bhv_vnode *, void *, size_t, int, ssize_t *);
67 67
68#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ 68#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */
69#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ 69#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 9462be86aa14..9455051f0120 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -34,7 +33,6 @@
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_alloc.h" 34#include "xfs_alloc.h"
36#include "xfs_btree.h" 35#include "xfs_btree.h"
37#include "xfs_dir_sf.h"
38#include "xfs_dir2_sf.h" 36#include "xfs_dir2_sf.h"
39#include "xfs_attr_sf.h" 37#include "xfs_attr_sf.h"
40#include "xfs_dinode.h" 38#include "xfs_dinode.h"
@@ -2990,7 +2988,7 @@ xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
2990 nmap = 1; 2988 nmap = 1;
2991 error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt, 2989 error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt,
2992 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2990 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2993 NULL, 0, &map, &nmap, NULL); 2991 NULL, 0, &map, &nmap, NULL, NULL);
2994 if (error) { 2992 if (error) {
2995 return(error); 2993 return(error);
2996 } 2994 }
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 26939d364bc4..3a6137539064 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,13 +24,11 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h" 30#include "xfs_alloc_btree.h"
32#include "xfs_ialloc_btree.h" 31#include "xfs_ialloc_btree.h"
33#include "xfs_dir_sf.h"
34#include "xfs_dir2_sf.h" 32#include "xfs_dir2_sf.h"
35#include "xfs_attr_sf.h" 33#include "xfs_attr_sf.h"
36#include "xfs_dinode.h" 34#include "xfs_dinode.h"
@@ -40,13 +38,15 @@
40#include "xfs_mount.h" 38#include "xfs_mount.h"
41#include "xfs_ialloc.h" 39#include "xfs_ialloc.h"
42#include "xfs_itable.h" 40#include "xfs_itable.h"
41#include "xfs_dir2_data.h"
42#include "xfs_dir2_leaf.h"
43#include "xfs_dir2_block.h"
43#include "xfs_inode_item.h" 44#include "xfs_inode_item.h"
44#include "xfs_extfree_item.h" 45#include "xfs_extfree_item.h"
45#include "xfs_alloc.h" 46#include "xfs_alloc.h"
46#include "xfs_bmap.h" 47#include "xfs_bmap.h"
47#include "xfs_rtalloc.h" 48#include "xfs_rtalloc.h"
48#include "xfs_error.h" 49#include "xfs_error.h"
49#include "xfs_dir_leaf.h"
50#include "xfs_attr_leaf.h" 50#include "xfs_attr_leaf.h"
51#include "xfs_rw.h" 51#include "xfs_rw.h"
52#include "xfs_quota.h" 52#include "xfs_quota.h"
@@ -101,6 +101,7 @@ xfs_bmap_add_extent(
101 xfs_fsblock_t *first, /* pointer to firstblock variable */ 101 xfs_fsblock_t *first, /* pointer to firstblock variable */
102 xfs_bmap_free_t *flist, /* list of extents to be freed */ 102 xfs_bmap_free_t *flist, /* list of extents to be freed */
103 int *logflagsp, /* inode logging flags */ 103 int *logflagsp, /* inode logging flags */
104 xfs_extdelta_t *delta, /* Change made to incore extents */
104 int whichfork, /* data or attr fork */ 105 int whichfork, /* data or attr fork */
105 int rsvd); /* OK to allocate reserved blocks */ 106 int rsvd); /* OK to allocate reserved blocks */
106 107
@@ -118,6 +119,7 @@ xfs_bmap_add_extent_delay_real(
118 xfs_fsblock_t *first, /* pointer to firstblock variable */ 119 xfs_fsblock_t *first, /* pointer to firstblock variable */
119 xfs_bmap_free_t *flist, /* list of extents to be freed */ 120 xfs_bmap_free_t *flist, /* list of extents to be freed */
120 int *logflagsp, /* inode logging flags */ 121 int *logflagsp, /* inode logging flags */
122 xfs_extdelta_t *delta, /* Change made to incore extents */
121 int rsvd); /* OK to allocate reserved blocks */ 123 int rsvd); /* OK to allocate reserved blocks */
122 124
123/* 125/*
@@ -131,6 +133,7 @@ xfs_bmap_add_extent_hole_delay(
131 xfs_btree_cur_t *cur, /* if null, not a btree */ 133 xfs_btree_cur_t *cur, /* if null, not a btree */
132 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 134 xfs_bmbt_irec_t *new, /* new data to add to file extents */
133 int *logflagsp,/* inode logging flags */ 135 int *logflagsp,/* inode logging flags */
136 xfs_extdelta_t *delta, /* Change made to incore extents */
134 int rsvd); /* OK to allocate reserved blocks */ 137 int rsvd); /* OK to allocate reserved blocks */
135 138
136/* 139/*
@@ -144,6 +147,7 @@ xfs_bmap_add_extent_hole_real(
144 xfs_btree_cur_t *cur, /* if null, not a btree */ 147 xfs_btree_cur_t *cur, /* if null, not a btree */
145 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 148 xfs_bmbt_irec_t *new, /* new data to add to file extents */
146 int *logflagsp, /* inode logging flags */ 149 int *logflagsp, /* inode logging flags */
150 xfs_extdelta_t *delta, /* Change made to incore extents */
147 int whichfork); /* data or attr fork */ 151 int whichfork); /* data or attr fork */
148 152
149/* 153/*
@@ -156,7 +160,8 @@ xfs_bmap_add_extent_unwritten_real(
156 xfs_extnum_t idx, /* extent number to update/insert */ 160 xfs_extnum_t idx, /* extent number to update/insert */
157 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 161 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
158 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 162 xfs_bmbt_irec_t *new, /* new data to add to file extents */
159 int *logflagsp); /* inode logging flags */ 163 int *logflagsp, /* inode logging flags */
164 xfs_extdelta_t *delta); /* Change made to incore extents */
160 165
161/* 166/*
162 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. 167 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
@@ -203,6 +208,7 @@ xfs_bmap_del_extent(
203 xfs_btree_cur_t *cur, /* if null, not a btree */ 208 xfs_btree_cur_t *cur, /* if null, not a btree */
204 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 209 xfs_bmbt_irec_t *new, /* new data to add to file extents */
205 int *logflagsp,/* inode logging flags */ 210 int *logflagsp,/* inode logging flags */
211 xfs_extdelta_t *delta, /* Change made to incore extents */
206 int whichfork, /* data or attr fork */ 212 int whichfork, /* data or attr fork */
207 int rsvd); /* OK to allocate reserved blocks */ 213 int rsvd); /* OK to allocate reserved blocks */
208 214
@@ -510,7 +516,7 @@ xfs_bmap_add_attrfork_local(
510 dargs.total = mp->m_dirblkfsbs; 516 dargs.total = mp->m_dirblkfsbs;
511 dargs.whichfork = XFS_DATA_FORK; 517 dargs.whichfork = XFS_DATA_FORK;
512 dargs.trans = tp; 518 dargs.trans = tp;
513 error = XFS_DIR_SHORTFORM_TO_SINGLE(mp, &dargs); 519 error = xfs_dir2_sf_to_block(&dargs);
514 } else 520 } else
515 error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags, 521 error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags,
516 XFS_DATA_FORK); 522 XFS_DATA_FORK);
@@ -530,6 +536,7 @@ xfs_bmap_add_extent(
530 xfs_fsblock_t *first, /* pointer to firstblock variable */ 536 xfs_fsblock_t *first, /* pointer to firstblock variable */
531 xfs_bmap_free_t *flist, /* list of extents to be freed */ 537 xfs_bmap_free_t *flist, /* list of extents to be freed */
532 int *logflagsp, /* inode logging flags */ 538 int *logflagsp, /* inode logging flags */
539 xfs_extdelta_t *delta, /* Change made to incore extents */
533 int whichfork, /* data or attr fork */ 540 int whichfork, /* data or attr fork */
534 int rsvd) /* OK to use reserved data blocks */ 541 int rsvd) /* OK to use reserved data blocks */
535{ 542{
@@ -567,6 +574,15 @@ xfs_bmap_add_extent(
567 logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 574 logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
568 } else 575 } else
569 logflags = 0; 576 logflags = 0;
577 /* DELTA: single new extent */
578 if (delta) {
579 if (delta->xed_startoff > new->br_startoff)
580 delta->xed_startoff = new->br_startoff;
581 if (delta->xed_blockcount <
582 new->br_startoff + new->br_blockcount)
583 delta->xed_blockcount = new->br_startoff +
584 new->br_blockcount;
585 }
570 } 586 }
571 /* 587 /*
572 * Any kind of new delayed allocation goes here. 588 * Any kind of new delayed allocation goes here.
@@ -576,7 +592,7 @@ xfs_bmap_add_extent(
576 ASSERT((cur->bc_private.b.flags & 592 ASSERT((cur->bc_private.b.flags &
577 XFS_BTCUR_BPRV_WASDEL) == 0); 593 XFS_BTCUR_BPRV_WASDEL) == 0);
578 if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new, 594 if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new,
579 &logflags, rsvd))) 595 &logflags, delta, rsvd)))
580 goto done; 596 goto done;
581 } 597 }
582 /* 598 /*
@@ -587,7 +603,7 @@ xfs_bmap_add_extent(
587 ASSERT((cur->bc_private.b.flags & 603 ASSERT((cur->bc_private.b.flags &
588 XFS_BTCUR_BPRV_WASDEL) == 0); 604 XFS_BTCUR_BPRV_WASDEL) == 0);
589 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, 605 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
590 &logflags, whichfork))) 606 &logflags, delta, whichfork)))
591 goto done; 607 goto done;
592 } else { 608 } else {
593 xfs_bmbt_irec_t prev; /* old extent at offset idx */ 609 xfs_bmbt_irec_t prev; /* old extent at offset idx */
@@ -612,17 +628,17 @@ xfs_bmap_add_extent(
612 XFS_BTCUR_BPRV_WASDEL); 628 XFS_BTCUR_BPRV_WASDEL);
613 if ((error = xfs_bmap_add_extent_delay_real(ip, 629 if ((error = xfs_bmap_add_extent_delay_real(ip,
614 idx, &cur, new, &da_new, first, flist, 630 idx, &cur, new, &da_new, first, flist,
615 &logflags, rsvd))) 631 &logflags, delta, rsvd)))
616 goto done; 632 goto done;
617 } else if (new->br_state == XFS_EXT_NORM) { 633 } else if (new->br_state == XFS_EXT_NORM) {
618 ASSERT(new->br_state == XFS_EXT_NORM); 634 ASSERT(new->br_state == XFS_EXT_NORM);
619 if ((error = xfs_bmap_add_extent_unwritten_real( 635 if ((error = xfs_bmap_add_extent_unwritten_real(
620 ip, idx, &cur, new, &logflags))) 636 ip, idx, &cur, new, &logflags, delta)))
621 goto done; 637 goto done;
622 } else { 638 } else {
623 ASSERT(new->br_state == XFS_EXT_UNWRITTEN); 639 ASSERT(new->br_state == XFS_EXT_UNWRITTEN);
624 if ((error = xfs_bmap_add_extent_unwritten_real( 640 if ((error = xfs_bmap_add_extent_unwritten_real(
625 ip, idx, &cur, new, &logflags))) 641 ip, idx, &cur, new, &logflags, delta)))
626 goto done; 642 goto done;
627 } 643 }
628 ASSERT(*curp == cur || *curp == NULL); 644 ASSERT(*curp == cur || *curp == NULL);
@@ -635,7 +651,7 @@ xfs_bmap_add_extent(
635 ASSERT((cur->bc_private.b.flags & 651 ASSERT((cur->bc_private.b.flags &
636 XFS_BTCUR_BPRV_WASDEL) == 0); 652 XFS_BTCUR_BPRV_WASDEL) == 0);
637 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, 653 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
638 new, &logflags, whichfork))) 654 new, &logflags, delta, whichfork)))
639 goto done; 655 goto done;
640 } 656 }
641 } 657 }
@@ -700,6 +716,7 @@ xfs_bmap_add_extent_delay_real(
700 xfs_fsblock_t *first, /* pointer to firstblock variable */ 716 xfs_fsblock_t *first, /* pointer to firstblock variable */
701 xfs_bmap_free_t *flist, /* list of extents to be freed */ 717 xfs_bmap_free_t *flist, /* list of extents to be freed */
702 int *logflagsp, /* inode logging flags */ 718 int *logflagsp, /* inode logging flags */
719 xfs_extdelta_t *delta, /* Change made to incore extents */
703 int rsvd) /* OK to use reserved data block allocation */ 720 int rsvd) /* OK to use reserved data block allocation */
704{ 721{
705 xfs_btree_cur_t *cur; /* btree cursor */ 722 xfs_btree_cur_t *cur; /* btree cursor */
@@ -716,8 +733,8 @@ xfs_bmap_add_extent_delay_real(
716 /* left is 0, right is 1, prev is 2 */ 733 /* left is 0, right is 1, prev is 2 */
717 int rval=0; /* return value (logging flags) */ 734 int rval=0; /* return value (logging flags) */
718 int state = 0;/* state bits, accessed thru macros */ 735 int state = 0;/* state bits, accessed thru macros */
719 xfs_filblks_t temp; /* value for dnew calculations */ 736 xfs_filblks_t temp=0; /* value for dnew calculations */
720 xfs_filblks_t temp2; /* value for dnew calculations */ 737 xfs_filblks_t temp2=0;/* value for dnew calculations */
721 int tmp_rval; /* partial logging flags */ 738 int tmp_rval; /* partial logging flags */
722 enum { /* bit number definitions for state */ 739 enum { /* bit number definitions for state */
723 LEFT_CONTIG, RIGHT_CONTIG, 740 LEFT_CONTIG, RIGHT_CONTIG,
@@ -839,6 +856,11 @@ xfs_bmap_add_extent_delay_real(
839 goto done; 856 goto done;
840 } 857 }
841 *dnew = 0; 858 *dnew = 0;
859 /* DELTA: Three in-core extents are replaced by one. */
860 temp = LEFT.br_startoff;
861 temp2 = LEFT.br_blockcount +
862 PREV.br_blockcount +
863 RIGHT.br_blockcount;
842 break; 864 break;
843 865
844 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): 866 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
@@ -872,6 +894,10 @@ xfs_bmap_add_extent_delay_real(
872 goto done; 894 goto done;
873 } 895 }
874 *dnew = 0; 896 *dnew = 0;
897 /* DELTA: Two in-core extents are replaced by one. */
898 temp = LEFT.br_startoff;
899 temp2 = LEFT.br_blockcount +
900 PREV.br_blockcount;
875 break; 901 break;
876 902
877 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): 903 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
@@ -906,6 +932,10 @@ xfs_bmap_add_extent_delay_real(
906 goto done; 932 goto done;
907 } 933 }
908 *dnew = 0; 934 *dnew = 0;
935 /* DELTA: Two in-core extents are replaced by one. */
936 temp = PREV.br_startoff;
937 temp2 = PREV.br_blockcount +
938 RIGHT.br_blockcount;
909 break; 939 break;
910 940
911 case MASK2(LEFT_FILLING, RIGHT_FILLING): 941 case MASK2(LEFT_FILLING, RIGHT_FILLING):
@@ -936,6 +966,9 @@ xfs_bmap_add_extent_delay_real(
936 ASSERT(i == 1); 966 ASSERT(i == 1);
937 } 967 }
938 *dnew = 0; 968 *dnew = 0;
969 /* DELTA: The in-core extent described by new changed type. */
970 temp = new->br_startoff;
971 temp2 = new->br_blockcount;
939 break; 972 break;
940 973
941 case MASK2(LEFT_FILLING, LEFT_CONTIG): 974 case MASK2(LEFT_FILLING, LEFT_CONTIG):
@@ -978,6 +1011,10 @@ xfs_bmap_add_extent_delay_real(
978 xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx, 1011 xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx,
979 XFS_DATA_FORK); 1012 XFS_DATA_FORK);
980 *dnew = temp; 1013 *dnew = temp;
1014 /* DELTA: The boundary between two in-core extents moved. */
1015 temp = LEFT.br_startoff;
1016 temp2 = LEFT.br_blockcount +
1017 PREV.br_blockcount;
981 break; 1018 break;
982 1019
983 case MASK(LEFT_FILLING): 1020 case MASK(LEFT_FILLING):
@@ -1025,6 +1062,9 @@ xfs_bmap_add_extent_delay_real(
1025 xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1, 1062 xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1,
1026 XFS_DATA_FORK); 1063 XFS_DATA_FORK);
1027 *dnew = temp; 1064 *dnew = temp;
1065 /* DELTA: One in-core extent is split in two. */
1066 temp = PREV.br_startoff;
1067 temp2 = PREV.br_blockcount;
1028 break; 1068 break;
1029 1069
1030 case MASK2(RIGHT_FILLING, RIGHT_CONTIG): 1070 case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
@@ -1067,6 +1107,10 @@ xfs_bmap_add_extent_delay_real(
1067 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx, 1107 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx,
1068 XFS_DATA_FORK); 1108 XFS_DATA_FORK);
1069 *dnew = temp; 1109 *dnew = temp;
1110 /* DELTA: The boundary between two in-core extents moved. */
1111 temp = PREV.br_startoff;
1112 temp2 = PREV.br_blockcount +
1113 RIGHT.br_blockcount;
1070 break; 1114 break;
1071 1115
1072 case MASK(RIGHT_FILLING): 1116 case MASK(RIGHT_FILLING):
@@ -1112,6 +1156,9 @@ xfs_bmap_add_extent_delay_real(
1112 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 1156 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
1113 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); 1157 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
1114 *dnew = temp; 1158 *dnew = temp;
1159 /* DELTA: One in-core extent is split in two. */
1160 temp = PREV.br_startoff;
1161 temp2 = PREV.br_blockcount;
1115 break; 1162 break;
1116 1163
1117 case 0: 1164 case 0:
@@ -1194,6 +1241,9 @@ xfs_bmap_add_extent_delay_real(
1194 xfs_bmap_trace_post_update(fname, "0", ip, idx + 2, 1241 xfs_bmap_trace_post_update(fname, "0", ip, idx + 2,
1195 XFS_DATA_FORK); 1242 XFS_DATA_FORK);
1196 *dnew = temp + temp2; 1243 *dnew = temp + temp2;
1244 /* DELTA: One in-core extent is split in three. */
1245 temp = PREV.br_startoff;
1246 temp2 = PREV.br_blockcount;
1197 break; 1247 break;
1198 1248
1199 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 1249 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
@@ -1209,6 +1259,13 @@ xfs_bmap_add_extent_delay_real(
1209 ASSERT(0); 1259 ASSERT(0);
1210 } 1260 }
1211 *curp = cur; 1261 *curp = cur;
1262 if (delta) {
1263 temp2 += temp;
1264 if (delta->xed_startoff > temp)
1265 delta->xed_startoff = temp;
1266 if (delta->xed_blockcount < temp2)
1267 delta->xed_blockcount = temp2;
1268 }
1212done: 1269done:
1213 *logflagsp = rval; 1270 *logflagsp = rval;
1214 return error; 1271 return error;
@@ -1235,7 +1292,8 @@ xfs_bmap_add_extent_unwritten_real(
1235 xfs_extnum_t idx, /* extent number to update/insert */ 1292 xfs_extnum_t idx, /* extent number to update/insert */
1236 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 1293 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
1237 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1294 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1238 int *logflagsp) /* inode logging flags */ 1295 int *logflagsp, /* inode logging flags */
1296 xfs_extdelta_t *delta) /* Change made to incore extents */
1239{ 1297{
1240 xfs_btree_cur_t *cur; /* btree cursor */ 1298 xfs_btree_cur_t *cur; /* btree cursor */
1241 xfs_bmbt_rec_t *ep; /* extent entry for idx */ 1299 xfs_bmbt_rec_t *ep; /* extent entry for idx */
@@ -1252,6 +1310,8 @@ xfs_bmap_add_extent_unwritten_real(
1252 /* left is 0, right is 1, prev is 2 */ 1310 /* left is 0, right is 1, prev is 2 */
1253 int rval=0; /* return value (logging flags) */ 1311 int rval=0; /* return value (logging flags) */
1254 int state = 0;/* state bits, accessed thru macros */ 1312 int state = 0;/* state bits, accessed thru macros */
1313 xfs_filblks_t temp=0;
1314 xfs_filblks_t temp2=0;
1255 enum { /* bit number definitions for state */ 1315 enum { /* bit number definitions for state */
1256 LEFT_CONTIG, RIGHT_CONTIG, 1316 LEFT_CONTIG, RIGHT_CONTIG,
1257 LEFT_FILLING, RIGHT_FILLING, 1317 LEFT_FILLING, RIGHT_FILLING,
@@ -1380,6 +1440,11 @@ xfs_bmap_add_extent_unwritten_real(
1380 RIGHT.br_blockcount, LEFT.br_state))) 1440 RIGHT.br_blockcount, LEFT.br_state)))
1381 goto done; 1441 goto done;
1382 } 1442 }
1443 /* DELTA: Three in-core extents are replaced by one. */
1444 temp = LEFT.br_startoff;
1445 temp2 = LEFT.br_blockcount +
1446 PREV.br_blockcount +
1447 RIGHT.br_blockcount;
1383 break; 1448 break;
1384 1449
1385 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): 1450 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
@@ -1419,6 +1484,10 @@ xfs_bmap_add_extent_unwritten_real(
1419 LEFT.br_state))) 1484 LEFT.br_state)))
1420 goto done; 1485 goto done;
1421 } 1486 }
1487 /* DELTA: Two in-core extents are replaced by one. */
1488 temp = LEFT.br_startoff;
1489 temp2 = LEFT.br_blockcount +
1490 PREV.br_blockcount;
1422 break; 1491 break;
1423 1492
1424 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): 1493 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
@@ -1459,6 +1528,10 @@ xfs_bmap_add_extent_unwritten_real(
1459 newext))) 1528 newext)))
1460 goto done; 1529 goto done;
1461 } 1530 }
1531 /* DELTA: Two in-core extents are replaced by one. */
1532 temp = PREV.br_startoff;
1533 temp2 = PREV.br_blockcount +
1534 RIGHT.br_blockcount;
1462 break; 1535 break;
1463 1536
1464 case MASK2(LEFT_FILLING, RIGHT_FILLING): 1537 case MASK2(LEFT_FILLING, RIGHT_FILLING):
@@ -1487,6 +1560,9 @@ xfs_bmap_add_extent_unwritten_real(
1487 newext))) 1560 newext)))
1488 goto done; 1561 goto done;
1489 } 1562 }
1563 /* DELTA: The in-core extent described by new changed type. */
1564 temp = new->br_startoff;
1565 temp2 = new->br_blockcount;
1490 break; 1566 break;
1491 1567
1492 case MASK2(LEFT_FILLING, LEFT_CONTIG): 1568 case MASK2(LEFT_FILLING, LEFT_CONTIG):
@@ -1534,6 +1610,10 @@ xfs_bmap_add_extent_unwritten_real(
1534 LEFT.br_state)) 1610 LEFT.br_state))
1535 goto done; 1611 goto done;
1536 } 1612 }
1613 /* DELTA: The boundary between two in-core extents moved. */
1614 temp = LEFT.br_startoff;
1615 temp2 = LEFT.br_blockcount +
1616 PREV.br_blockcount;
1537 break; 1617 break;
1538 1618
1539 case MASK(LEFT_FILLING): 1619 case MASK(LEFT_FILLING):
@@ -1574,6 +1654,9 @@ xfs_bmap_add_extent_unwritten_real(
1574 goto done; 1654 goto done;
1575 ASSERT(i == 1); 1655 ASSERT(i == 1);
1576 } 1656 }
1657 /* DELTA: One in-core extent is split in two. */
1658 temp = PREV.br_startoff;
1659 temp2 = PREV.br_blockcount;
1577 break; 1660 break;
1578 1661
1579 case MASK2(RIGHT_FILLING, RIGHT_CONTIG): 1662 case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
@@ -1617,6 +1700,10 @@ xfs_bmap_add_extent_unwritten_real(
1617 newext))) 1700 newext)))
1618 goto done; 1701 goto done;
1619 } 1702 }
1703 /* DELTA: The boundary between two in-core extents moved. */
1704 temp = PREV.br_startoff;
1705 temp2 = PREV.br_blockcount +
1706 RIGHT.br_blockcount;
1620 break; 1707 break;
1621 1708
1622 case MASK(RIGHT_FILLING): 1709 case MASK(RIGHT_FILLING):
@@ -1657,6 +1744,9 @@ xfs_bmap_add_extent_unwritten_real(
1657 goto done; 1744 goto done;
1658 ASSERT(i == 1); 1745 ASSERT(i == 1);
1659 } 1746 }
1747 /* DELTA: One in-core extent is split in two. */
1748 temp = PREV.br_startoff;
1749 temp2 = PREV.br_blockcount;
1660 break; 1750 break;
1661 1751
1662 case 0: 1752 case 0:
@@ -1710,6 +1800,9 @@ xfs_bmap_add_extent_unwritten_real(
1710 goto done; 1800 goto done;
1711 ASSERT(i == 1); 1801 ASSERT(i == 1);
1712 } 1802 }
1803 /* DELTA: One in-core extent is split in three. */
1804 temp = PREV.br_startoff;
1805 temp2 = PREV.br_blockcount;
1713 break; 1806 break;
1714 1807
1715 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 1808 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
@@ -1725,6 +1818,13 @@ xfs_bmap_add_extent_unwritten_real(
1725 ASSERT(0); 1818 ASSERT(0);
1726 } 1819 }
1727 *curp = cur; 1820 *curp = cur;
1821 if (delta) {
1822 temp2 += temp;
1823 if (delta->xed_startoff > temp)
1824 delta->xed_startoff = temp;
1825 if (delta->xed_blockcount < temp2)
1826 delta->xed_blockcount = temp2;
1827 }
1728done: 1828done:
1729 *logflagsp = rval; 1829 *logflagsp = rval;
1730 return error; 1830 return error;
@@ -1753,6 +1853,7 @@ xfs_bmap_add_extent_hole_delay(
1753 xfs_btree_cur_t *cur, /* if null, not a btree */ 1853 xfs_btree_cur_t *cur, /* if null, not a btree */
1754 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1854 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1755 int *logflagsp, /* inode logging flags */ 1855 int *logflagsp, /* inode logging flags */
1856 xfs_extdelta_t *delta, /* Change made to incore extents */
1756 int rsvd) /* OK to allocate reserved blocks */ 1857 int rsvd) /* OK to allocate reserved blocks */
1757{ 1858{
1758 xfs_bmbt_rec_t *ep; /* extent record for idx */ 1859 xfs_bmbt_rec_t *ep; /* extent record for idx */
@@ -1765,7 +1866,8 @@ xfs_bmap_add_extent_hole_delay(
1765 xfs_filblks_t oldlen=0; /* old indirect size */ 1866 xfs_filblks_t oldlen=0; /* old indirect size */
1766 xfs_bmbt_irec_t right; /* right neighbor extent entry */ 1867 xfs_bmbt_irec_t right; /* right neighbor extent entry */
1767 int state; /* state bits, accessed thru macros */ 1868 int state; /* state bits, accessed thru macros */
1768 xfs_filblks_t temp; /* temp for indirect calculations */ 1869 xfs_filblks_t temp=0; /* temp for indirect calculations */
1870 xfs_filblks_t temp2=0;
1769 enum { /* bit number definitions for state */ 1871 enum { /* bit number definitions for state */
1770 LEFT_CONTIG, RIGHT_CONTIG, 1872 LEFT_CONTIG, RIGHT_CONTIG,
1771 LEFT_DELAY, RIGHT_DELAY, 1873 LEFT_DELAY, RIGHT_DELAY,
@@ -1844,6 +1946,9 @@ xfs_bmap_add_extent_hole_delay(
1844 XFS_DATA_FORK); 1946 XFS_DATA_FORK);
1845 xfs_iext_remove(ifp, idx, 1); 1947 xfs_iext_remove(ifp, idx, 1);
1846 ip->i_df.if_lastex = idx - 1; 1948 ip->i_df.if_lastex = idx - 1;
1949 /* DELTA: Two in-core extents were replaced by one. */
1950 temp2 = temp;
1951 temp = left.br_startoff;
1847 break; 1952 break;
1848 1953
1849 case MASK(LEFT_CONTIG): 1954 case MASK(LEFT_CONTIG):
@@ -1864,6 +1969,9 @@ xfs_bmap_add_extent_hole_delay(
1864 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, 1969 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1,
1865 XFS_DATA_FORK); 1970 XFS_DATA_FORK);
1866 ip->i_df.if_lastex = idx - 1; 1971 ip->i_df.if_lastex = idx - 1;
1972 /* DELTA: One in-core extent grew into a hole. */
1973 temp2 = temp;
1974 temp = left.br_startoff;
1867 break; 1975 break;
1868 1976
1869 case MASK(RIGHT_CONTIG): 1977 case MASK(RIGHT_CONTIG):
@@ -1881,6 +1989,9 @@ xfs_bmap_add_extent_hole_delay(
1881 NULLSTARTBLOCK((int)newlen), temp, right.br_state); 1989 NULLSTARTBLOCK((int)newlen), temp, right.br_state);
1882 xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK); 1990 xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK);
1883 ip->i_df.if_lastex = idx; 1991 ip->i_df.if_lastex = idx;
1992 /* DELTA: One in-core extent grew into a hole. */
1993 temp2 = temp;
1994 temp = new->br_startoff;
1884 break; 1995 break;
1885 1996
1886 case 0: 1997 case 0:
@@ -1894,6 +2005,9 @@ xfs_bmap_add_extent_hole_delay(
1894 XFS_DATA_FORK); 2005 XFS_DATA_FORK);
1895 xfs_iext_insert(ifp, idx, 1, new); 2006 xfs_iext_insert(ifp, idx, 1, new);
1896 ip->i_df.if_lastex = idx; 2007 ip->i_df.if_lastex = idx;
2008 /* DELTA: A new in-core extent was added in a hole. */
2009 temp2 = new->br_blockcount;
2010 temp = new->br_startoff;
1897 break; 2011 break;
1898 } 2012 }
1899 if (oldlen != newlen) { 2013 if (oldlen != newlen) {
@@ -1904,6 +2018,13 @@ xfs_bmap_add_extent_hole_delay(
1904 * Nothing to do for disk quota accounting here. 2018 * Nothing to do for disk quota accounting here.
1905 */ 2019 */
1906 } 2020 }
2021 if (delta) {
2022 temp2 += temp;
2023 if (delta->xed_startoff > temp)
2024 delta->xed_startoff = temp;
2025 if (delta->xed_blockcount < temp2)
2026 delta->xed_blockcount = temp2;
2027 }
1907 *logflagsp = 0; 2028 *logflagsp = 0;
1908 return 0; 2029 return 0;
1909#undef MASK 2030#undef MASK
@@ -1925,6 +2046,7 @@ xfs_bmap_add_extent_hole_real(
1925 xfs_btree_cur_t *cur, /* if null, not a btree */ 2046 xfs_btree_cur_t *cur, /* if null, not a btree */
1926 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 2047 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1927 int *logflagsp, /* inode logging flags */ 2048 int *logflagsp, /* inode logging flags */
2049 xfs_extdelta_t *delta, /* Change made to incore extents */
1928 int whichfork) /* data or attr fork */ 2050 int whichfork) /* data or attr fork */
1929{ 2051{
1930 xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */ 2052 xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */
@@ -1936,7 +2058,10 @@ xfs_bmap_add_extent_hole_real(
1936 xfs_ifork_t *ifp; /* inode fork pointer */ 2058 xfs_ifork_t *ifp; /* inode fork pointer */
1937 xfs_bmbt_irec_t left; /* left neighbor extent entry */ 2059 xfs_bmbt_irec_t left; /* left neighbor extent entry */
1938 xfs_bmbt_irec_t right; /* right neighbor extent entry */ 2060 xfs_bmbt_irec_t right; /* right neighbor extent entry */
2061 int rval=0; /* return value (logging flags) */
1939 int state; /* state bits, accessed thru macros */ 2062 int state; /* state bits, accessed thru macros */
2063 xfs_filblks_t temp=0;
2064 xfs_filblks_t temp2=0;
1940 enum { /* bit number definitions for state */ 2065 enum { /* bit number definitions for state */
1941 LEFT_CONTIG, RIGHT_CONTIG, 2066 LEFT_CONTIG, RIGHT_CONTIG,
1942 LEFT_DELAY, RIGHT_DELAY, 2067 LEFT_DELAY, RIGHT_DELAY,
@@ -1993,6 +2118,7 @@ xfs_bmap_add_extent_hole_real(
1993 left.br_blockcount + new->br_blockcount + 2118 left.br_blockcount + new->br_blockcount +
1994 right.br_blockcount <= MAXEXTLEN)); 2119 right.br_blockcount <= MAXEXTLEN));
1995 2120
2121 error = 0;
1996 /* 2122 /*
1997 * Select which case we're in here, and implement it. 2123 * Select which case we're in here, and implement it.
1998 */ 2124 */
@@ -2018,25 +2144,35 @@ xfs_bmap_add_extent_hole_real(
2018 XFS_IFORK_NEXT_SET(ip, whichfork, 2144 XFS_IFORK_NEXT_SET(ip, whichfork,
2019 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 2145 XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
2020 if (cur == NULL) { 2146 if (cur == NULL) {
2021 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 2147 rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
2022 return 0; 2148 } else {
2149 rval = XFS_ILOG_CORE;
2150 if ((error = xfs_bmbt_lookup_eq(cur,
2151 right.br_startoff,
2152 right.br_startblock,
2153 right.br_blockcount, &i)))
2154 goto done;
2155 ASSERT(i == 1);
2156 if ((error = xfs_bmbt_delete(cur, &i)))
2157 goto done;
2158 ASSERT(i == 1);
2159 if ((error = xfs_bmbt_decrement(cur, 0, &i)))
2160 goto done;
2161 ASSERT(i == 1);
2162 if ((error = xfs_bmbt_update(cur, left.br_startoff,
2163 left.br_startblock,
2164 left.br_blockcount +
2165 new->br_blockcount +
2166 right.br_blockcount,
2167 left.br_state)))
2168 goto done;
2023 } 2169 }
2024 *logflagsp = XFS_ILOG_CORE; 2170 /* DELTA: Two in-core extents were replaced by one. */
2025 if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, 2171 temp = left.br_startoff;
2026 right.br_startblock, right.br_blockcount, &i))) 2172 temp2 = left.br_blockcount +
2027 return error; 2173 new->br_blockcount +
2028 ASSERT(i == 1); 2174 right.br_blockcount;
2029 if ((error = xfs_bmbt_delete(cur, &i))) 2175 break;
2030 return error;
2031 ASSERT(i == 1);
2032 if ((error = xfs_bmbt_decrement(cur, 0, &i)))
2033 return error;
2034 ASSERT(i == 1);
2035 error = xfs_bmbt_update(cur, left.br_startoff,
2036 left.br_startblock,
2037 left.br_blockcount + new->br_blockcount +
2038 right.br_blockcount, left.br_state);
2039 return error;
2040 2176
2041 case MASK(LEFT_CONTIG): 2177 case MASK(LEFT_CONTIG):
2042 /* 2178 /*
@@ -2050,19 +2186,27 @@ xfs_bmap_add_extent_hole_real(
2050 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork); 2186 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork);
2051 ifp->if_lastex = idx - 1; 2187 ifp->if_lastex = idx - 1;
2052 if (cur == NULL) { 2188 if (cur == NULL) {
2053 *logflagsp = XFS_ILOG_FEXT(whichfork); 2189 rval = XFS_ILOG_FEXT(whichfork);
2054 return 0; 2190 } else {
2191 rval = 0;
2192 if ((error = xfs_bmbt_lookup_eq(cur,
2193 left.br_startoff,
2194 left.br_startblock,
2195 left.br_blockcount, &i)))
2196 goto done;
2197 ASSERT(i == 1);
2198 if ((error = xfs_bmbt_update(cur, left.br_startoff,
2199 left.br_startblock,
2200 left.br_blockcount +
2201 new->br_blockcount,
2202 left.br_state)))
2203 goto done;
2055 } 2204 }
2056 *logflagsp = 0; 2205 /* DELTA: One in-core extent grew. */
2057 if ((error = xfs_bmbt_lookup_eq(cur, left.br_startoff, 2206 temp = left.br_startoff;
2058 left.br_startblock, left.br_blockcount, &i))) 2207 temp2 = left.br_blockcount +
2059 return error; 2208 new->br_blockcount;
2060 ASSERT(i == 1); 2209 break;
2061 error = xfs_bmbt_update(cur, left.br_startoff,
2062 left.br_startblock,
2063 left.br_blockcount + new->br_blockcount,
2064 left.br_state);
2065 return error;
2066 2210
2067 case MASK(RIGHT_CONTIG): 2211 case MASK(RIGHT_CONTIG):
2068 /* 2212 /*
@@ -2077,19 +2221,27 @@ xfs_bmap_add_extent_hole_real(
2077 xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork); 2221 xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork);
2078 ifp->if_lastex = idx; 2222 ifp->if_lastex = idx;
2079 if (cur == NULL) { 2223 if (cur == NULL) {
2080 *logflagsp = XFS_ILOG_FEXT(whichfork); 2224 rval = XFS_ILOG_FEXT(whichfork);
2081 return 0; 2225 } else {
2226 rval = 0;
2227 if ((error = xfs_bmbt_lookup_eq(cur,
2228 right.br_startoff,
2229 right.br_startblock,
2230 right.br_blockcount, &i)))
2231 goto done;
2232 ASSERT(i == 1);
2233 if ((error = xfs_bmbt_update(cur, new->br_startoff,
2234 new->br_startblock,
2235 new->br_blockcount +
2236 right.br_blockcount,
2237 right.br_state)))
2238 goto done;
2082 } 2239 }
2083 *logflagsp = 0; 2240 /* DELTA: One in-core extent grew. */
2084 if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, 2241 temp = new->br_startoff;
2085 right.br_startblock, right.br_blockcount, &i))) 2242 temp2 = new->br_blockcount +
2086 return error; 2243 right.br_blockcount;
2087 ASSERT(i == 1); 2244 break;
2088 error = xfs_bmbt_update(cur, new->br_startoff,
2089 new->br_startblock,
2090 new->br_blockcount + right.br_blockcount,
2091 right.br_state);
2092 return error;
2093 2245
2094 case 0: 2246 case 0:
2095 /* 2247 /*
@@ -2104,29 +2256,41 @@ xfs_bmap_add_extent_hole_real(
2104 XFS_IFORK_NEXT_SET(ip, whichfork, 2256 XFS_IFORK_NEXT_SET(ip, whichfork,
2105 XFS_IFORK_NEXTENTS(ip, whichfork) + 1); 2257 XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
2106 if (cur == NULL) { 2258 if (cur == NULL) {
2107 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 2259 rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
2108 return 0; 2260 } else {
2261 rval = XFS_ILOG_CORE;
2262 if ((error = xfs_bmbt_lookup_eq(cur,
2263 new->br_startoff,
2264 new->br_startblock,
2265 new->br_blockcount, &i)))
2266 goto done;
2267 ASSERT(i == 0);
2268 cur->bc_rec.b.br_state = new->br_state;
2269 if ((error = xfs_bmbt_insert(cur, &i)))
2270 goto done;
2271 ASSERT(i == 1);
2109 } 2272 }
2110 *logflagsp = XFS_ILOG_CORE; 2273 /* DELTA: A new extent was added in a hole. */
2111 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 2274 temp = new->br_startoff;
2112 new->br_startblock, new->br_blockcount, &i))) 2275 temp2 = new->br_blockcount;
2113 return error; 2276 break;
2114 ASSERT(i == 0); 2277 }
2115 cur->bc_rec.b.br_state = new->br_state; 2278 if (delta) {
2116 if ((error = xfs_bmbt_insert(cur, &i))) 2279 temp2 += temp;
2117 return error; 2280 if (delta->xed_startoff > temp)
2118 ASSERT(i == 1); 2281 delta->xed_startoff = temp;
2119 return 0; 2282 if (delta->xed_blockcount < temp2)
2283 delta->xed_blockcount = temp2;
2120 } 2284 }
2285done:
2286 *logflagsp = rval;
2287 return error;
2121#undef MASK 2288#undef MASK
2122#undef MASK2 2289#undef MASK2
2123#undef STATE_SET 2290#undef STATE_SET
2124#undef STATE_TEST 2291#undef STATE_TEST
2125#undef STATE_SET_TEST 2292#undef STATE_SET_TEST
2126#undef SWITCH_STATE 2293#undef SWITCH_STATE
2127 /* NOTREACHED */
2128 ASSERT(0);
2129 return 0; /* keep gcc quite */
2130} 2294}
2131 2295
2132/* 2296/*
@@ -2598,6 +2762,7 @@ xfs_bmap_btalloc(
2598 args.mp = mp; 2762 args.mp = mp;
2599 args.fsbno = ap->rval; 2763 args.fsbno = ap->rval;
2600 args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); 2764 args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
2765 args.firstblock = ap->firstblock;
2601 blen = 0; 2766 blen = 0;
2602 if (nullfb) { 2767 if (nullfb) {
2603 args.type = XFS_ALLOCTYPE_START_BNO; 2768 args.type = XFS_ALLOCTYPE_START_BNO;
@@ -2657,7 +2822,7 @@ xfs_bmap_btalloc(
2657 else 2822 else
2658 args.minlen = ap->alen; 2823 args.minlen = ap->alen;
2659 } else if (ap->low) { 2824 } else if (ap->low) {
2660 args.type = XFS_ALLOCTYPE_FIRST_AG; 2825 args.type = XFS_ALLOCTYPE_START_BNO;
2661 args.total = args.minlen = ap->minlen; 2826 args.total = args.minlen = ap->minlen;
2662 } else { 2827 } else {
2663 args.type = XFS_ALLOCTYPE_NEAR_BNO; 2828 args.type = XFS_ALLOCTYPE_NEAR_BNO;
@@ -2669,7 +2834,7 @@ xfs_bmap_btalloc(
2669 args.prod = ap->ip->i_d.di_extsize; 2834 args.prod = ap->ip->i_d.di_extsize;
2670 if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) 2835 if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod)))
2671 args.mod = (xfs_extlen_t)(args.prod - args.mod); 2836 args.mod = (xfs_extlen_t)(args.prod - args.mod);
2672 } else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) { 2837 } else if (mp->m_sb.sb_blocksize >= NBPP) {
2673 args.prod = 1; 2838 args.prod = 1;
2674 args.mod = 0; 2839 args.mod = 0;
2675 } else { 2840 } else {
@@ -2885,6 +3050,7 @@ xfs_bmap_del_extent(
2885 xfs_btree_cur_t *cur, /* if null, not a btree */ 3050 xfs_btree_cur_t *cur, /* if null, not a btree */
2886 xfs_bmbt_irec_t *del, /* data to remove from extents */ 3051 xfs_bmbt_irec_t *del, /* data to remove from extents */
2887 int *logflagsp, /* inode logging flags */ 3052 int *logflagsp, /* inode logging flags */
3053 xfs_extdelta_t *delta, /* Change made to incore extents */
2888 int whichfork, /* data or attr fork */ 3054 int whichfork, /* data or attr fork */
2889 int rsvd) /* OK to allocate reserved blocks */ 3055 int rsvd) /* OK to allocate reserved blocks */
2890{ 3056{
@@ -3193,6 +3359,14 @@ xfs_bmap_del_extent(
3193 if (da_old > da_new) 3359 if (da_old > da_new)
3194 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new), 3360 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new),
3195 rsvd); 3361 rsvd);
3362 if (delta) {
3363 /* DELTA: report the original extent. */
3364 if (delta->xed_startoff > got.br_startoff)
3365 delta->xed_startoff = got.br_startoff;
3366 if (delta->xed_blockcount < got.br_startoff+got.br_blockcount)
3367 delta->xed_blockcount = got.br_startoff +
3368 got.br_blockcount;
3369 }
3196done: 3370done:
3197 *logflagsp = flags; 3371 *logflagsp = flags;
3198 return error; 3372 return error;
@@ -3279,6 +3453,7 @@ xfs_bmap_extents_to_btree(
3279 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); 3453 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
3280 args.tp = tp; 3454 args.tp = tp;
3281 args.mp = mp; 3455 args.mp = mp;
3456 args.firstblock = *firstblock;
3282 if (*firstblock == NULLFSBLOCK) { 3457 if (*firstblock == NULLFSBLOCK) {
3283 args.type = XFS_ALLOCTYPE_START_BNO; 3458 args.type = XFS_ALLOCTYPE_START_BNO;
3284 args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); 3459 args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino);
@@ -3414,6 +3589,7 @@ xfs_bmap_local_to_extents(
3414 3589
3415 args.tp = tp; 3590 args.tp = tp;
3416 args.mp = ip->i_mount; 3591 args.mp = ip->i_mount;
3592 args.firstblock = *firstblock;
3417 ASSERT((ifp->if_flags & 3593 ASSERT((ifp->if_flags &
3418 (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE); 3594 (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
3419 /* 3595 /*
@@ -3753,7 +3929,7 @@ xfs_bunmap_trace(
3753 if (ip->i_rwtrace == NULL) 3929 if (ip->i_rwtrace == NULL)
3754 return; 3930 return;
3755 ktrace_enter(ip->i_rwtrace, 3931 ktrace_enter(ip->i_rwtrace,
3756 (void *)(__psint_t)XFS_BUNMAPI, 3932 (void *)(__psint_t)XFS_BUNMAP,
3757 (void *)ip, 3933 (void *)ip,
3758 (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff), 3934 (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff),
3759 (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff), 3935 (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff),
@@ -4087,8 +4263,8 @@ xfs_bmap_finish(
4087 if (!XFS_FORCED_SHUTDOWN(mp)) 4263 if (!XFS_FORCED_SHUTDOWN(mp))
4088 xfs_force_shutdown(mp, 4264 xfs_force_shutdown(mp,
4089 (error == EFSCORRUPTED) ? 4265 (error == EFSCORRUPTED) ?
4090 XFS_CORRUPT_INCORE : 4266 SHUTDOWN_CORRUPT_INCORE :
4091 XFS_METADATA_IO_ERROR); 4267 SHUTDOWN_META_IO_ERROR);
4092 return error; 4268 return error;
4093 } 4269 }
4094 xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock, 4270 xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock,
@@ -4538,7 +4714,8 @@ xfs_bmapi(
4538 xfs_extlen_t total, /* total blocks needed */ 4714 xfs_extlen_t total, /* total blocks needed */
4539 xfs_bmbt_irec_t *mval, /* output: map values */ 4715 xfs_bmbt_irec_t *mval, /* output: map values */
4540 int *nmap, /* i/o: mval size/count */ 4716 int *nmap, /* i/o: mval size/count */
4541 xfs_bmap_free_t *flist) /* i/o: list extents to free */ 4717 xfs_bmap_free_t *flist, /* i/o: list extents to free */
4718 xfs_extdelta_t *delta) /* o: change made to incore extents */
4542{ 4719{
4543 xfs_fsblock_t abno; /* allocated block number */ 4720 xfs_fsblock_t abno; /* allocated block number */
4544 xfs_extlen_t alen; /* allocated extent length */ 4721 xfs_extlen_t alen; /* allocated extent length */
@@ -4650,6 +4827,10 @@ xfs_bmapi(
4650 end = bno + len; 4827 end = bno + len;
4651 obno = bno; 4828 obno = bno;
4652 bma.ip = NULL; 4829 bma.ip = NULL;
4830 if (delta) {
4831 delta->xed_startoff = NULLFILEOFF;
4832 delta->xed_blockcount = 0;
4833 }
4653 while (bno < end && n < *nmap) { 4834 while (bno < end && n < *nmap) {
4654 /* 4835 /*
4655 * Reading past eof, act as though there's a hole 4836 * Reading past eof, act as though there's a hole
@@ -4886,8 +5067,8 @@ xfs_bmapi(
4886 got.br_state = XFS_EXT_UNWRITTEN; 5067 got.br_state = XFS_EXT_UNWRITTEN;
4887 } 5068 }
4888 error = xfs_bmap_add_extent(ip, lastx, &cur, &got, 5069 error = xfs_bmap_add_extent(ip, lastx, &cur, &got,
4889 firstblock, flist, &tmp_logflags, whichfork, 5070 firstblock, flist, &tmp_logflags, delta,
4890 (flags & XFS_BMAPI_RSVBLOCKS)); 5071 whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
4891 logflags |= tmp_logflags; 5072 logflags |= tmp_logflags;
4892 if (error) 5073 if (error)
4893 goto error0; 5074 goto error0;
@@ -4983,8 +5164,8 @@ xfs_bmapi(
4983 } 5164 }
4984 mval->br_state = XFS_EXT_NORM; 5165 mval->br_state = XFS_EXT_NORM;
4985 error = xfs_bmap_add_extent(ip, lastx, &cur, mval, 5166 error = xfs_bmap_add_extent(ip, lastx, &cur, mval,
4986 firstblock, flist, &tmp_logflags, whichfork, 5167 firstblock, flist, &tmp_logflags, delta,
4987 (flags & XFS_BMAPI_RSVBLOCKS)); 5168 whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
4988 logflags |= tmp_logflags; 5169 logflags |= tmp_logflags;
4989 if (error) 5170 if (error)
4990 goto error0; 5171 goto error0;
@@ -5073,7 +5254,14 @@ xfs_bmapi(
5073 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || 5254 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
5074 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max); 5255 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max);
5075 error = 0; 5256 error = 0;
5076 5257 if (delta && delta->xed_startoff != NULLFILEOFF) {
5258 /* A change was actually made.
5259 * Note that delta->xed_blockount is an offset at this
5260 * point and needs to be converted to a block count.
5261 */
5262 ASSERT(delta->xed_blockcount > delta->xed_startoff);
5263 delta->xed_blockcount -= delta->xed_startoff;
5264 }
5077error0: 5265error0:
5078 /* 5266 /*
5079 * Log everything. Do this after conversion, there's no point in 5267 * Log everything. Do this after conversion, there's no point in
@@ -5185,6 +5373,8 @@ xfs_bunmapi(
5185 xfs_fsblock_t *firstblock, /* first allocated block 5373 xfs_fsblock_t *firstblock, /* first allocated block
5186 controls a.g. for allocs */ 5374 controls a.g. for allocs */
5187 xfs_bmap_free_t *flist, /* i/o: list extents to free */ 5375 xfs_bmap_free_t *flist, /* i/o: list extents to free */
5376 xfs_extdelta_t *delta, /* o: change made to incore
5377 extents */
5188 int *done) /* set if not done yet */ 5378 int *done) /* set if not done yet */
5189{ 5379{
5190 xfs_btree_cur_t *cur; /* bmap btree cursor */ 5380 xfs_btree_cur_t *cur; /* bmap btree cursor */
@@ -5242,6 +5432,10 @@ xfs_bunmapi(
5242 bno = start + len - 1; 5432 bno = start + len - 1;
5243 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, 5433 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
5244 &prev); 5434 &prev);
5435 if (delta) {
5436 delta->xed_startoff = NULLFILEOFF;
5437 delta->xed_blockcount = 0;
5438 }
5245 /* 5439 /*
5246 * Check to see if the given block number is past the end of the 5440 * Check to see if the given block number is past the end of the
5247 * file, back up to the last block if so... 5441 * file, back up to the last block if so...
@@ -5340,7 +5534,8 @@ xfs_bunmapi(
5340 } 5534 }
5341 del.br_state = XFS_EXT_UNWRITTEN; 5535 del.br_state = XFS_EXT_UNWRITTEN;
5342 error = xfs_bmap_add_extent(ip, lastx, &cur, &del, 5536 error = xfs_bmap_add_extent(ip, lastx, &cur, &del,
5343 firstblock, flist, &logflags, XFS_DATA_FORK, 0); 5537 firstblock, flist, &logflags, delta,
5538 XFS_DATA_FORK, 0);
5344 if (error) 5539 if (error)
5345 goto error0; 5540 goto error0;
5346 goto nodelete; 5541 goto nodelete;
@@ -5394,7 +5589,7 @@ xfs_bunmapi(
5394 prev.br_state = XFS_EXT_UNWRITTEN; 5589 prev.br_state = XFS_EXT_UNWRITTEN;
5395 error = xfs_bmap_add_extent(ip, lastx - 1, &cur, 5590 error = xfs_bmap_add_extent(ip, lastx - 1, &cur,
5396 &prev, firstblock, flist, &logflags, 5591 &prev, firstblock, flist, &logflags,
5397 XFS_DATA_FORK, 0); 5592 delta, XFS_DATA_FORK, 0);
5398 if (error) 5593 if (error)
5399 goto error0; 5594 goto error0;
5400 goto nodelete; 5595 goto nodelete;
@@ -5403,7 +5598,7 @@ xfs_bunmapi(
5403 del.br_state = XFS_EXT_UNWRITTEN; 5598 del.br_state = XFS_EXT_UNWRITTEN;
5404 error = xfs_bmap_add_extent(ip, lastx, &cur, 5599 error = xfs_bmap_add_extent(ip, lastx, &cur,
5405 &del, firstblock, flist, &logflags, 5600 &del, firstblock, flist, &logflags,
5406 XFS_DATA_FORK, 0); 5601 delta, XFS_DATA_FORK, 0);
5407 if (error) 5602 if (error)
5408 goto error0; 5603 goto error0;
5409 goto nodelete; 5604 goto nodelete;
@@ -5456,7 +5651,7 @@ xfs_bunmapi(
5456 goto error0; 5651 goto error0;
5457 } 5652 }
5458 error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, 5653 error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del,
5459 &tmp_logflags, whichfork, rsvd); 5654 &tmp_logflags, delta, whichfork, rsvd);
5460 logflags |= tmp_logflags; 5655 logflags |= tmp_logflags;
5461 if (error) 5656 if (error)
5462 goto error0; 5657 goto error0;
@@ -5513,6 +5708,14 @@ nodelete:
5513 ASSERT(ifp->if_ext_max == 5708 ASSERT(ifp->if_ext_max ==
5514 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 5709 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
5515 error = 0; 5710 error = 0;
5711 if (delta && delta->xed_startoff != NULLFILEOFF) {
5712 /* A change was actually made.
5713 * Note that delta->xed_blockount is an offset at this
5714 * point and needs to be converted to a block count.
5715 */
5716 ASSERT(delta->xed_blockcount > delta->xed_startoff);
5717 delta->xed_blockcount -= delta->xed_startoff;
5718 }
5516error0: 5719error0:
5517 /* 5720 /*
5518 * Log everything. Do this after conversion, there's no point in 5721 * Log everything. Do this after conversion, there's no point in
@@ -5556,7 +5759,7 @@ xfs_getbmap(
5556 __int64_t fixlen; /* length for -1 case */ 5759 __int64_t fixlen; /* length for -1 case */
5557 int i; /* extent number */ 5760 int i; /* extent number */
5558 xfs_inode_t *ip; /* xfs incore inode pointer */ 5761 xfs_inode_t *ip; /* xfs incore inode pointer */
5559 vnode_t *vp; /* corresponding vnode */ 5762 bhv_vnode_t *vp; /* corresponding vnode */
5560 int lock; /* lock state */ 5763 int lock; /* lock state */
5561 xfs_bmbt_irec_t *map; /* buffer for user's data */ 5764 xfs_bmbt_irec_t *map; /* buffer for user's data */
5562 xfs_mount_t *mp; /* file system mount point */ 5765 xfs_mount_t *mp; /* file system mount point */
@@ -5653,7 +5856,7 @@ xfs_getbmap(
5653 5856
5654 if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) { 5857 if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) {
5655 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ 5858 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
5656 VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error); 5859 error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
5657 } 5860 }
5658 5861
5659 ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0); 5862 ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0);
@@ -5689,7 +5892,8 @@ xfs_getbmap(
5689 nmap = (nexleft > subnex) ? subnex : nexleft; 5892 nmap = (nexleft > subnex) ? subnex : nexleft;
5690 error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset), 5893 error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
5691 XFS_BB_TO_FSB(mp, bmv->bmv_length), 5894 XFS_BB_TO_FSB(mp, bmv->bmv_length),
5692 bmapi_flags, NULL, 0, map, &nmap, NULL); 5895 bmapi_flags, NULL, 0, map, &nmap,
5896 NULL, NULL);
5693 if (error) 5897 if (error)
5694 goto unlock_and_return; 5898 goto unlock_and_return;
5695 ASSERT(nmap <= subnex); 5899 ASSERT(nmap <= subnex);
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 8e0d73d9ccc4..80e93409b78d 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -26,6 +26,20 @@ struct xfs_mount;
26struct xfs_trans; 26struct xfs_trans;
27 27
28/* 28/*
29 * DELTA: describe a change to the in-core extent list.
30 *
31 * Internally the use of xed_blockount is somewhat funky.
32 * xed_blockcount contains an offset much of the time because this
33 * makes merging changes easier. (xfs_fileoff_t and xfs_filblks_t are
34 * the same underlying type).
35 */
36typedef struct xfs_extdelta
37{
38 xfs_fileoff_t xed_startoff; /* offset of range */
39 xfs_filblks_t xed_blockcount; /* blocks in range */
40} xfs_extdelta_t;
41
42/*
29 * List of extents to be free "later". 43 * List of extents to be free "later".
30 * The list is kept sorted on xbf_startblock. 44 * The list is kept sorted on xbf_startblock.
31 */ 45 */
@@ -275,7 +289,9 @@ xfs_bmapi(
275 xfs_extlen_t total, /* total blocks needed */ 289 xfs_extlen_t total, /* total blocks needed */
276 struct xfs_bmbt_irec *mval, /* output: map values */ 290 struct xfs_bmbt_irec *mval, /* output: map values */
277 int *nmap, /* i/o: mval size/count */ 291 int *nmap, /* i/o: mval size/count */
278 xfs_bmap_free_t *flist); /* i/o: list extents to free */ 292 xfs_bmap_free_t *flist, /* i/o: list extents to free */
293 xfs_extdelta_t *delta); /* o: change made to incore
294 extents */
279 295
280/* 296/*
281 * Map file blocks to filesystem blocks, simple version. 297 * Map file blocks to filesystem blocks, simple version.
@@ -309,6 +325,8 @@ xfs_bunmapi(
309 xfs_fsblock_t *firstblock, /* first allocated block 325 xfs_fsblock_t *firstblock, /* first allocated block
310 controls a.g. for allocs */ 326 controls a.g. for allocs */
311 xfs_bmap_free_t *flist, /* i/o: list extents to free */ 327 xfs_bmap_free_t *flist, /* i/o: list extents to free */
328 xfs_extdelta_t *delta, /* o: change made to incore
329 extents */
312 int *done); /* set if not done yet */ 330 int *done); /* set if not done yet */
313 331
314/* 332/*
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index bea44709afbe..18fb7385d719 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -1569,12 +1567,11 @@ xfs_bmbt_split(
1569 lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp)); 1567 lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp));
1570 left = XFS_BUF_TO_BMBT_BLOCK(lbp); 1568 left = XFS_BUF_TO_BMBT_BLOCK(lbp);
1571 args.fsbno = cur->bc_private.b.firstblock; 1569 args.fsbno = cur->bc_private.b.firstblock;
1570 args.firstblock = args.fsbno;
1572 if (args.fsbno == NULLFSBLOCK) { 1571 if (args.fsbno == NULLFSBLOCK) {
1573 args.fsbno = lbno; 1572 args.fsbno = lbno;
1574 args.type = XFS_ALLOCTYPE_START_BNO; 1573 args.type = XFS_ALLOCTYPE_START_BNO;
1575 } else if (cur->bc_private.b.flist->xbf_low) 1574 } else
1576 args.type = XFS_ALLOCTYPE_FIRST_AG;
1577 else
1578 args.type = XFS_ALLOCTYPE_NEAR_BNO; 1575 args.type = XFS_ALLOCTYPE_NEAR_BNO;
1579 args.mod = args.minleft = args.alignment = args.total = args.isfl = 1576 args.mod = args.minleft = args.alignment = args.total = args.isfl =
1580 args.userdata = args.minalignslop = 0; 1577 args.userdata = args.minalignslop = 0;
@@ -2356,6 +2353,7 @@ xfs_bmbt_newroot(
2356 args.userdata = args.minalignslop = 0; 2353 args.userdata = args.minalignslop = 0;
2357 args.minlen = args.maxlen = args.prod = 1; 2354 args.minlen = args.maxlen = args.prod = 1;
2358 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; 2355 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
2356 args.firstblock = args.fsbno;
2359 if (args.fsbno == NULLFSBLOCK) { 2357 if (args.fsbno == NULLFSBLOCK) {
2360#ifdef DEBUG 2358#ifdef DEBUG
2361 if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) { 2359 if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) {
@@ -2365,9 +2363,7 @@ xfs_bmbt_newroot(
2365#endif 2363#endif
2366 args.fsbno = INT_GET(*pp, ARCH_CONVERT); 2364 args.fsbno = INT_GET(*pp, ARCH_CONVERT);
2367 args.type = XFS_ALLOCTYPE_START_BNO; 2365 args.type = XFS_ALLOCTYPE_START_BNO;
2368 } else if (args.wasdel) 2366 } else
2369 args.type = XFS_ALLOCTYPE_FIRST_AG;
2370 else
2371 args.type = XFS_ALLOCTYPE_NEAR_BNO; 2367 args.type = XFS_ALLOCTYPE_NEAR_BNO;
2372 if ((error = xfs_alloc_vextent(&args))) { 2368 if ((error = xfs_alloc_vextent(&args))) {
2373 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 2369 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index 52d5d095fc35..ee2255bd6562 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 5fed15682dda..a4aa53974f76 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -23,7 +23,6 @@
23#include "xfs_inum.h" 23#include "xfs_inum.h"
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_dir.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_buf_item.h" 28#include "xfs_buf_item.h"
@@ -1030,9 +1029,9 @@ xfs_buf_iodone_callbacks(
1030 if ((XFS_BUF_TARGET(bp) != lasttarg) || 1029 if ((XFS_BUF_TARGET(bp) != lasttarg) ||
1031 (time_after(jiffies, (lasttime + 5*HZ)))) { 1030 (time_after(jiffies, (lasttime + 5*HZ)))) {
1032 lasttime = jiffies; 1031 lasttime = jiffies;
1033 prdev("XFS write error in file system meta-data " 1032 cmn_err(CE_ALERT, "Device %s, XFS metadata write error"
1034 "block 0x%llx in %s", 1033 " block 0x%llx in %s",
1035 XFS_BUF_TARGET(bp), 1034 XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)),
1036 (__uint64_t)XFS_BUF_ADDR(bp), mp->m_fsname); 1035 (__uint64_t)XFS_BUF_ADDR(bp), mp->m_fsname);
1037 } 1036 }
1038 lasttarg = XFS_BUF_TARGET(bp); 1037 lasttarg = XFS_BUF_TARGET(bp);
@@ -1108,7 +1107,7 @@ xfs_buf_error_relse(
1108 XFS_BUF_ERROR(bp,0); 1107 XFS_BUF_ERROR(bp,0);
1109 xfs_buftrace("BUF_ERROR_RELSE", bp); 1108 xfs_buftrace("BUF_ERROR_RELSE", bp);
1110 if (! XFS_FORCED_SHUTDOWN(mp)) 1109 if (! XFS_FORCED_SHUTDOWN(mp))
1111 xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); 1110 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
1112 /* 1111 /*
1113 * We have to unpin the pinned buffers so do the 1112 * We have to unpin the pinned buffers so do the
1114 * callbacks. 1113 * callbacks.
diff --git a/fs/xfs/xfs_cap.h b/fs/xfs/xfs_cap.h
index d0035c6e9514..7a0e482dd436 100644
--- a/fs/xfs/xfs_cap.h
+++ b/fs/xfs/xfs_cap.h
@@ -49,12 +49,12 @@ typedef struct xfs_cap_set {
49 49
50#include <linux/posix_cap_xattr.h> 50#include <linux/posix_cap_xattr.h>
51 51
52struct vnode; 52struct bhv_vnode;
53 53
54extern int xfs_cap_vhascap(struct vnode *); 54extern int xfs_cap_vhascap(struct bhv_vnode *);
55extern int xfs_cap_vset(struct vnode *, void *, size_t); 55extern int xfs_cap_vset(struct bhv_vnode *, void *, size_t);
56extern int xfs_cap_vget(struct vnode *, void *, size_t); 56extern int xfs_cap_vget(struct bhv_vnode *, void *, size_t);
57extern int xfs_cap_vremove(struct vnode *vp); 57extern int xfs_cap_vremove(struct bhv_vnode *);
58 58
59#define _CAP_EXISTS xfs_cap_vhascap 59#define _CAP_EXISTS xfs_cap_vhascap
60 60
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 8988b9051175..32ab61d17ace 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -43,7 +41,6 @@
43#include "xfs_bmap.h" 41#include "xfs_bmap.h"
44#include "xfs_attr.h" 42#include "xfs_attr.h"
45#include "xfs_attr_leaf.h" 43#include "xfs_attr_leaf.h"
46#include "xfs_dir_leaf.h"
47#include "xfs_dir2_data.h" 44#include "xfs_dir2_data.h"
48#include "xfs_dir2_leaf.h" 45#include "xfs_dir2_leaf.h"
49#include "xfs_dir2_block.h" 46#include "xfs_dir2_block.h"
@@ -159,7 +156,7 @@ xfs_da_split(xfs_da_state_t *state)
159 max = state->path.active - 1; 156 max = state->path.active - 1;
160 ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH)); 157 ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH));
161 ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC || 158 ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC ||
162 state->path.blk[max].magic == XFS_DIRX_LEAF_MAGIC(state->mp)); 159 state->path.blk[max].magic == XFS_DIR2_LEAFN_MAGIC);
163 160
164 addblk = &state->path.blk[max]; /* initial dummy value */ 161 addblk = &state->path.blk[max]; /* initial dummy value */
165 for (i = max; (i >= 0) && addblk; state->path.active--, i--) { 162 for (i = max; (i >= 0) && addblk; state->path.active--, i--) {
@@ -199,38 +196,7 @@ xfs_da_split(xfs_da_state_t *state)
199 return(error); /* GROT: attr inconsistent */ 196 return(error); /* GROT: attr inconsistent */
200 addblk = newblk; 197 addblk = newblk;
201 break; 198 break;
202 case XFS_DIR_LEAF_MAGIC:
203 ASSERT(XFS_DIR_IS_V1(state->mp));
204 error = xfs_dir_leaf_split(state, oldblk, newblk);
205 if ((error != 0) && (error != ENOSPC)) {
206 return(error); /* GROT: dir is inconsistent */
207 }
208 if (!error) {
209 addblk = newblk;
210 break;
211 }
212 /*
213 * Entry wouldn't fit, split the leaf again.
214 */
215 state->extravalid = 1;
216 if (state->inleaf) {
217 state->extraafter = 0; /* before newblk */
218 error = xfs_dir_leaf_split(state, oldblk,
219 &state->extrablk);
220 if (error)
221 return(error); /* GROT: dir incon. */
222 addblk = newblk;
223 } else {
224 state->extraafter = 1; /* after newblk */
225 error = xfs_dir_leaf_split(state, newblk,
226 &state->extrablk);
227 if (error)
228 return(error); /* GROT: dir incon. */
229 addblk = newblk;
230 }
231 break;
232 case XFS_DIR2_LEAFN_MAGIC: 199 case XFS_DIR2_LEAFN_MAGIC:
233 ASSERT(XFS_DIR_IS_V2(state->mp));
234 error = xfs_dir2_leafn_split(state, oldblk, newblk); 200 error = xfs_dir2_leafn_split(state, oldblk, newblk);
235 if (error) 201 if (error)
236 return error; 202 return error;
@@ -363,7 +329,6 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
363 size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - 329 size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] -
364 (char *)oldroot); 330 (char *)oldroot);
365 } else { 331 } else {
366 ASSERT(XFS_DIR_IS_V2(mp));
367 ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 332 ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
368 leaf = (xfs_dir2_leaf_t *)oldroot; 333 leaf = (xfs_dir2_leaf_t *)oldroot;
369 size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - 334 size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] -
@@ -379,8 +344,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
379 * Set up the new root node. 344 * Set up the new root node.
380 */ 345 */
381 error = xfs_da_node_create(args, 346 error = xfs_da_node_create(args,
382 args->whichfork == XFS_DATA_FORK && 347 (args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0,
383 XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0,
384 be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork); 348 be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork);
385 if (error) 349 if (error)
386 return(error); 350 return(error);
@@ -427,10 +391,9 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
427 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 391 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
428 392
429 /* 393 /*
430 * With V2 the extra block is data or freespace. 394 * With V2 dirs the extra block is data or freespace.
431 */ 395 */
432 useextra = state->extravalid && (XFS_DIR_IS_V1(state->mp) || 396 useextra = state->extravalid && state->args->whichfork == XFS_ATTR_FORK;
433 state->args->whichfork == XFS_ATTR_FORK);
434 newcount = 1 + useextra; 397 newcount = 1 + useextra;
435 /* 398 /*
436 * Do we have to split the node? 399 * Do we have to split the node?
@@ -624,7 +587,7 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
624 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 587 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
625 ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); 588 ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count)));
626 ASSERT(newblk->blkno != 0); 589 ASSERT(newblk->blkno != 0);
627 if (state->args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) 590 if (state->args->whichfork == XFS_DATA_FORK)
628 ASSERT(newblk->blkno >= mp->m_dirleafblk && 591 ASSERT(newblk->blkno >= mp->m_dirleafblk &&
629 newblk->blkno < mp->m_dirfreeblk); 592 newblk->blkno < mp->m_dirfreeblk);
630 593
@@ -670,7 +633,7 @@ xfs_da_join(xfs_da_state_t *state)
670 save_blk = &state->altpath.blk[ state->path.active-1 ]; 633 save_blk = &state->altpath.blk[ state->path.active-1 ];
671 ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC); 634 ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC);
672 ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC || 635 ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC ||
673 drop_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp)); 636 drop_blk->magic == XFS_DIR2_LEAFN_MAGIC);
674 637
675 /* 638 /*
676 * Walk back up the tree joining/deallocating as necessary. 639 * Walk back up the tree joining/deallocating as necessary.
@@ -693,17 +656,7 @@ xfs_da_join(xfs_da_state_t *state)
693 return(0); 656 return(0);
694 xfs_attr_leaf_unbalance(state, drop_blk, save_blk); 657 xfs_attr_leaf_unbalance(state, drop_blk, save_blk);
695 break; 658 break;
696 case XFS_DIR_LEAF_MAGIC:
697 ASSERT(XFS_DIR_IS_V1(state->mp));
698 error = xfs_dir_leaf_toosmall(state, &action);
699 if (error)
700 return(error);
701 if (action == 0)
702 return(0);
703 xfs_dir_leaf_unbalance(state, drop_blk, save_blk);
704 break;
705 case XFS_DIR2_LEAFN_MAGIC: 659 case XFS_DIR2_LEAFN_MAGIC:
706 ASSERT(XFS_DIR_IS_V2(state->mp));
707 error = xfs_dir2_leafn_toosmall(state, &action); 660 error = xfs_dir2_leafn_toosmall(state, &action);
708 if (error) 661 if (error)
709 return error; 662 return error;
@@ -790,7 +743,7 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
790 ASSERT(bp != NULL); 743 ASSERT(bp != NULL);
791 blkinfo = bp->data; 744 blkinfo = bp->data;
792 if (be16_to_cpu(oldroot->hdr.level) == 1) { 745 if (be16_to_cpu(oldroot->hdr.level) == 1) {
793 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || 746 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIR2_LEAFN_MAGIC ||
794 be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC); 747 be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC);
795 } else { 748 } else {
796 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC); 749 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC);
@@ -951,14 +904,7 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path)
951 if (count == 0) 904 if (count == 0)
952 return; 905 return;
953 break; 906 break;
954 case XFS_DIR_LEAF_MAGIC:
955 ASSERT(XFS_DIR_IS_V1(state->mp));
956 lasthash = xfs_dir_leaf_lasthash(blk->bp, &count);
957 if (count == 0)
958 return;
959 break;
960 case XFS_DIR2_LEAFN_MAGIC: 907 case XFS_DIR2_LEAFN_MAGIC:
961 ASSERT(XFS_DIR_IS_V2(state->mp));
962 lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count); 908 lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count);
963 if (count == 0) 909 if (count == 0)
964 return; 910 return;
@@ -1117,10 +1063,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
1117 * Descend thru the B-tree searching each level for the right 1063 * Descend thru the B-tree searching each level for the right
1118 * node to use, until the right hashval is found. 1064 * node to use, until the right hashval is found.
1119 */ 1065 */
1120 if (args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(state->mp)) 1066 blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0;
1121 blkno = state->mp->m_dirleafblk;
1122 else
1123 blkno = 0;
1124 for (blk = &state->path.blk[0], state->path.active = 1; 1067 for (blk = &state->path.blk[0], state->path.active = 1;
1125 state->path.active <= XFS_DA_NODE_MAXDEPTH; 1068 state->path.active <= XFS_DA_NODE_MAXDEPTH;
1126 blk++, state->path.active++) { 1069 blk++, state->path.active++) {
@@ -1137,7 +1080,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
1137 } 1080 }
1138 curr = blk->bp->data; 1081 curr = blk->bp->data;
1139 ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC || 1082 ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC ||
1140 be16_to_cpu(curr->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || 1083 be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC ||
1141 be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC); 1084 be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC);
1142 1085
1143 /* 1086 /*
@@ -1190,16 +1133,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
1190 blk->index = probe; 1133 blk->index = probe;
1191 blkno = be32_to_cpu(btree->before); 1134 blkno = be32_to_cpu(btree->before);
1192 } 1135 }
1193 } 1136 } else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
1194 else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
1195 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); 1137 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
1196 break; 1138 break;
1197 } 1139 } else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
1198 else if (be16_to_cpu(curr->magic) == XFS_DIR_LEAF_MAGIC) {
1199 blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL);
1200 break;
1201 }
1202 else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
1203 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); 1140 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL);
1204 break; 1141 break;
1205 } 1142 }
@@ -1212,12 +1149,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
1212 * next leaf and keep searching. 1149 * next leaf and keep searching.
1213 */ 1150 */
1214 for (;;) { 1151 for (;;) {
1215 if (blk->magic == XFS_DIR_LEAF_MAGIC) { 1152 if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
1216 ASSERT(XFS_DIR_IS_V1(state->mp));
1217 retval = xfs_dir_leaf_lookup_int(blk->bp, args,
1218 &blk->index);
1219 } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
1220 ASSERT(XFS_DIR_IS_V2(state->mp));
1221 retval = xfs_dir2_leafn_lookup_int(blk->bp, args, 1153 retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
1222 &blk->index, state); 1154 &blk->index, state);
1223 } 1155 }
@@ -1270,7 +1202,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
1270 old_info = old_blk->bp->data; 1202 old_info = old_blk->bp->data;
1271 new_info = new_blk->bp->data; 1203 new_info = new_blk->bp->data;
1272 ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || 1204 ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC ||
1273 old_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || 1205 old_blk->magic == XFS_DIR2_LEAFN_MAGIC ||
1274 old_blk->magic == XFS_ATTR_LEAF_MAGIC); 1206 old_blk->magic == XFS_ATTR_LEAF_MAGIC);
1275 ASSERT(old_blk->magic == be16_to_cpu(old_info->magic)); 1207 ASSERT(old_blk->magic == be16_to_cpu(old_info->magic));
1276 ASSERT(new_blk->magic == be16_to_cpu(new_info->magic)); 1208 ASSERT(new_blk->magic == be16_to_cpu(new_info->magic));
@@ -1280,12 +1212,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
1280 case XFS_ATTR_LEAF_MAGIC: 1212 case XFS_ATTR_LEAF_MAGIC:
1281 before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp); 1213 before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp);
1282 break; 1214 break;
1283 case XFS_DIR_LEAF_MAGIC:
1284 ASSERT(XFS_DIR_IS_V1(state->mp));
1285 before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp);
1286 break;
1287 case XFS_DIR2_LEAFN_MAGIC: 1215 case XFS_DIR2_LEAFN_MAGIC:
1288 ASSERT(XFS_DIR_IS_V2(state->mp));
1289 before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp); 1216 before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp);
1290 break; 1217 break;
1291 case XFS_DA_NODE_MAGIC: 1218 case XFS_DA_NODE_MAGIC:
@@ -1404,7 +1331,7 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
1404 save_info = save_blk->bp->data; 1331 save_info = save_blk->bp->data;
1405 drop_info = drop_blk->bp->data; 1332 drop_info = drop_blk->bp->data;
1406 ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || 1333 ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC ||
1407 save_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || 1334 save_blk->magic == XFS_DIR2_LEAFN_MAGIC ||
1408 save_blk->magic == XFS_ATTR_LEAF_MAGIC); 1335 save_blk->magic == XFS_ATTR_LEAF_MAGIC);
1409 ASSERT(save_blk->magic == be16_to_cpu(save_info->magic)); 1336 ASSERT(save_blk->magic == be16_to_cpu(save_info->magic));
1410 ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic)); 1337 ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic));
@@ -1529,7 +1456,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
1529 ASSERT(blk->bp != NULL); 1456 ASSERT(blk->bp != NULL);
1530 info = blk->bp->data; 1457 info = blk->bp->data;
1531 ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC || 1458 ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC ||
1532 be16_to_cpu(info->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || 1459 be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC ||
1533 be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); 1460 be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC);
1534 blk->magic = be16_to_cpu(info->magic); 1461 blk->magic = be16_to_cpu(info->magic);
1535 if (blk->magic == XFS_DA_NODE_MAGIC) { 1462 if (blk->magic == XFS_DA_NODE_MAGIC) {
@@ -1548,20 +1475,13 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
1548 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, 1475 blk->hashval = xfs_attr_leaf_lasthash(blk->bp,
1549 NULL); 1476 NULL);
1550 break; 1477 break;
1551 case XFS_DIR_LEAF_MAGIC:
1552 ASSERT(XFS_DIR_IS_V1(state->mp));
1553 blk->hashval = xfs_dir_leaf_lasthash(blk->bp,
1554 NULL);
1555 break;
1556 case XFS_DIR2_LEAFN_MAGIC: 1478 case XFS_DIR2_LEAFN_MAGIC:
1557 ASSERT(XFS_DIR_IS_V2(state->mp));
1558 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, 1479 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp,
1559 NULL); 1480 NULL);
1560 break; 1481 break;
1561 default: 1482 default:
1562 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || 1483 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC ||
1563 blk->magic == 1484 blk->magic == XFS_DIR2_LEAFN_MAGIC);
1564 XFS_DIRX_LEAF_MAGIC(state->mp));
1565 break; 1485 break;
1566 } 1486 }
1567 } 1487 }
@@ -1620,7 +1540,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1620 xfs_bmbt_irec_t *mapp; 1540 xfs_bmbt_irec_t *mapp;
1621 xfs_inode_t *dp; 1541 xfs_inode_t *dp;
1622 int nmap, error, w, count, c, got, i, mapi; 1542 int nmap, error, w, count, c, got, i, mapi;
1623 xfs_fsize_t size;
1624 xfs_trans_t *tp; 1543 xfs_trans_t *tp;
1625 xfs_mount_t *mp; 1544 xfs_mount_t *mp;
1626 1545
@@ -1631,7 +1550,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1631 /* 1550 /*
1632 * For new directories adjust the file offset and block count. 1551 * For new directories adjust the file offset and block count.
1633 */ 1552 */
1634 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) { 1553 if (w == XFS_DATA_FORK) {
1635 bno = mp->m_dirleafblk; 1554 bno = mp->m_dirleafblk;
1636 count = mp->m_dirblkfsbs; 1555 count = mp->m_dirblkfsbs;
1637 } else { 1556 } else {
@@ -1641,10 +1560,9 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1641 /* 1560 /*
1642 * Find a spot in the file space to put the new block. 1561 * Find a spot in the file space to put the new block.
1643 */ 1562 */
1644 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) { 1563 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w)))
1645 return error; 1564 return error;
1646 } 1565 if (w == XFS_DATA_FORK)
1647 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
1648 ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk); 1566 ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk);
1649 /* 1567 /*
1650 * Try mapping it in one filesystem block. 1568 * Try mapping it in one filesystem block.
@@ -1655,7 +1573,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1655 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| 1573 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|
1656 XFS_BMAPI_CONTIG, 1574 XFS_BMAPI_CONTIG,
1657 args->firstblock, args->total, &map, &nmap, 1575 args->firstblock, args->total, &map, &nmap,
1658 args->flist))) { 1576 args->flist, NULL))) {
1659 return error; 1577 return error;
1660 } 1578 }
1661 ASSERT(nmap <= 1); 1579 ASSERT(nmap <= 1);
@@ -1676,7 +1594,8 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1676 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE| 1594 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|
1677 XFS_BMAPI_METADATA, 1595 XFS_BMAPI_METADATA,
1678 args->firstblock, args->total, 1596 args->firstblock, args->total,
1679 &mapp[mapi], &nmap, args->flist))) { 1597 &mapp[mapi], &nmap, args->flist,
1598 NULL))) {
1680 kmem_free(mapp, sizeof(*mapp) * count); 1599 kmem_free(mapp, sizeof(*mapp) * count);
1681 return error; 1600 return error;
1682 } 1601 }
@@ -1705,19 +1624,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1705 if (mapp != &map) 1624 if (mapp != &map)
1706 kmem_free(mapp, sizeof(*mapp) * count); 1625 kmem_free(mapp, sizeof(*mapp) * count);
1707 *new_blkno = (xfs_dablk_t)bno; 1626 *new_blkno = (xfs_dablk_t)bno;
1708 /*
1709 * For version 1 directories, adjust the file size if it changed.
1710 */
1711 if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
1712 ASSERT(mapi == 1);
1713 if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
1714 return error;
1715 size = XFS_FSB_TO_B(mp, bno);
1716 if (size != dp->i_d.di_size) {
1717 dp->i_d.di_size = size;
1718 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
1719 }
1720 }
1721 return 0; 1627 return 0;
1722} 1628}
1723 1629
@@ -1742,7 +1648,6 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1742 int error, w, entno, level, dead_level; 1648 int error, w, entno, level, dead_level;
1743 xfs_da_blkinfo_t *dead_info, *sib_info; 1649 xfs_da_blkinfo_t *dead_info, *sib_info;
1744 xfs_da_intnode_t *par_node, *dead_node; 1650 xfs_da_intnode_t *par_node, *dead_node;
1745 xfs_dir_leafblock_t *dead_leaf;
1746 xfs_dir2_leaf_t *dead_leaf2; 1651 xfs_dir2_leaf_t *dead_leaf2;
1747 xfs_dahash_t dead_hash; 1652 xfs_dahash_t dead_hash;
1748 1653
@@ -1753,11 +1658,8 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1753 w = args->whichfork; 1658 w = args->whichfork;
1754 ASSERT(w == XFS_DATA_FORK); 1659 ASSERT(w == XFS_DATA_FORK);
1755 mp = ip->i_mount; 1660 mp = ip->i_mount;
1756 if (XFS_DIR_IS_V2(mp)) { 1661 lastoff = mp->m_dirfreeblk;
1757 lastoff = mp->m_dirfreeblk; 1662 error = xfs_bmap_last_before(tp, ip, &lastoff, w);
1758 error = xfs_bmap_last_before(tp, ip, &lastoff, w);
1759 } else
1760 error = xfs_bmap_last_offset(tp, ip, &lastoff, w);
1761 if (error) 1663 if (error)
1762 return error; 1664 return error;
1763 if (unlikely(lastoff == 0)) { 1665 if (unlikely(lastoff == 0)) {
@@ -1780,14 +1682,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1780 /* 1682 /*
1781 * Get values from the moved block. 1683 * Get values from the moved block.
1782 */ 1684 */
1783 if (be16_to_cpu(dead_info->magic) == XFS_DIR_LEAF_MAGIC) { 1685 if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) {
1784 ASSERT(XFS_DIR_IS_V1(mp));
1785 dead_leaf = (xfs_dir_leafblock_t *)dead_info;
1786 dead_level = 0;
1787 dead_hash =
1788 INT_GET(dead_leaf->entries[INT_GET(dead_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
1789 } else if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) {
1790 ASSERT(XFS_DIR_IS_V2(mp));
1791 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; 1686 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
1792 dead_level = 0; 1687 dead_level = 0;
1793 dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); 1688 dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval);
@@ -1842,7 +1737,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1842 xfs_da_buf_done(sib_buf); 1737 xfs_da_buf_done(sib_buf);
1843 sib_buf = NULL; 1738 sib_buf = NULL;
1844 } 1739 }
1845 par_blkno = XFS_DIR_IS_V1(mp) ? 0 : mp->m_dirleafblk; 1740 par_blkno = mp->m_dirleafblk;
1846 level = -1; 1741 level = -1;
1847 /* 1742 /*
1848 * Walk down the tree looking for the parent of the moved block. 1743 * Walk down the tree looking for the parent of the moved block.
@@ -1941,8 +1836,6 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
1941{ 1836{
1942 xfs_inode_t *dp; 1837 xfs_inode_t *dp;
1943 int done, error, w, count; 1838 int done, error, w, count;
1944 xfs_fileoff_t bno;
1945 xfs_fsize_t size;
1946 xfs_trans_t *tp; 1839 xfs_trans_t *tp;
1947 xfs_mount_t *mp; 1840 xfs_mount_t *mp;
1948 1841
@@ -1950,7 +1843,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
1950 w = args->whichfork; 1843 w = args->whichfork;
1951 tp = args->trans; 1844 tp = args->trans;
1952 mp = dp->i_mount; 1845 mp = dp->i_mount;
1953 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) 1846 if (w == XFS_DATA_FORK)
1954 count = mp->m_dirblkfsbs; 1847 count = mp->m_dirblkfsbs;
1955 else 1848 else
1956 count = 1; 1849 count = 1;
@@ -1961,34 +1854,17 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
1961 */ 1854 */
1962 if ((error = xfs_bunmapi(tp, dp, dead_blkno, count, 1855 if ((error = xfs_bunmapi(tp, dp, dead_blkno, count,
1963 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA, 1856 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA,
1964 0, args->firstblock, args->flist, 1857 0, args->firstblock, args->flist, NULL,
1965 &done)) == ENOSPC) { 1858 &done)) == ENOSPC) {
1966 if (w != XFS_DATA_FORK) 1859 if (w != XFS_DATA_FORK)
1967 goto done; 1860 break;
1968 if ((error = xfs_da_swap_lastblock(args, &dead_blkno, 1861 if ((error = xfs_da_swap_lastblock(args, &dead_blkno,
1969 &dead_buf))) 1862 &dead_buf)))
1970 goto done; 1863 break;
1971 } else if (error) 1864 } else {
1972 goto done;
1973 else
1974 break; 1865 break;
1975 }
1976 ASSERT(done);
1977 xfs_da_binval(tp, dead_buf);
1978 /*
1979 * Adjust the directory size for version 1.
1980 */
1981 if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
1982 if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
1983 return error;
1984 size = XFS_FSB_TO_B(dp->i_mount, bno);
1985 if (size != dp->i_d.di_size) {
1986 dp->i_d.di_size = size;
1987 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
1988 } 1866 }
1989 } 1867 }
1990 return 0;
1991done:
1992 xfs_da_binval(tp, dead_buf); 1868 xfs_da_binval(tp, dead_buf);
1993 return error; 1869 return error;
1994} 1870}
@@ -2049,10 +1925,7 @@ xfs_da_do_buf(
2049 xfs_dabuf_t *rbp; 1925 xfs_dabuf_t *rbp;
2050 1926
2051 mp = dp->i_mount; 1927 mp = dp->i_mount;
2052 if (whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) 1928 nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1;
2053 nfsb = mp->m_dirblkfsbs;
2054 else
2055 nfsb = 1;
2056 mappedbno = *mappedbnop; 1929 mappedbno = *mappedbnop;
2057 /* 1930 /*
2058 * Caller doesn't have a mapping. -2 means don't complain 1931 * Caller doesn't have a mapping. -2 means don't complain
@@ -2086,7 +1959,7 @@ xfs_da_do_buf(
2086 nfsb, 1959 nfsb,
2087 XFS_BMAPI_METADATA | 1960 XFS_BMAPI_METADATA |
2088 XFS_BMAPI_AFLAG(whichfork), 1961 XFS_BMAPI_AFLAG(whichfork),
2089 NULL, 0, mapp, &nmap, NULL))) 1962 NULL, 0, mapp, &nmap, NULL, NULL)))
2090 goto exit0; 1963 goto exit0;
2091 } 1964 }
2092 } else { 1965 } else {
@@ -2198,7 +2071,6 @@ xfs_da_do_buf(
2198 magic1 = be32_to_cpu(data->hdr.magic); 2071 magic1 = be32_to_cpu(data->hdr.magic);
2199 if (unlikely( 2072 if (unlikely(
2200 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && 2073 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
2201 (magic != XFS_DIR_LEAF_MAGIC) &&
2202 (magic != XFS_ATTR_LEAF_MAGIC) && 2074 (magic != XFS_ATTR_LEAF_MAGIC) &&
2203 (magic != XFS_DIR2_LEAF1_MAGIC) && 2075 (magic != XFS_DIR2_LEAF1_MAGIC) &&
2204 (magic != XFS_DIR2_LEAFN_MAGIC) && 2076 (magic != XFS_DIR2_LEAFN_MAGIC) &&
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index 243a730d5ec8..4ab865ec8b82 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -36,14 +36,10 @@ struct zone;
36 * level in the Btree, and to identify which type of block this is. 36 * level in the Btree, and to identify which type of block this is.
37 */ 37 */
38#define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ 38#define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */
39#define XFS_DIR_LEAF_MAGIC 0xfeeb /* magic number: directory leaf blks */
40#define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ 39#define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */
41#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ 40#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */
42#define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ 41#define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */
43 42
44#define XFS_DIRX_LEAF_MAGIC(mp) \
45 (XFS_DIR_IS_V1(mp) ? XFS_DIR_LEAF_MAGIC : XFS_DIR2_LEAFN_MAGIC)
46
47typedef struct xfs_da_blkinfo { 43typedef struct xfs_da_blkinfo {
48 __be32 forw; /* previous block in list */ 44 __be32 forw; /* previous block in list */
49 __be32 back; /* following block in list */ 45 __be32 back; /* following block in list */
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 4968a6358e61..80562b60fb95 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -54,24 +52,14 @@ xfs_swapext(
54 xfs_swapext_t __user *sxu) 52 xfs_swapext_t __user *sxu)
55{ 53{
56 xfs_swapext_t *sxp; 54 xfs_swapext_t *sxp;
57 xfs_inode_t *ip=NULL, *tip=NULL, *ips[2]; 55 xfs_inode_t *ip=NULL, *tip=NULL;
58 xfs_trans_t *tp;
59 xfs_mount_t *mp; 56 xfs_mount_t *mp;
60 xfs_bstat_t *sbp;
61 struct file *fp = NULL, *tfp = NULL; 57 struct file *fp = NULL, *tfp = NULL;
62 vnode_t *vp, *tvp; 58 bhv_vnode_t *vp, *tvp;
63 static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
64 int ilf_fields, tilf_fields;
65 int error = 0; 59 int error = 0;
66 xfs_ifork_t *tempifp, *ifp, *tifp;
67 __uint64_t tmp;
68 int aforkblks = 0;
69 int taforkblks = 0;
70 char locked = 0;
71 60
72 sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL); 61 sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL);
73 tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); 62 if (!sxp) {
74 if (!sxp || !tempifp) {
75 error = XFS_ERROR(ENOMEM); 63 error = XFS_ERROR(ENOMEM);
76 goto error0; 64 goto error0;
77 } 65 }
@@ -118,14 +106,56 @@ xfs_swapext(
118 106
119 mp = ip->i_mount; 107 mp = ip->i_mount;
120 108
121 sbp = &sxp->sx_stat;
122
123 if (XFS_FORCED_SHUTDOWN(mp)) { 109 if (XFS_FORCED_SHUTDOWN(mp)) {
124 error = XFS_ERROR(EIO); 110 error = XFS_ERROR(EIO);
125 goto error0; 111 goto error0;
126 } 112 }
127 113
128 locked = 1; 114 error = XFS_SWAP_EXTENTS(mp, &ip->i_iocore, &tip->i_iocore, sxp);
115
116 error0:
117 if (fp != NULL)
118 fput(fp);
119 if (tfp != NULL)
120 fput(tfp);
121
122 if (sxp != NULL)
123 kmem_free(sxp, sizeof(xfs_swapext_t));
124
125 return error;
126}
127
128int
129xfs_swap_extents(
130 xfs_inode_t *ip,
131 xfs_inode_t *tip,
132 xfs_swapext_t *sxp)
133{
134 xfs_mount_t *mp;
135 xfs_inode_t *ips[2];
136 xfs_trans_t *tp;
137 xfs_bstat_t *sbp = &sxp->sx_stat;
138 bhv_vnode_t *vp, *tvp;
139 xfs_ifork_t *tempifp, *ifp, *tifp;
140 int ilf_fields, tilf_fields;
141 static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
142 int error = 0;
143 int aforkblks = 0;
144 int taforkblks = 0;
145 __uint64_t tmp;
146 char locked = 0;
147
148 mp = ip->i_mount;
149
150 tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
151 if (!tempifp) {
152 error = XFS_ERROR(ENOMEM);
153 goto error0;
154 }
155
156 sbp = &sxp->sx_stat;
157 vp = XFS_ITOV(ip);
158 tvp = XFS_ITOV(tip);
129 159
130 /* Lock in i_ino order */ 160 /* Lock in i_ino order */
131 if (ip->i_ino < tip->i_ino) { 161 if (ip->i_ino < tip->i_ino) {
@@ -137,6 +167,7 @@ xfs_swapext(
137 } 167 }
138 168
139 xfs_lock_inodes(ips, 2, 0, lock_flags); 169 xfs_lock_inodes(ips, 2, 0, lock_flags);
170 locked = 1;
140 171
141 /* Check permissions */ 172 /* Check permissions */
142 error = xfs_iaccess(ip, S_IWUSR, NULL); 173 error = xfs_iaccess(ip, S_IWUSR, NULL);
@@ -169,7 +200,7 @@ xfs_swapext(
169 200
170 if (VN_CACHED(tvp) != 0) { 201 if (VN_CACHED(tvp) != 0) {
171 xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1); 202 xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
172 VOP_FLUSHINVAL_PAGES(tvp, 0, -1, FI_REMAPF_LOCKED); 203 bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED);
173 } 204 }
174 205
175 /* Verify O_DIRECT for ftmp */ 206 /* Verify O_DIRECT for ftmp */
@@ -214,7 +245,7 @@ xfs_swapext(
214 /* We need to fail if the file is memory mapped. Once we have tossed 245 /* We need to fail if the file is memory mapped. Once we have tossed
215 * all existing pages, the page fault will have no option 246 * all existing pages, the page fault will have no option
216 * but to go to the filesystem for pages. By making the page fault call 247 * but to go to the filesystem for pages. By making the page fault call
217 * VOP_READ (or write in the case of autogrow) they block on the iolock 248 * vop_read (or write in the case of autogrow) they block on the iolock
218 * until we have switched the extents. 249 * until we have switched the extents.
219 */ 250 */
220 if (VN_MAPPED(vp)) { 251 if (VN_MAPPED(vp)) {
@@ -233,7 +264,7 @@ xfs_swapext(
233 * fields change. 264 * fields change.
234 */ 265 */
235 266
236 VOP_TOSS_PAGES(vp, 0, -1, FI_REMAPF); 267 bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
237 268
238 tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT); 269 tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT);
239 if ((error = xfs_trans_reserve(tp, 0, 270 if ((error = xfs_trans_reserve(tp, 0,
@@ -360,16 +391,7 @@ xfs_swapext(
360 xfs_iunlock(ip, lock_flags); 391 xfs_iunlock(ip, lock_flags);
361 xfs_iunlock(tip, lock_flags); 392 xfs_iunlock(tip, lock_flags);
362 } 393 }
363
364 if (fp != NULL)
365 fput(fp);
366 if (tfp != NULL)
367 fput(tfp);
368
369 if (sxp != NULL)
370 kmem_free(sxp, sizeof(xfs_swapext_t));
371 if (tempifp != NULL) 394 if (tempifp != NULL)
372 kmem_free(tempifp, sizeof(xfs_ifork_t)); 395 kmem_free(tempifp, sizeof(xfs_ifork_t));
373
374 return error; 396 return error;
375} 397}
diff --git a/fs/xfs/xfs_dfrag.h b/fs/xfs/xfs_dfrag.h
index f678559abc45..da178205be68 100644
--- a/fs/xfs/xfs_dfrag.h
+++ b/fs/xfs/xfs_dfrag.h
@@ -48,6 +48,9 @@ typedef struct xfs_swapext
48 */ 48 */
49int xfs_swapext(struct xfs_swapext __user *sx); 49int xfs_swapext(struct xfs_swapext __user *sx);
50 50
51int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip,
52 struct xfs_swapext *sxp);
53
51#endif /* __KERNEL__ */ 54#endif /* __KERNEL__ */
52 55
53#endif /* __XFS_DFRAG_H__ */ 56#endif /* __XFS_DFRAG_H__ */
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h
index 79d0d9e1fbab..b33826961c45 100644
--- a/fs/xfs/xfs_dinode.h
+++ b/fs/xfs/xfs_dinode.h
@@ -85,7 +85,6 @@ typedef struct xfs_dinode
85 union { 85 union {
86 xfs_bmdr_block_t di_bmbt; /* btree root block */ 86 xfs_bmdr_block_t di_bmbt; /* btree root block */
87 xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */ 87 xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */
88 xfs_dir_shortform_t di_dirsf; /* shortform directory */
89 xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */ 88 xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */
90 char di_c[1]; /* local contents */ 89 char di_c[1]; /* local contents */
91 xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */ 90 xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */
@@ -257,6 +256,7 @@ typedef enum xfs_dinode_fmt
257#define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */ 256#define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */
258#define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */ 257#define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */
259#define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ 258#define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */
259#define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */
260#define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT) 260#define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT)
261#define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) 261#define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT)
262#define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT) 262#define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT)
@@ -270,12 +270,13 @@ typedef enum xfs_dinode_fmt
270#define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT) 270#define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT)
271#define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT) 271#define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT)
272#define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT) 272#define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
273#define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT)
273 274
274#define XFS_DIFLAG_ANY \ 275#define XFS_DIFLAG_ANY \
275 (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ 276 (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
276 XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ 277 XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
277 XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \ 278 XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
278 XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \ 279 XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
279 XFS_DIFLAG_EXTSZINHERIT) 280 XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG)
280 281
281#endif /* __XFS_DINODE_H__ */ 282#endif /* __XFS_DINODE_H__ */
diff --git a/fs/xfs/xfs_dir.c b/fs/xfs/xfs_dir.c
deleted file mode 100644
index 9cc702a839a3..000000000000
--- a/fs/xfs/xfs_dir.c
+++ /dev/null
@@ -1,1217 +0,0 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_types.h"
21#include "xfs_log.h"
22#include "xfs_inum.h"
23#include "xfs_trans.h"
24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h"
27#include "xfs_dmapi.h"
28#include "xfs_mount.h"
29#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h"
32#include "xfs_ialloc_btree.h"
33#include "xfs_alloc.h"
34#include "xfs_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h"
38#include "xfs_dinode.h"
39#include "xfs_inode.h"
40#include "xfs_bmap.h"
41#include "xfs_dir_leaf.h"
42#include "xfs_error.h"
43
44/*
45 * xfs_dir.c
46 *
47 * Provide the external interfaces to manage directories.
48 */
49
50/*========================================================================
51 * Function prototypes for the kernel.
52 *========================================================================*/
53
54/*
55 * Functions for the dirops interfaces.
56 */
57static void xfs_dir_mount(struct xfs_mount *mp);
58
59static int xfs_dir_isempty(struct xfs_inode *dp);
60
61static int xfs_dir_init(struct xfs_trans *trans,
62 struct xfs_inode *dir,
63 struct xfs_inode *parent_dir);
64
65static int xfs_dir_createname(struct xfs_trans *trans,
66 struct xfs_inode *dp,
67 char *name_string,
68 int name_len,
69 xfs_ino_t inode_number,
70 xfs_fsblock_t *firstblock,
71 xfs_bmap_free_t *flist,
72 xfs_extlen_t total);
73
74static int xfs_dir_lookup(struct xfs_trans *tp,
75 struct xfs_inode *dp,
76 char *name_string,
77 int name_length,
78 xfs_ino_t *inode_number);
79
80static int xfs_dir_removename(struct xfs_trans *trans,
81 struct xfs_inode *dp,
82 char *name_string,
83 int name_length,
84 xfs_ino_t ino,
85 xfs_fsblock_t *firstblock,
86 xfs_bmap_free_t *flist,
87 xfs_extlen_t total);
88
89static int xfs_dir_getdents(struct xfs_trans *tp,
90 struct xfs_inode *dp,
91 struct uio *uiop,
92 int *eofp);
93
94static int xfs_dir_replace(struct xfs_trans *tp,
95 struct xfs_inode *dp,
96 char *name_string,
97 int name_length,
98 xfs_ino_t inode_number,
99 xfs_fsblock_t *firstblock,
100 xfs_bmap_free_t *flist,
101 xfs_extlen_t total);
102
103static int xfs_dir_canenter(struct xfs_trans *tp,
104 struct xfs_inode *dp,
105 char *name_string,
106 int name_length);
107
108static int xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp,
109 xfs_dinode_t *dip);
110
111xfs_dirops_t xfsv1_dirops = {
112 .xd_mount = xfs_dir_mount,
113 .xd_isempty = xfs_dir_isempty,
114 .xd_init = xfs_dir_init,
115 .xd_createname = xfs_dir_createname,
116 .xd_lookup = xfs_dir_lookup,
117 .xd_removename = xfs_dir_removename,
118 .xd_getdents = xfs_dir_getdents,
119 .xd_replace = xfs_dir_replace,
120 .xd_canenter = xfs_dir_canenter,
121 .xd_shortform_validate_ondisk = xfs_dir_shortform_validate_ondisk,
122 .xd_shortform_to_single = xfs_dir_shortform_to_leaf,
123};
124
125/*
126 * Internal routines when dirsize == XFS_LBSIZE(mp).
127 */
128STATIC int xfs_dir_leaf_lookup(xfs_da_args_t *args);
129STATIC int xfs_dir_leaf_removename(xfs_da_args_t *args, int *number_entries,
130 int *total_namebytes);
131STATIC int xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp,
132 uio_t *uio, int *eofp,
133 xfs_dirent_t *dbp,
134 xfs_dir_put_t put);
135STATIC int xfs_dir_leaf_replace(xfs_da_args_t *args);
136
137/*
138 * Internal routines when dirsize > XFS_LBSIZE(mp).
139 */
140STATIC int xfs_dir_node_addname(xfs_da_args_t *args);
141STATIC int xfs_dir_node_lookup(xfs_da_args_t *args);
142STATIC int xfs_dir_node_removename(xfs_da_args_t *args);
143STATIC int xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp,
144 uio_t *uio, int *eofp,
145 xfs_dirent_t *dbp,
146 xfs_dir_put_t put);
147STATIC int xfs_dir_node_replace(xfs_da_args_t *args);
148
149#if defined(XFS_DIR_TRACE)
150ktrace_t *xfs_dir_trace_buf;
151#endif
152
153
154/*========================================================================
155 * Overall external interface routines.
156 *========================================================================*/
157
158xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
159
160/*
161 * One-time startup routine called from xfs_init().
162 */
163void
164xfs_dir_startup(void)
165{
166 xfs_dir_hash_dot = xfs_da_hashname(".", 1);
167 xfs_dir_hash_dotdot = xfs_da_hashname("..", 2);
168}
169
170/*
171 * Initialize directory-related fields in the mount structure.
172 */
173static void
174xfs_dir_mount(xfs_mount_t *mp)
175{
176 uint shortcount, leafcount, count;
177
178 mp->m_dirversion = 1;
179 if (!(mp->m_flags & XFS_MOUNT_ATTR2)) {
180 shortcount = (mp->m_attroffset -
181 (uint)sizeof(xfs_dir_sf_hdr_t)) /
182 (uint)sizeof(xfs_dir_sf_entry_t);
183 leafcount = (XFS_LBSIZE(mp) -
184 (uint)sizeof(xfs_dir_leaf_hdr_t)) /
185 ((uint)sizeof(xfs_dir_leaf_entry_t) +
186 (uint)sizeof(xfs_dir_leaf_name_t));
187 } else {
188 shortcount = (XFS_BMDR_SPACE_CALC(MINABTPTRS) -
189 (uint)sizeof(xfs_dir_sf_hdr_t)) /
190 (uint)sizeof(xfs_dir_sf_entry_t);
191 leafcount = (XFS_LBSIZE(mp) -
192 (uint)sizeof(xfs_dir_leaf_hdr_t)) /
193 ((uint)sizeof(xfs_dir_leaf_entry_t) +
194 (uint)sizeof(xfs_dir_leaf_name_t));
195 }
196 count = shortcount > leafcount ? shortcount : leafcount;
197 mp->m_dircook_elog = xfs_da_log2_roundup(count + 1);
198 ASSERT(mp->m_dircook_elog <= mp->m_sb.sb_blocklog);
199 mp->m_dir_node_ents = mp->m_attr_node_ents =
200 (XFS_LBSIZE(mp) - (uint)sizeof(xfs_da_node_hdr_t)) /
201 (uint)sizeof(xfs_da_node_entry_t);
202 mp->m_dir_magicpct = (XFS_LBSIZE(mp) * 37) / 100;
203 mp->m_dirblksize = mp->m_sb.sb_blocksize;
204 mp->m_dirblkfsbs = 1;
205}
206
207/*
208 * Return 1 if directory contains only "." and "..".
209 */
210static int
211xfs_dir_isempty(xfs_inode_t *dp)
212{
213 xfs_dir_sf_hdr_t *hdr;
214
215 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
216 if (dp->i_d.di_size == 0)
217 return(1);
218 if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
219 return(0);
220 hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data;
221 return(hdr->count == 0);
222}
223
224/*
225 * Initialize a directory with its "." and ".." entries.
226 */
227static int
228xfs_dir_init(xfs_trans_t *trans, xfs_inode_t *dir, xfs_inode_t *parent_dir)
229{
230 xfs_da_args_t args;
231 int error;
232
233 memset((char *)&args, 0, sizeof(args));
234 args.dp = dir;
235 args.trans = trans;
236
237 ASSERT((dir->i_d.di_mode & S_IFMT) == S_IFDIR);
238 if ((error = xfs_dir_ino_validate(trans->t_mountp, parent_dir->i_ino)))
239 return error;
240
241 return(xfs_dir_shortform_create(&args, parent_dir->i_ino));
242}
243
244/*
245 * Generic handler routine to add a name to a directory.
246 * Transitions directory from shortform to Btree as necessary.
247 */
248static int /* error */
249xfs_dir_createname(xfs_trans_t *trans, xfs_inode_t *dp, char *name,
250 int namelen, xfs_ino_t inum, xfs_fsblock_t *firstblock,
251 xfs_bmap_free_t *flist, xfs_extlen_t total)
252{
253 xfs_da_args_t args;
254 int retval, newsize, done;
255
256 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
257
258 if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
259 return (retval);
260
261 XFS_STATS_INC(xs_dir_create);
262 /*
263 * Fill in the arg structure for this request.
264 */
265 args.name = name;
266 args.namelen = namelen;
267 args.hashval = xfs_da_hashname(name, namelen);
268 args.inumber = inum;
269 args.dp = dp;
270 args.firstblock = firstblock;
271 args.flist = flist;
272 args.total = total;
273 args.whichfork = XFS_DATA_FORK;
274 args.trans = trans;
275 args.justcheck = 0;
276 args.addname = args.oknoent = 1;
277
278 /*
279 * Decide on what work routines to call based on the inode size.
280 */
281 done = 0;
282 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
283 newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen);
284 if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp)) {
285 retval = xfs_dir_shortform_addname(&args);
286 done = 1;
287 } else {
288 if (total == 0)
289 return XFS_ERROR(ENOSPC);
290 retval = xfs_dir_shortform_to_leaf(&args);
291 done = retval != 0;
292 }
293 }
294 if (!done && xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
295 retval = xfs_dir_leaf_addname(&args);
296 done = retval != ENOSPC;
297 if (!done) {
298 if (total == 0)
299 return XFS_ERROR(ENOSPC);
300 retval = xfs_dir_leaf_to_node(&args);
301 done = retval != 0;
302 }
303 }
304 if (!done) {
305 retval = xfs_dir_node_addname(&args);
306 }
307 return(retval);
308}
309
310/*
311 * Generic handler routine to check if a name can be added to a directory,
312 * without adding any blocks to the directory.
313 */
314static int /* error */
315xfs_dir_canenter(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen)
316{
317 xfs_da_args_t args;
318 int retval, newsize;
319
320 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
321 /*
322 * Fill in the arg structure for this request.
323 */
324 args.name = name;
325 args.namelen = namelen;
326 args.hashval = xfs_da_hashname(name, namelen);
327 args.inumber = 0;
328 args.dp = dp;
329 args.firstblock = NULL;
330 args.flist = NULL;
331 args.total = 0;
332 args.whichfork = XFS_DATA_FORK;
333 args.trans = trans;
334 args.justcheck = args.addname = args.oknoent = 1;
335
336 /*
337 * Decide on what work routines to call based on the inode size.
338 */
339 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
340 newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen);
341 if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp))
342 retval = 0;
343 else
344 retval = XFS_ERROR(ENOSPC);
345 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
346 retval = xfs_dir_leaf_addname(&args);
347 } else {
348 retval = xfs_dir_node_addname(&args);
349 }
350 return(retval);
351}
352
353/*
354 * Generic handler routine to remove a name from a directory.
355 * Transitions directory from Btree to shortform as necessary.
356 */
357static int /* error */
358xfs_dir_removename(xfs_trans_t *trans, xfs_inode_t *dp, char *name,
359 int namelen, xfs_ino_t ino, xfs_fsblock_t *firstblock,
360 xfs_bmap_free_t *flist, xfs_extlen_t total)
361{
362 xfs_da_args_t args;
363 int count, totallen, newsize, retval;
364
365 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
366 XFS_STATS_INC(xs_dir_remove);
367 /*
368 * Fill in the arg structure for this request.
369 */
370 args.name = name;
371 args.namelen = namelen;
372 args.hashval = xfs_da_hashname(name, namelen);
373 args.inumber = ino;
374 args.dp = dp;
375 args.firstblock = firstblock;
376 args.flist = flist;
377 args.total = total;
378 args.whichfork = XFS_DATA_FORK;
379 args.trans = trans;
380 args.justcheck = args.addname = args.oknoent = 0;
381
382 /*
383 * Decide on what work routines to call based on the inode size.
384 */
385 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
386 retval = xfs_dir_shortform_removename(&args);
387 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
388 retval = xfs_dir_leaf_removename(&args, &count, &totallen);
389 if (retval == 0) {
390 newsize = XFS_DIR_SF_ALLFIT(count, totallen);
391 if (newsize <= XFS_IFORK_DSIZE(dp)) {
392 retval = xfs_dir_leaf_to_shortform(&args);
393 }
394 }
395 } else {
396 retval = xfs_dir_node_removename(&args);
397 }
398 return(retval);
399}
400
401static int /* error */
402xfs_dir_lookup(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen,
403 xfs_ino_t *inum)
404{
405 xfs_da_args_t args;
406 int retval;
407
408 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
409
410 XFS_STATS_INC(xs_dir_lookup);
411 /*
412 * Fill in the arg structure for this request.
413 */
414 args.name = name;
415 args.namelen = namelen;
416 args.hashval = xfs_da_hashname(name, namelen);
417 args.inumber = 0;
418 args.dp = dp;
419 args.firstblock = NULL;
420 args.flist = NULL;
421 args.total = 0;
422 args.whichfork = XFS_DATA_FORK;
423 args.trans = trans;
424 args.justcheck = args.addname = 0;
425 args.oknoent = 1;
426
427 /*
428 * Decide on what work routines to call based on the inode size.
429 */
430 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
431 retval = xfs_dir_shortform_lookup(&args);
432 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
433 retval = xfs_dir_leaf_lookup(&args);
434 } else {
435 retval = xfs_dir_node_lookup(&args);
436 }
437 if (retval == EEXIST)
438 retval = 0;
439 *inum = args.inumber;
440 return(retval);
441}
442
443/*
444 * Implement readdir.
445 */
446static int /* error */
447xfs_dir_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, int *eofp)
448{
449 xfs_dirent_t *dbp;
450 int alignment, retval;
451 xfs_dir_put_t put;
452
453 XFS_STATS_INC(xs_dir_getdents);
454 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
455
456 /*
457 * If our caller has given us a single contiguous memory buffer,
458 * just work directly within that buffer. If it's in user memory,
459 * lock it down first.
460 */
461 alignment = sizeof(xfs_off_t) - 1;
462 if ((uio->uio_iovcnt == 1) &&
463 (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) &&
464 ((uio->uio_iov[0].iov_len & alignment) == 0)) {
465 dbp = NULL;
466 put = xfs_dir_put_dirent64_direct;
467 } else {
468 dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP);
469 put = xfs_dir_put_dirent64_uio;
470 }
471
472 /*
473 * Decide on what work routines to call based on the inode size.
474 */
475 *eofp = 0;
476
477 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
478 retval = xfs_dir_shortform_getdents(dp, uio, eofp, dbp, put);
479 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
480 retval = xfs_dir_leaf_getdents(trans, dp, uio, eofp, dbp, put);
481 } else {
482 retval = xfs_dir_node_getdents(trans, dp, uio, eofp, dbp, put);
483 }
484 if (dbp != NULL)
485 kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN);
486
487 return(retval);
488}
489
490static int /* error */
491xfs_dir_replace(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen,
492 xfs_ino_t inum, xfs_fsblock_t *firstblock,
493 xfs_bmap_free_t *flist, xfs_extlen_t total)
494{
495 xfs_da_args_t args;
496 int retval;
497
498 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
499
500 if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
501 return retval;
502
503 /*
504 * Fill in the arg structure for this request.
505 */
506 args.name = name;
507 args.namelen = namelen;
508 args.hashval = xfs_da_hashname(name, namelen);
509 args.inumber = inum;
510 args.dp = dp;
511 args.firstblock = firstblock;
512 args.flist = flist;
513 args.total = total;
514 args.whichfork = XFS_DATA_FORK;
515 args.trans = trans;
516 args.justcheck = args.addname = args.oknoent = 0;
517
518 /*
519 * Decide on what work routines to call based on the inode size.
520 */
521 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
522 retval = xfs_dir_shortform_replace(&args);
523 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
524 retval = xfs_dir_leaf_replace(&args);
525 } else {
526 retval = xfs_dir_node_replace(&args);
527 }
528
529 return(retval);
530}
531
532static int
533xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp, xfs_dinode_t *dp)
534{
535 xfs_ino_t ino;
536 int namelen_sum;
537 int count;
538 xfs_dir_shortform_t *sf;
539 xfs_dir_sf_entry_t *sfe;
540 int i;
541
542
543
544 if ((INT_GET(dp->di_core.di_mode, ARCH_CONVERT) & S_IFMT) != S_IFDIR) {
545 return 0;
546 }
547 if (INT_GET(dp->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_LOCAL) {
548 return 0;
549 }
550 if (INT_GET(dp->di_core.di_size, ARCH_CONVERT) < sizeof(sf->hdr)) {
551 xfs_fs_cmn_err(CE_WARN, mp, "Invalid shortform size: dp 0x%p",
552 dp);
553 return 1;
554 }
555 sf = (xfs_dir_shortform_t *)(&dp->di_u.di_dirsf);
556 ino = XFS_GET_DIR_INO8(sf->hdr.parent);
557 if (xfs_dir_ino_validate(mp, ino))
558 return 1;
559
560 count = sf->hdr.count;
561 if ((count < 0) || ((count * 10) > XFS_LITINO(mp))) {
562 xfs_fs_cmn_err(CE_WARN, mp,
563 "Invalid shortform count: dp 0x%p", dp);
564 return(1);
565 }
566
567 if (count == 0) {
568 return 0;
569 }
570
571 namelen_sum = 0;
572 sfe = &sf->list[0];
573 for (i = sf->hdr.count - 1; i >= 0; i--) {
574 ino = XFS_GET_DIR_INO8(sfe->inumber);
575 xfs_dir_ino_validate(mp, ino);
576 if (sfe->namelen >= XFS_LITINO(mp)) {
577 xfs_fs_cmn_err(CE_WARN, mp,
578 "Invalid shortform namelen: dp 0x%p", dp);
579 return 1;
580 }
581 namelen_sum += sfe->namelen;
582 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
583 }
584 if (namelen_sum >= XFS_LITINO(mp)) {
585 xfs_fs_cmn_err(CE_WARN, mp,
586 "Invalid shortform namelen: dp 0x%p", dp);
587 return 1;
588 }
589
590 return 0;
591}
592
593/*========================================================================
594 * External routines when dirsize == XFS_LBSIZE(dp->i_mount).
595 *========================================================================*/
596
597/*
598 * Add a name to the leaf directory structure
599 * This is the external routine.
600 */
601int
602xfs_dir_leaf_addname(xfs_da_args_t *args)
603{
604 int index, retval;
605 xfs_dabuf_t *bp;
606
607 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
608 XFS_DATA_FORK);
609 if (retval)
610 return(retval);
611 ASSERT(bp != NULL);
612
613 retval = xfs_dir_leaf_lookup_int(bp, args, &index);
614 if (retval == ENOENT)
615 retval = xfs_dir_leaf_add(bp, args, index);
616 xfs_da_buf_done(bp);
617 return(retval);
618}
619
620/*
621 * Remove a name from the leaf directory structure
622 * This is the external routine.
623 */
624STATIC int
625xfs_dir_leaf_removename(xfs_da_args_t *args, int *count, int *totallen)
626{
627 xfs_dir_leafblock_t *leaf;
628 int index, retval;
629 xfs_dabuf_t *bp;
630
631 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
632 XFS_DATA_FORK);
633 if (retval)
634 return(retval);
635 ASSERT(bp != NULL);
636 leaf = bp->data;
637 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
638 retval = xfs_dir_leaf_lookup_int(bp, args, &index);
639 if (retval == EEXIST) {
640 (void)xfs_dir_leaf_remove(args->trans, bp, index);
641 *count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
642 *totallen = INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
643 retval = 0;
644 }
645 xfs_da_buf_done(bp);
646 return(retval);
647}
648
649/*
650 * Look up a name in a leaf directory structure.
651 * This is the external routine.
652 */
653STATIC int
654xfs_dir_leaf_lookup(xfs_da_args_t *args)
655{
656 int index, retval;
657 xfs_dabuf_t *bp;
658
659 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
660 XFS_DATA_FORK);
661 if (retval)
662 return(retval);
663 ASSERT(bp != NULL);
664 retval = xfs_dir_leaf_lookup_int(bp, args, &index);
665 xfs_da_brelse(args->trans, bp);
666 return(retval);
667}
668
669/*
670 * Copy out directory entries for getdents(), for leaf directories.
671 */
672STATIC int
673xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
674 int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put)
675{
676 xfs_dabuf_t *bp;
677 int retval, eob;
678
679 retval = xfs_da_read_buf(dp->i_transp, dp, 0, -1, &bp, XFS_DATA_FORK);
680 if (retval)
681 return(retval);
682 ASSERT(bp != NULL);
683 retval = xfs_dir_leaf_getdents_int(bp, dp, 0, uio, &eob, dbp, put, -1);
684 xfs_da_brelse(trans, bp);
685 *eofp = (eob == 0);
686 return(retval);
687}
688
689/*
690 * Look up a name in a leaf directory structure, replace the inode number.
691 * This is the external routine.
692 */
693STATIC int
694xfs_dir_leaf_replace(xfs_da_args_t *args)
695{
696 int index, retval;
697 xfs_dabuf_t *bp;
698 xfs_ino_t inum;
699 xfs_dir_leafblock_t *leaf;
700 xfs_dir_leaf_entry_t *entry;
701 xfs_dir_leaf_name_t *namest;
702
703 inum = args->inumber;
704 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
705 XFS_DATA_FORK);
706 if (retval)
707 return(retval);
708 ASSERT(bp != NULL);
709 retval = xfs_dir_leaf_lookup_int(bp, args, &index);
710 if (retval == EEXIST) {
711 leaf = bp->data;
712 entry = &leaf->entries[index];
713 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
714 /* XXX - replace assert? */
715 XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber);
716 xfs_da_log_buf(args->trans, bp,
717 XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber)));
718 xfs_da_buf_done(bp);
719 retval = 0;
720 } else
721 xfs_da_brelse(args->trans, bp);
722 return(retval);
723}
724
725
726/*========================================================================
727 * External routines when dirsize > XFS_LBSIZE(mp).
728 *========================================================================*/
729
730/*
731 * Add a name to a Btree-format directory.
732 *
733 * This will involve walking down the Btree, and may involve splitting
734 * leaf nodes and even splitting intermediate nodes up to and including
735 * the root node (a special case of an intermediate node).
736 */
737STATIC int
738xfs_dir_node_addname(xfs_da_args_t *args)
739{
740 xfs_da_state_t *state;
741 xfs_da_state_blk_t *blk;
742 int retval, error;
743
744 /*
745 * Fill in bucket of arguments/results/context to carry around.
746 */
747 state = xfs_da_state_alloc();
748 state->args = args;
749 state->mp = args->dp->i_mount;
750 state->blocksize = state->mp->m_sb.sb_blocksize;
751 state->node_ents = state->mp->m_dir_node_ents;
752
753 /*
754 * Search to see if name already exists, and get back a pointer
755 * to where it should go.
756 */
757 error = xfs_da_node_lookup_int(state, &retval);
758 if (error)
759 retval = error;
760 if (retval != ENOENT)
761 goto error;
762 blk = &state->path.blk[ state->path.active-1 ];
763 ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
764 retval = xfs_dir_leaf_add(blk->bp, args, blk->index);
765 if (retval == 0) {
766 /*
767 * Addition succeeded, update Btree hashvals.
768 */
769 if (!args->justcheck)
770 xfs_da_fixhashpath(state, &state->path);
771 } else {
772 /*
773 * Addition failed, split as many Btree elements as required.
774 */
775 if (args->total == 0) {
776 ASSERT(retval == ENOSPC);
777 goto error;
778 }
779 retval = xfs_da_split(state);
780 }
781error:
782 xfs_da_state_free(state);
783
784 return(retval);
785}
786
787/*
788 * Remove a name from a B-tree directory.
789 *
790 * This will involve walking down the Btree, and may involve joining
791 * leaf nodes and even joining intermediate nodes up to and including
792 * the root node (a special case of an intermediate node).
793 */
794STATIC int
795xfs_dir_node_removename(xfs_da_args_t *args)
796{
797 xfs_da_state_t *state;
798 xfs_da_state_blk_t *blk;
799 int retval, error;
800
801 state = xfs_da_state_alloc();
802 state->args = args;
803 state->mp = args->dp->i_mount;
804 state->blocksize = state->mp->m_sb.sb_blocksize;
805 state->node_ents = state->mp->m_dir_node_ents;
806
807 /*
808 * Search to see if name exists, and get back a pointer to it.
809 */
810 error = xfs_da_node_lookup_int(state, &retval);
811 if (error)
812 retval = error;
813 if (retval != EEXIST) {
814 xfs_da_state_free(state);
815 return(retval);
816 }
817
818 /*
819 * Remove the name and update the hashvals in the tree.
820 */
821 blk = &state->path.blk[ state->path.active-1 ];
822 ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
823 retval = xfs_dir_leaf_remove(args->trans, blk->bp, blk->index);
824 xfs_da_fixhashpath(state, &state->path);
825
826 /*
827 * Check to see if the tree needs to be collapsed.
828 */
829 error = 0;
830 if (retval) {
831 error = xfs_da_join(state);
832 }
833
834 xfs_da_state_free(state);
835 if (error)
836 return(error);
837 return(0);
838}
839
840/*
841 * Look up a filename in a int directory.
842 * Use an internal routine to actually do all the work.
843 */
844STATIC int
845xfs_dir_node_lookup(xfs_da_args_t *args)
846{
847 xfs_da_state_t *state;
848 int retval, error, i;
849
850 state = xfs_da_state_alloc();
851 state->args = args;
852 state->mp = args->dp->i_mount;
853 state->blocksize = state->mp->m_sb.sb_blocksize;
854 state->node_ents = state->mp->m_dir_node_ents;
855
856 /*
857 * Search to see if name exists,
858 * and get back a pointer to it.
859 */
860 error = xfs_da_node_lookup_int(state, &retval);
861 if (error) {
862 retval = error;
863 }
864
865 /*
866 * If not in a transaction, we have to release all the buffers.
867 */
868 for (i = 0; i < state->path.active; i++) {
869 xfs_da_brelse(args->trans, state->path.blk[i].bp);
870 state->path.blk[i].bp = NULL;
871 }
872
873 xfs_da_state_free(state);
874 return(retval);
875}
876
877STATIC int
878xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
879 int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put)
880{
881 xfs_da_intnode_t *node;
882 xfs_da_node_entry_t *btree;
883 xfs_dir_leafblock_t *leaf = NULL;
884 xfs_dablk_t bno, nextbno;
885 xfs_dahash_t cookhash;
886 xfs_mount_t *mp;
887 int error, eob, i;
888 xfs_dabuf_t *bp;
889 xfs_daddr_t nextda;
890
891 /*
892 * Pick up our context.
893 */
894 mp = dp->i_mount;
895 bp = NULL;
896 bno = XFS_DA_COOKIE_BNO(mp, uio->uio_offset);
897 cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);
898
899 xfs_dir_trace_g_du("node: start", dp, uio);
900
901 /*
902 * Re-find our place, even if we're confused about what our place is.
903 *
904 * First we check the block number from the magic cookie, it is a
905 * cache of where we ended last time. If we find a leaf block, and
906 * the starting hashval in that block is less than our desired
907 * hashval, then we run with it.
908 */
909 if (bno > 0) {
910 error = xfs_da_read_buf(trans, dp, bno, -2, &bp, XFS_DATA_FORK);
911 if ((error != 0) && (error != EFSCORRUPTED))
912 return(error);
913 if (bp)
914 leaf = bp->data;
915 if (bp && be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) {
916 xfs_dir_trace_g_dub("node: block not a leaf",
917 dp, uio, bno);
918 xfs_da_brelse(trans, bp);
919 bp = NULL;
920 }
921 if (bp && INT_GET(leaf->entries[0].hashval, ARCH_CONVERT) > cookhash) {
922 xfs_dir_trace_g_dub("node: leaf hash too large",
923 dp, uio, bno);
924 xfs_da_brelse(trans, bp);
925 bp = NULL;
926 }
927 if (bp &&
928 cookhash > INT_GET(leaf->entries[INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT)) {
929 xfs_dir_trace_g_dub("node: leaf hash too small",
930 dp, uio, bno);
931 xfs_da_brelse(trans, bp);
932 bp = NULL;
933 }
934 }
935
936 /*
937 * If we did not find a leaf block from the blockno in the cookie,
938 * or we there was no blockno in the cookie (eg: first time thru),
939 * the we start at the top of the Btree and re-find our hashval.
940 */
941 if (bp == NULL) {
942 xfs_dir_trace_g_du("node: start at root" , dp, uio);
943 bno = 0;
944 for (;;) {
945 error = xfs_da_read_buf(trans, dp, bno, -1, &bp,
946 XFS_DATA_FORK);
947 if (error)
948 return(error);
949 if (bp == NULL)
950 return(XFS_ERROR(EFSCORRUPTED));
951 node = bp->data;
952 if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC)
953 break;
954 btree = &node->btree[0];
955 xfs_dir_trace_g_dun("node: node detail", dp, uio, node);
956 for (i = 0; i < be16_to_cpu(node->hdr.count); btree++, i++) {
957 if (be32_to_cpu(btree->hashval) >= cookhash) {
958 bno = be32_to_cpu(btree->before);
959 break;
960 }
961 }
962 if (i == be16_to_cpu(node->hdr.count)) {
963 xfs_da_brelse(trans, bp);
964 xfs_dir_trace_g_du("node: hash beyond EOF",
965 dp, uio);
966 uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0,
967 XFS_DA_MAXHASH);
968 *eofp = 1;
969 return(0);
970 }
971 xfs_dir_trace_g_dub("node: going to block",
972 dp, uio, bno);
973 xfs_da_brelse(trans, bp);
974 }
975 }
976 ASSERT(cookhash != XFS_DA_MAXHASH);
977
978 /*
979 * We've dropped down to the (first) leaf block that contains the
980 * hashval we are interested in. Continue rolling upward thru the
981 * leaf blocks until we fill up our buffer.
982 */
983 for (;;) {
984 leaf = bp->data;
985 if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC)) {
986 xfs_dir_trace_g_dul("node: not a leaf", dp, uio, leaf);
987 xfs_da_brelse(trans, bp);
988 XFS_CORRUPTION_ERROR("xfs_dir_node_getdents(1)",
989 XFS_ERRLEVEL_LOW, mp, leaf);
990 return XFS_ERROR(EFSCORRUPTED);
991 }
992 xfs_dir_trace_g_dul("node: leaf detail", dp, uio, leaf);
993 if ((nextbno = be32_to_cpu(leaf->hdr.info.forw))) {
994 nextda = xfs_da_reada_buf(trans, dp, nextbno,
995 XFS_DATA_FORK);
996 } else
997 nextda = -1;
998 error = xfs_dir_leaf_getdents_int(bp, dp, bno, uio, &eob, dbp,
999 put, nextda);
1000 xfs_da_brelse(trans, bp);
1001 bno = nextbno;
1002 if (eob) {
1003 xfs_dir_trace_g_dub("node: E-O-B", dp, uio, bno);
1004 *eofp = 0;
1005 return(error);
1006 }
1007 if (bno == 0)
1008 break;
1009 error = xfs_da_read_buf(trans, dp, bno, nextda, &bp,
1010 XFS_DATA_FORK);
1011 if (error)
1012 return(error);
1013 if (unlikely(bp == NULL)) {
1014 XFS_ERROR_REPORT("xfs_dir_node_getdents(2)",
1015 XFS_ERRLEVEL_LOW, mp);
1016 return(XFS_ERROR(EFSCORRUPTED));
1017 }
1018 }
1019 *eofp = 1;
1020 xfs_dir_trace_g_du("node: E-O-F", dp, uio);
1021 return(0);
1022}
1023
1024/*
1025 * Look up a filename in an int directory, replace the inode number.
1026 * Use an internal routine to actually do the lookup.
1027 */
1028STATIC int
1029xfs_dir_node_replace(xfs_da_args_t *args)
1030{
1031 xfs_da_state_t *state;
1032 xfs_da_state_blk_t *blk;
1033 xfs_dir_leafblock_t *leaf;
1034 xfs_dir_leaf_entry_t *entry;
1035 xfs_dir_leaf_name_t *namest;
1036 xfs_ino_t inum;
1037 int retval, error, i;
1038 xfs_dabuf_t *bp;
1039
1040 state = xfs_da_state_alloc();
1041 state->args = args;
1042 state->mp = args->dp->i_mount;
1043 state->blocksize = state->mp->m_sb.sb_blocksize;
1044 state->node_ents = state->mp->m_dir_node_ents;
1045 inum = args->inumber;
1046
1047 /*
1048 * Search to see if name exists,
1049 * and get back a pointer to it.
1050 */
1051 error = xfs_da_node_lookup_int(state, &retval);
1052 if (error) {
1053 retval = error;
1054 }
1055
1056 if (retval == EEXIST) {
1057 blk = &state->path.blk[state->path.active - 1];
1058 ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
1059 bp = blk->bp;
1060 leaf = bp->data;
1061 entry = &leaf->entries[blk->index];
1062 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
1063 /* XXX - replace assert ? */
1064 XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber);
1065 xfs_da_log_buf(args->trans, bp,
1066 XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber)));
1067 xfs_da_buf_done(bp);
1068 blk->bp = NULL;
1069 retval = 0;
1070 } else {
1071 i = state->path.active - 1;
1072 xfs_da_brelse(args->trans, state->path.blk[i].bp);
1073 state->path.blk[i].bp = NULL;
1074 }
1075 for (i = 0; i < state->path.active - 1; i++) {
1076 xfs_da_brelse(args->trans, state->path.blk[i].bp);
1077 state->path.blk[i].bp = NULL;
1078 }
1079
1080 xfs_da_state_free(state);
1081 return(retval);
1082}
1083
1084#if defined(XFS_DIR_TRACE)
1085/*
1086 * Add a trace buffer entry for an inode and a uio.
1087 */
1088void
1089xfs_dir_trace_g_du(char *where, xfs_inode_t *dp, uio_t *uio)
1090{
1091 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DU, where,
1092 (void *)dp, (void *)dp->i_mount,
1093 (void *)((unsigned long)(uio->uio_offset >> 32)),
1094 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1095 (void *)(unsigned long)uio->uio_resid,
1096 NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1097}
1098
1099/*
1100 * Add a trace buffer entry for an inode and a uio.
1101 */
1102void
1103xfs_dir_trace_g_dub(char *where, xfs_inode_t *dp, uio_t *uio, xfs_dablk_t bno)
1104{
1105 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUB, where,
1106 (void *)dp, (void *)dp->i_mount,
1107 (void *)((unsigned long)(uio->uio_offset >> 32)),
1108 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1109 (void *)(unsigned long)uio->uio_resid,
1110 (void *)(unsigned long)bno,
1111 NULL, NULL, NULL, NULL, NULL, NULL);
1112}
1113
1114/*
1115 * Add a trace buffer entry for an inode and a uio.
1116 */
1117void
1118xfs_dir_trace_g_dun(char *where, xfs_inode_t *dp, uio_t *uio,
1119 xfs_da_intnode_t *node)
1120{
1121 int last = be16_to_cpu(node->hdr.count) - 1;
1122
1123 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUN, where,
1124 (void *)dp, (void *)dp->i_mount,
1125 (void *)((unsigned long)(uio->uio_offset >> 32)),
1126 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1127 (void *)(unsigned long)uio->uio_resid,
1128 (void *)(unsigned long)be32_to_cpu(node->hdr.info.forw),
1129 (void *)(unsigned long)
1130 be16_to_cpu(node->hdr.count),
1131 (void *)(unsigned long)
1132 be32_to_cpu(node->btree[0].hashval),
1133 (void *)(unsigned long)
1134 be32_to_cpu(node->btree[last].hashval),
1135 NULL, NULL, NULL);
1136}
1137
1138/*
1139 * Add a trace buffer entry for an inode and a uio.
1140 */
1141void
1142xfs_dir_trace_g_dul(char *where, xfs_inode_t *dp, uio_t *uio,
1143 xfs_dir_leafblock_t *leaf)
1144{
1145 int last = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1;
1146
1147 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUL, where,
1148 (void *)dp, (void *)dp->i_mount,
1149 (void *)((unsigned long)(uio->uio_offset >> 32)),
1150 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1151 (void *)(unsigned long)uio->uio_resid,
1152 (void *)(unsigned long)be32_to_cpu(leaf->hdr.info.forw),
1153 (void *)(unsigned long)
1154 INT_GET(leaf->hdr.count, ARCH_CONVERT),
1155 (void *)(unsigned long)
1156 INT_GET(leaf->entries[0].hashval, ARCH_CONVERT),
1157 (void *)(unsigned long)
1158 INT_GET(leaf->entries[last].hashval, ARCH_CONVERT),
1159 NULL, NULL, NULL);
1160}
1161
1162/*
1163 * Add a trace buffer entry for an inode and a uio.
1164 */
1165void
1166xfs_dir_trace_g_due(char *where, xfs_inode_t *dp, uio_t *uio,
1167 xfs_dir_leaf_entry_t *entry)
1168{
1169 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUE, where,
1170 (void *)dp, (void *)dp->i_mount,
1171 (void *)((unsigned long)(uio->uio_offset >> 32)),
1172 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1173 (void *)(unsigned long)uio->uio_resid,
1174 (void *)(unsigned long)
1175 INT_GET(entry->hashval, ARCH_CONVERT),
1176 NULL, NULL, NULL, NULL, NULL, NULL);
1177}
1178
1179/*
1180 * Add a trace buffer entry for an inode and a uio.
1181 */
1182void
1183xfs_dir_trace_g_duc(char *where, xfs_inode_t *dp, uio_t *uio, xfs_off_t cookie)
1184{
1185 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUC, where,
1186 (void *)dp, (void *)dp->i_mount,
1187 (void *)((unsigned long)(uio->uio_offset >> 32)),
1188 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1189 (void *)(unsigned long)uio->uio_resid,
1190 (void *)((unsigned long)(cookie >> 32)),
1191 (void *)((unsigned long)(cookie & 0xFFFFFFFF)),
1192 NULL, NULL, NULL, NULL, NULL);
1193}
1194
1195/*
1196 * Add a trace buffer entry for the arguments given to the routine,
1197 * generic form.
1198 */
1199void
1200xfs_dir_trace_enter(int type, char *where,
1201 void * a0, void * a1,
1202 void * a2, void * a3,
1203 void * a4, void * a5,
1204 void * a6, void * a7,
1205 void * a8, void * a9,
1206 void * a10, void * a11)
1207{
1208 ASSERT(xfs_dir_trace_buf);
1209 ktrace_enter(xfs_dir_trace_buf, (void *)(unsigned long)type,
1210 (void *)where,
1211 (void *)a0, (void *)a1, (void *)a2,
1212 (void *)a3, (void *)a4, (void *)a5,
1213 (void *)a6, (void *)a7, (void *)a8,
1214 (void *)a9, (void *)a10, (void *)a11,
1215 NULL, NULL);
1216}
1217#endif /* XFS_DIR_TRACE */
diff --git a/fs/xfs/xfs_dir.h b/fs/xfs/xfs_dir.h
deleted file mode 100644
index 8cc8afb9f6c0..000000000000
--- a/fs/xfs/xfs_dir.h
+++ /dev/null
@@ -1,142 +0,0 @@
1/*
2 * Copyright (c) 2000,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR_H__
19#define __XFS_DIR_H__
20
21/*
22 * Large directories are structured around Btrees where all the data
23 * elements are in the leaf nodes. Filenames are hashed into an int,
24 * then that int is used as the index into the Btree. Since the hashval
25 * of a filename may not be unique, we may have duplicate keys. The
26 * internal links in the Btree are logical block offsets into the file.
27 *
28 * Small directories use a different format and are packed as tightly
29 * as possible so as to fit into the literal area of the inode.
30 */
31
32/*========================================================================
33 * Function prototypes for the kernel.
34 *========================================================================*/
35
36struct uio;
37struct xfs_bmap_free;
38struct xfs_da_args;
39struct xfs_dinode;
40struct xfs_inode;
41struct xfs_mount;
42struct xfs_trans;
43
44/*
45 * Directory function types.
46 * Put in structures (xfs_dirops_t) for v1 and v2 directories.
47 */
48typedef void (*xfs_dir_mount_t)(struct xfs_mount *mp);
49typedef int (*xfs_dir_isempty_t)(struct xfs_inode *dp);
50typedef int (*xfs_dir_init_t)(struct xfs_trans *tp,
51 struct xfs_inode *dp,
52 struct xfs_inode *pdp);
53typedef int (*xfs_dir_createname_t)(struct xfs_trans *tp,
54 struct xfs_inode *dp,
55 char *name,
56 int namelen,
57 xfs_ino_t inum,
58 xfs_fsblock_t *first,
59 struct xfs_bmap_free *flist,
60 xfs_extlen_t total);
61typedef int (*xfs_dir_lookup_t)(struct xfs_trans *tp,
62 struct xfs_inode *dp,
63 char *name,
64 int namelen,
65 xfs_ino_t *inum);
66typedef int (*xfs_dir_removename_t)(struct xfs_trans *tp,
67 struct xfs_inode *dp,
68 char *name,
69 int namelen,
70 xfs_ino_t ino,
71 xfs_fsblock_t *first,
72 struct xfs_bmap_free *flist,
73 xfs_extlen_t total);
74typedef int (*xfs_dir_getdents_t)(struct xfs_trans *tp,
75 struct xfs_inode *dp,
76 struct uio *uio,
77 int *eofp);
78typedef int (*xfs_dir_replace_t)(struct xfs_trans *tp,
79 struct xfs_inode *dp,
80 char *name,
81 int namelen,
82 xfs_ino_t inum,
83 xfs_fsblock_t *first,
84 struct xfs_bmap_free *flist,
85 xfs_extlen_t total);
86typedef int (*xfs_dir_canenter_t)(struct xfs_trans *tp,
87 struct xfs_inode *dp,
88 char *name,
89 int namelen);
90typedef int (*xfs_dir_shortform_validate_ondisk_t)(struct xfs_mount *mp,
91 struct xfs_dinode *dip);
92typedef int (*xfs_dir_shortform_to_single_t)(struct xfs_da_args *args);
93
94typedef struct xfs_dirops {
95 xfs_dir_mount_t xd_mount;
96 xfs_dir_isempty_t xd_isempty;
97 xfs_dir_init_t xd_init;
98 xfs_dir_createname_t xd_createname;
99 xfs_dir_lookup_t xd_lookup;
100 xfs_dir_removename_t xd_removename;
101 xfs_dir_getdents_t xd_getdents;
102 xfs_dir_replace_t xd_replace;
103 xfs_dir_canenter_t xd_canenter;
104 xfs_dir_shortform_validate_ondisk_t xd_shortform_validate_ondisk;
105 xfs_dir_shortform_to_single_t xd_shortform_to_single;
106} xfs_dirops_t;
107
108/*
109 * Overall external interface routines.
110 */
111void xfs_dir_startup(void); /* called exactly once */
112
113#define XFS_DIR_MOUNT(mp) \
114 ((mp)->m_dirops.xd_mount(mp))
115#define XFS_DIR_ISEMPTY(mp,dp) \
116 ((mp)->m_dirops.xd_isempty(dp))
117#define XFS_DIR_INIT(mp,tp,dp,pdp) \
118 ((mp)->m_dirops.xd_init(tp,dp,pdp))
119#define XFS_DIR_CREATENAME(mp,tp,dp,name,namelen,inum,first,flist,total) \
120 ((mp)->m_dirops.xd_createname(tp,dp,name,namelen,inum,first,flist,\
121 total))
122#define XFS_DIR_LOOKUP(mp,tp,dp,name,namelen,inum) \
123 ((mp)->m_dirops.xd_lookup(tp,dp,name,namelen,inum))
124#define XFS_DIR_REMOVENAME(mp,tp,dp,name,namelen,ino,first,flist,total) \
125 ((mp)->m_dirops.xd_removename(tp,dp,name,namelen,ino,first,flist,total))
126#define XFS_DIR_GETDENTS(mp,tp,dp,uio,eofp) \
127 ((mp)->m_dirops.xd_getdents(tp,dp,uio,eofp))
128#define XFS_DIR_REPLACE(mp,tp,dp,name,namelen,inum,first,flist,total) \
129 ((mp)->m_dirops.xd_replace(tp,dp,name,namelen,inum,first,flist,total))
130#define XFS_DIR_CANENTER(mp,tp,dp,name,namelen) \
131 ((mp)->m_dirops.xd_canenter(tp,dp,name,namelen))
132#define XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp,dip) \
133 ((mp)->m_dirops.xd_shortform_validate_ondisk(mp,dip))
134#define XFS_DIR_SHORTFORM_TO_SINGLE(mp,args) \
135 ((mp)->m_dirops.xd_shortform_to_single(args))
136
137#define XFS_DIR_IS_V1(mp) ((mp)->m_dirversion == 1)
138#define XFS_DIR_IS_V2(mp) ((mp)->m_dirversion == 2)
139extern xfs_dirops_t xfsv1_dirops;
140extern xfs_dirops_t xfsv2_dirops;
141
142#endif /* __XFS_DIR_H__ */
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 022c8398ab62..8edbe1adb95b 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -24,21 +24,18 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_da_btree.h" 30#include "xfs_da_btree.h"
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
38#include "xfs_inode.h" 36#include "xfs_inode.h"
39#include "xfs_inode_item.h" 37#include "xfs_inode_item.h"
40#include "xfs_bmap.h" 38#include "xfs_bmap.h"
41#include "xfs_dir_leaf.h"
42#include "xfs_dir2_data.h" 39#include "xfs_dir2_data.h"
43#include "xfs_dir2_leaf.h" 40#include "xfs_dir2_leaf.h"
44#include "xfs_dir2_block.h" 41#include "xfs_dir2_block.h"
@@ -46,69 +43,14 @@
46#include "xfs_dir2_trace.h" 43#include "xfs_dir2_trace.h"
47#include "xfs_error.h" 44#include "xfs_error.h"
48 45
49/*
50 * Declarations for interface routines.
51 */
52static void xfs_dir2_mount(xfs_mount_t *mp);
53static int xfs_dir2_isempty(xfs_inode_t *dp);
54static int xfs_dir2_init(xfs_trans_t *tp, xfs_inode_t *dp,
55 xfs_inode_t *pdp);
56static int xfs_dir2_createname(xfs_trans_t *tp, xfs_inode_t *dp,
57 char *name, int namelen, xfs_ino_t inum,
58 xfs_fsblock_t *first,
59 xfs_bmap_free_t *flist, xfs_extlen_t total);
60static int xfs_dir2_lookup(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
61 int namelen, xfs_ino_t *inum);
62static int xfs_dir2_removename(xfs_trans_t *tp, xfs_inode_t *dp,
63 char *name, int namelen, xfs_ino_t ino,
64 xfs_fsblock_t *first,
65 xfs_bmap_free_t *flist, xfs_extlen_t total);
66static int xfs_dir2_getdents(xfs_trans_t *tp, xfs_inode_t *dp, uio_t *uio,
67 int *eofp);
68static int xfs_dir2_replace(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
69 int namelen, xfs_ino_t inum,
70 xfs_fsblock_t *first, xfs_bmap_free_t *flist,
71 xfs_extlen_t total);
72static int xfs_dir2_canenter(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
73 int namelen);
74static int xfs_dir2_shortform_validate_ondisk(xfs_mount_t *mp,
75 xfs_dinode_t *dip);
76
77/*
78 * Utility routine declarations.
79 */
80static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa); 46static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa);
81static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa); 47static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa);
82 48
83/* 49void
84 * Directory operations vector. 50xfs_dir_mount(
85 */ 51 xfs_mount_t *mp)
86xfs_dirops_t xfsv2_dirops = {
87 .xd_mount = xfs_dir2_mount,
88 .xd_isempty = xfs_dir2_isempty,
89 .xd_init = xfs_dir2_init,
90 .xd_createname = xfs_dir2_createname,
91 .xd_lookup = xfs_dir2_lookup,
92 .xd_removename = xfs_dir2_removename,
93 .xd_getdents = xfs_dir2_getdents,
94 .xd_replace = xfs_dir2_replace,
95 .xd_canenter = xfs_dir2_canenter,
96 .xd_shortform_validate_ondisk = xfs_dir2_shortform_validate_ondisk,
97 .xd_shortform_to_single = xfs_dir2_sf_to_block,
98};
99
100/*
101 * Interface routines.
102 */
103
104/*
105 * Initialize directory-related fields in the mount structure.
106 */
107static void
108xfs_dir2_mount(
109 xfs_mount_t *mp) /* filesystem mount point */
110{ 52{
111 mp->m_dirversion = 2; 53 ASSERT(XFS_SB_VERSION_HASDIRV2(&mp->m_sb));
112 ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= 54 ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <=
113 XFS_MAX_BLOCKSIZE); 55 XFS_MAX_BLOCKSIZE);
114 mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); 56 mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog);
@@ -128,19 +70,15 @@ xfs_dir2_mount(
128/* 70/*
129 * Return 1 if directory contains only "." and "..". 71 * Return 1 if directory contains only "." and "..".
130 */ 72 */
131static int /* return code */ 73int
132xfs_dir2_isempty( 74xfs_dir_isempty(
133 xfs_inode_t *dp) /* incore inode structure */ 75 xfs_inode_t *dp)
134{ 76{
135 xfs_dir2_sf_t *sfp; /* shortform directory structure */ 77 xfs_dir2_sf_t *sfp;
136 78
137 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 79 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
138 /* 80 if (dp->i_d.di_size == 0) /* might happen during shutdown. */
139 * Might happen during shutdown.
140 */
141 if (dp->i_d.di_size == 0) {
142 return 1; 81 return 1;
143 }
144 if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) 82 if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
145 return 0; 83 return 0;
146 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 84 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
@@ -148,53 +86,83 @@ xfs_dir2_isempty(
148} 86}
149 87
150/* 88/*
89 * Validate a given inode number.
90 */
91int
92xfs_dir_ino_validate(
93 xfs_mount_t *mp,
94 xfs_ino_t ino)
95{
96 xfs_agblock_t agblkno;
97 xfs_agino_t agino;
98 xfs_agnumber_t agno;
99 int ino_ok;
100 int ioff;
101
102 agno = XFS_INO_TO_AGNO(mp, ino);
103 agblkno = XFS_INO_TO_AGBNO(mp, ino);
104 ioff = XFS_INO_TO_OFFSET(mp, ino);
105 agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff);
106 ino_ok =
107 agno < mp->m_sb.sb_agcount &&
108 agblkno < mp->m_sb.sb_agblocks &&
109 agblkno != 0 &&
110 ioff < (1 << mp->m_sb.sb_inopblog) &&
111 XFS_AGINO_TO_INO(mp, agno, agino) == ino;
112 if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,
113 XFS_RANDOM_DIR_INO_VALIDATE))) {
114 xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx",
115 (unsigned long long) ino);
116 XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp);
117 return XFS_ERROR(EFSCORRUPTED);
118 }
119 return 0;
120}
121
122/*
151 * Initialize a directory with its "." and ".." entries. 123 * Initialize a directory with its "." and ".." entries.
152 */ 124 */
153static int /* error */ 125int
154xfs_dir2_init( 126xfs_dir_init(
155 xfs_trans_t *tp, /* transaction pointer */ 127 xfs_trans_t *tp,
156 xfs_inode_t *dp, /* incore directory inode */ 128 xfs_inode_t *dp,
157 xfs_inode_t *pdp) /* incore parent directory inode */ 129 xfs_inode_t *pdp)
158{ 130{
159 xfs_da_args_t args; /* operation arguments */ 131 xfs_da_args_t args;
160 int error; /* error return value */ 132 int error;
161 133
162 memset((char *)&args, 0, sizeof(args)); 134 memset((char *)&args, 0, sizeof(args));
163 args.dp = dp; 135 args.dp = dp;
164 args.trans = tp; 136 args.trans = tp;
165 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 137 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
166 if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) { 138 if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino)))
167 return error; 139 return error;
168 }
169 return xfs_dir2_sf_create(&args, pdp->i_ino); 140 return xfs_dir2_sf_create(&args, pdp->i_ino);
170} 141}
171 142
172/* 143/*
173 Enter a name in a directory. 144 Enter a name in a directory.
174 */ 145 */
175static int /* error */ 146int
176xfs_dir2_createname( 147xfs_dir_createname(
177 xfs_trans_t *tp, /* transaction pointer */ 148 xfs_trans_t *tp,
178 xfs_inode_t *dp, /* incore directory inode */ 149 xfs_inode_t *dp,
179 char *name, /* new entry name */ 150 char *name,
180 int namelen, /* new entry name length */ 151 int namelen,
181 xfs_ino_t inum, /* new entry inode number */ 152 xfs_ino_t inum, /* new entry inode number */
182 xfs_fsblock_t *first, /* bmap's firstblock */ 153 xfs_fsblock_t *first, /* bmap's firstblock */
183 xfs_bmap_free_t *flist, /* bmap's freeblock list */ 154 xfs_bmap_free_t *flist, /* bmap's freeblock list */
184 xfs_extlen_t total) /* bmap's total block count */ 155 xfs_extlen_t total) /* bmap's total block count */
185{ 156{
186 xfs_da_args_t args; /* operation arguments */ 157 xfs_da_args_t args;
187 int rval; /* return value */ 158 int rval;
188 int v; /* type-checking value */ 159 int v; /* type-checking value */
189 160
190 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 161 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
191 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { 162 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
192 return rval; 163 return rval;
193 }
194 XFS_STATS_INC(xs_dir_create); 164 XFS_STATS_INC(xs_dir_create);
195 /* 165
196 * Fill in the arg structure for this request.
197 */
198 args.name = name; 166 args.name = name;
199 args.namelen = namelen; 167 args.namelen = namelen;
200 args.hashval = xfs_da_hashname(name, namelen); 168 args.hashval = xfs_da_hashname(name, namelen);
@@ -207,18 +175,16 @@ xfs_dir2_createname(
207 args.trans = tp; 175 args.trans = tp;
208 args.justcheck = 0; 176 args.justcheck = 0;
209 args.addname = args.oknoent = 1; 177 args.addname = args.oknoent = 1;
210 /* 178
211 * Decide on what work routines to call based on the inode size.
212 */
213 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 179 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
214 rval = xfs_dir2_sf_addname(&args); 180 rval = xfs_dir2_sf_addname(&args);
215 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 181 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
216 return rval; 182 return rval;
217 } else if (v) 183 else if (v)
218 rval = xfs_dir2_block_addname(&args); 184 rval = xfs_dir2_block_addname(&args);
219 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 185 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
220 return rval; 186 return rval;
221 } else if (v) 187 else if (v)
222 rval = xfs_dir2_leaf_addname(&args); 188 rval = xfs_dir2_leaf_addname(&args);
223 else 189 else
224 rval = xfs_dir2_node_addname(&args); 190 rval = xfs_dir2_node_addname(&args);
@@ -228,24 +194,21 @@ xfs_dir2_createname(
228/* 194/*
229 * Lookup a name in a directory, give back the inode number. 195 * Lookup a name in a directory, give back the inode number.
230 */ 196 */
231static int /* error */ 197int
232xfs_dir2_lookup( 198xfs_dir_lookup(
233 xfs_trans_t *tp, /* transaction pointer */ 199 xfs_trans_t *tp,
234 xfs_inode_t *dp, /* incore directory inode */ 200 xfs_inode_t *dp,
235 char *name, /* lookup name */ 201 char *name,
236 int namelen, /* lookup name length */ 202 int namelen,
237 xfs_ino_t *inum) /* out: inode number */ 203 xfs_ino_t *inum) /* out: inode number */
238{ 204{
239 xfs_da_args_t args; /* operation arguments */ 205 xfs_da_args_t args;
240 int rval; /* return value */ 206 int rval;
241 int v; /* type-checking value */ 207 int v; /* type-checking value */
242 208
243 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 209 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
244 XFS_STATS_INC(xs_dir_lookup); 210 XFS_STATS_INC(xs_dir_lookup);
245 211
246 /*
247 * Fill in the arg structure for this request.
248 */
249 args.name = name; 212 args.name = name;
250 args.namelen = namelen; 213 args.namelen = namelen;
251 args.hashval = xfs_da_hashname(name, namelen); 214 args.hashval = xfs_da_hashname(name, namelen);
@@ -258,18 +221,16 @@ xfs_dir2_lookup(
258 args.trans = tp; 221 args.trans = tp;
259 args.justcheck = args.addname = 0; 222 args.justcheck = args.addname = 0;
260 args.oknoent = 1; 223 args.oknoent = 1;
261 /* 224
262 * Decide on what work routines to call based on the inode size.
263 */
264 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 225 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
265 rval = xfs_dir2_sf_lookup(&args); 226 rval = xfs_dir2_sf_lookup(&args);
266 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 227 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
267 return rval; 228 return rval;
268 } else if (v) 229 else if (v)
269 rval = xfs_dir2_block_lookup(&args); 230 rval = xfs_dir2_block_lookup(&args);
270 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 231 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
271 return rval; 232 return rval;
272 } else if (v) 233 else if (v)
273 rval = xfs_dir2_leaf_lookup(&args); 234 rval = xfs_dir2_leaf_lookup(&args);
274 else 235 else
275 rval = xfs_dir2_node_lookup(&args); 236 rval = xfs_dir2_node_lookup(&args);
@@ -283,26 +244,24 @@ xfs_dir2_lookup(
283/* 244/*
284 * Remove an entry from a directory. 245 * Remove an entry from a directory.
285 */ 246 */
286static int /* error */ 247int
287xfs_dir2_removename( 248xfs_dir_removename(
288 xfs_trans_t *tp, /* transaction pointer */ 249 xfs_trans_t *tp,
289 xfs_inode_t *dp, /* incore directory inode */ 250 xfs_inode_t *dp,
290 char *name, /* name of entry to remove */ 251 char *name,
291 int namelen, /* name length of entry to remove */ 252 int namelen,
292 xfs_ino_t ino, /* inode number of entry to remove */ 253 xfs_ino_t ino,
293 xfs_fsblock_t *first, /* bmap's firstblock */ 254 xfs_fsblock_t *first, /* bmap's firstblock */
294 xfs_bmap_free_t *flist, /* bmap's freeblock list */ 255 xfs_bmap_free_t *flist, /* bmap's freeblock list */
295 xfs_extlen_t total) /* bmap's total block count */ 256 xfs_extlen_t total) /* bmap's total block count */
296{ 257{
297 xfs_da_args_t args; /* operation arguments */ 258 xfs_da_args_t args;
298 int rval; /* return value */ 259 int rval;
299 int v; /* type-checking value */ 260 int v; /* type-checking value */
300 261
301 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 262 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
302 XFS_STATS_INC(xs_dir_remove); 263 XFS_STATS_INC(xs_dir_remove);
303 /* 264
304 * Fill in the arg structure for this request.
305 */
306 args.name = name; 265 args.name = name;
307 args.namelen = namelen; 266 args.namelen = namelen;
308 args.hashval = xfs_da_hashname(name, namelen); 267 args.hashval = xfs_da_hashname(name, namelen);
@@ -314,18 +273,16 @@ xfs_dir2_removename(
314 args.whichfork = XFS_DATA_FORK; 273 args.whichfork = XFS_DATA_FORK;
315 args.trans = tp; 274 args.trans = tp;
316 args.justcheck = args.addname = args.oknoent = 0; 275 args.justcheck = args.addname = args.oknoent = 0;
317 /* 276
318 * Decide on what work routines to call based on the inode size.
319 */
320 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 277 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
321 rval = xfs_dir2_sf_removename(&args); 278 rval = xfs_dir2_sf_removename(&args);
322 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 279 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
323 return rval; 280 return rval;
324 } else if (v) 281 else if (v)
325 rval = xfs_dir2_block_removename(&args); 282 rval = xfs_dir2_block_removename(&args);
326 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 283 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
327 return rval; 284 return rval;
328 } else if (v) 285 else if (v)
329 rval = xfs_dir2_leaf_removename(&args); 286 rval = xfs_dir2_leaf_removename(&args);
330 else 287 else
331 rval = xfs_dir2_node_removename(&args); 288 rval = xfs_dir2_node_removename(&args);
@@ -335,10 +292,10 @@ xfs_dir2_removename(
335/* 292/*
336 * Read a directory. 293 * Read a directory.
337 */ 294 */
338static int /* error */ 295int
339xfs_dir2_getdents( 296xfs_dir_getdents(
340 xfs_trans_t *tp, /* transaction pointer */ 297 xfs_trans_t *tp,
341 xfs_inode_t *dp, /* incore directory inode */ 298 xfs_inode_t *dp,
342 uio_t *uio, /* caller's buffer control */ 299 uio_t *uio, /* caller's buffer control */
343 int *eofp) /* out: eof reached */ 300 int *eofp) /* out: eof reached */
344{ 301{
@@ -367,14 +324,11 @@ xfs_dir2_getdents(
367 } 324 }
368 325
369 *eofp = 0; 326 *eofp = 0;
370 /*
371 * Decide on what work routines to call based on the inode size.
372 */
373 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 327 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
374 rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put); 328 rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put);
375 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 329 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
376 ; 330 ;
377 } else if (v) 331 else if (v)
378 rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put); 332 rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put);
379 else 333 else
380 rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put); 334 rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put);
@@ -386,29 +340,26 @@ xfs_dir2_getdents(
386/* 340/*
387 * Replace the inode number of a directory entry. 341 * Replace the inode number of a directory entry.
388 */ 342 */
389static int /* error */ 343int
390xfs_dir2_replace( 344xfs_dir_replace(
391 xfs_trans_t *tp, /* transaction pointer */ 345 xfs_trans_t *tp,
392 xfs_inode_t *dp, /* incore directory inode */ 346 xfs_inode_t *dp,
393 char *name, /* name of entry to replace */ 347 char *name, /* name of entry to replace */
394 int namelen, /* name length of entry to replace */ 348 int namelen,
395 xfs_ino_t inum, /* new inode number */ 349 xfs_ino_t inum, /* new inode number */
396 xfs_fsblock_t *first, /* bmap's firstblock */ 350 xfs_fsblock_t *first, /* bmap's firstblock */
397 xfs_bmap_free_t *flist, /* bmap's freeblock list */ 351 xfs_bmap_free_t *flist, /* bmap's freeblock list */
398 xfs_extlen_t total) /* bmap's total block count */ 352 xfs_extlen_t total) /* bmap's total block count */
399{ 353{
400 xfs_da_args_t args; /* operation arguments */ 354 xfs_da_args_t args;
401 int rval; /* return value */ 355 int rval;
402 int v; /* type-checking value */ 356 int v; /* type-checking value */
403 357
404 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 358 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
405 359
406 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { 360 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
407 return rval; 361 return rval;
408 } 362
409 /*
410 * Fill in the arg structure for this request.
411 */
412 args.name = name; 363 args.name = name;
413 args.namelen = namelen; 364 args.namelen = namelen;
414 args.hashval = xfs_da_hashname(name, namelen); 365 args.hashval = xfs_da_hashname(name, namelen);
@@ -420,18 +371,16 @@ xfs_dir2_replace(
420 args.whichfork = XFS_DATA_FORK; 371 args.whichfork = XFS_DATA_FORK;
421 args.trans = tp; 372 args.trans = tp;
422 args.justcheck = args.addname = args.oknoent = 0; 373 args.justcheck = args.addname = args.oknoent = 0;
423 /* 374
424 * Decide on what work routines to call based on the inode size.
425 */
426 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 375 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
427 rval = xfs_dir2_sf_replace(&args); 376 rval = xfs_dir2_sf_replace(&args);
428 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 377 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
429 return rval; 378 return rval;
430 } else if (v) 379 else if (v)
431 rval = xfs_dir2_block_replace(&args); 380 rval = xfs_dir2_block_replace(&args);
432 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 381 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
433 return rval; 382 return rval;
434 } else if (v) 383 else if (v)
435 rval = xfs_dir2_leaf_replace(&args); 384 rval = xfs_dir2_leaf_replace(&args);
436 else 385 else
437 rval = xfs_dir2_node_replace(&args); 386 rval = xfs_dir2_node_replace(&args);
@@ -441,21 +390,19 @@ xfs_dir2_replace(
441/* 390/*
442 * See if this entry can be added to the directory without allocating space. 391 * See if this entry can be added to the directory without allocating space.
443 */ 392 */
444static int /* error */ 393int
445xfs_dir2_canenter( 394xfs_dir_canenter(
446 xfs_trans_t *tp, /* transaction pointer */ 395 xfs_trans_t *tp,
447 xfs_inode_t *dp, /* incore directory inode */ 396 xfs_inode_t *dp,
448 char *name, /* name of entry to add */ 397 char *name, /* name of entry to add */
449 int namelen) /* name length of entry to add */ 398 int namelen)
450{ 399{
451 xfs_da_args_t args; /* operation arguments */ 400 xfs_da_args_t args;
452 int rval; /* return value */ 401 int rval;
453 int v; /* type-checking value */ 402 int v; /* type-checking value */
454 403
455 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 404 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
456 /* 405
457 * Fill in the arg structure for this request.
458 */
459 args.name = name; 406 args.name = name;
460 args.namelen = namelen; 407 args.namelen = namelen;
461 args.hashval = xfs_da_hashname(name, namelen); 408 args.hashval = xfs_da_hashname(name, namelen);
@@ -467,18 +414,16 @@ xfs_dir2_canenter(
467 args.whichfork = XFS_DATA_FORK; 414 args.whichfork = XFS_DATA_FORK;
468 args.trans = tp; 415 args.trans = tp;
469 args.justcheck = args.addname = args.oknoent = 1; 416 args.justcheck = args.addname = args.oknoent = 1;
470 /* 417
471 * Decide on what work routines to call based on the inode size.
472 */
473 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 418 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
474 rval = xfs_dir2_sf_addname(&args); 419 rval = xfs_dir2_sf_addname(&args);
475 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 420 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
476 return rval; 421 return rval;
477 } else if (v) 422 else if (v)
478 rval = xfs_dir2_block_addname(&args); 423 rval = xfs_dir2_block_addname(&args);
479 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 424 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
480 return rval; 425 return rval;
481 } else if (v) 426 else if (v)
482 rval = xfs_dir2_leaf_addname(&args); 427 rval = xfs_dir2_leaf_addname(&args);
483 else 428 else
484 rval = xfs_dir2_node_addname(&args); 429 rval = xfs_dir2_node_addname(&args);
@@ -486,19 +431,6 @@ xfs_dir2_canenter(
486} 431}
487 432
488/* 433/*
489 * Dummy routine for shortform inode validation.
490 * Can't really do this.
491 */
492/* ARGSUSED */
493static int /* error */
494xfs_dir2_shortform_validate_ondisk(
495 xfs_mount_t *mp, /* filesystem mount point */
496 xfs_dinode_t *dip) /* ondisk inode */
497{
498 return 0;
499}
500
501/*
502 * Utility routines. 434 * Utility routines.
503 */ 435 */
504 436
@@ -507,24 +439,24 @@ xfs_dir2_shortform_validate_ondisk(
507 * This routine is for data and free blocks, not leaf/node blocks 439 * This routine is for data and free blocks, not leaf/node blocks
508 * which are handled by xfs_da_grow_inode. 440 * which are handled by xfs_da_grow_inode.
509 */ 441 */
510int /* error */ 442int
511xfs_dir2_grow_inode( 443xfs_dir2_grow_inode(
512 xfs_da_args_t *args, /* operation arguments */ 444 xfs_da_args_t *args,
513 int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */ 445 int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */
514 xfs_dir2_db_t *dbp) /* out: block number added */ 446 xfs_dir2_db_t *dbp) /* out: block number added */
515{ 447{
516 xfs_fileoff_t bno; /* directory offset of new block */ 448 xfs_fileoff_t bno; /* directory offset of new block */
517 int count; /* count of filesystem blocks */ 449 int count; /* count of filesystem blocks */
518 xfs_inode_t *dp; /* incore directory inode */ 450 xfs_inode_t *dp; /* incore directory inode */
519 int error; /* error return value */ 451 int error;
520 int got; /* blocks actually mapped */ 452 int got; /* blocks actually mapped */
521 int i; /* temp mapping index */ 453 int i;
522 xfs_bmbt_irec_t map; /* single structure for bmap */ 454 xfs_bmbt_irec_t map; /* single structure for bmap */
523 int mapi; /* mapping index */ 455 int mapi; /* mapping index */
524 xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */ 456 xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */
525 xfs_mount_t *mp; /* filesystem mount point */ 457 xfs_mount_t *mp;
526 int nmap; /* number of bmap entries */ 458 int nmap; /* number of bmap entries */
527 xfs_trans_t *tp; /* transaction pointer */ 459 xfs_trans_t *tp;
528 460
529 xfs_dir2_trace_args_s("grow_inode", args, space); 461 xfs_dir2_trace_args_s("grow_inode", args, space);
530 dp = args->dp; 462 dp = args->dp;
@@ -538,9 +470,8 @@ xfs_dir2_grow_inode(
538 /* 470 /*
539 * Find the first hole for our block. 471 * Find the first hole for our block.
540 */ 472 */
541 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) { 473 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK)))
542 return error; 474 return error;
543 }
544 nmap = 1; 475 nmap = 1;
545 ASSERT(args->firstblock != NULL); 476 ASSERT(args->firstblock != NULL);
546 /* 477 /*
@@ -549,13 +480,9 @@ xfs_dir2_grow_inode(
549 if ((error = xfs_bmapi(tp, dp, bno, count, 480 if ((error = xfs_bmapi(tp, dp, bno, count,
550 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, 481 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG,
551 args->firstblock, args->total, &map, &nmap, 482 args->firstblock, args->total, &map, &nmap,
552 args->flist))) { 483 args->flist, NULL)))
553 return error; 484 return error;
554 }
555 ASSERT(nmap <= 1); 485 ASSERT(nmap <= 1);
556 /*
557 * Got it in 1.
558 */
559 if (nmap == 1) { 486 if (nmap == 1) {
560 mapp = &map; 487 mapp = &map;
561 mapi = 1; 488 mapi = 1;
@@ -585,7 +512,8 @@ xfs_dir2_grow_inode(
585 if ((error = xfs_bmapi(tp, dp, b, c, 512 if ((error = xfs_bmapi(tp, dp, b, c,
586 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA, 513 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA,
587 args->firstblock, args->total, 514 args->firstblock, args->total,
588 &mapp[mapi], &nmap, args->flist))) { 515 &mapp[mapi], &nmap, args->flist,
516 NULL))) {
589 kmem_free(mapp, sizeof(*mapp) * count); 517 kmem_free(mapp, sizeof(*mapp) * count);
590 return error; 518 return error;
591 } 519 }
@@ -645,20 +573,19 @@ xfs_dir2_grow_inode(
645/* 573/*
646 * See if the directory is a single-block form directory. 574 * See if the directory is a single-block form directory.
647 */ 575 */
648int /* error */ 576int
649xfs_dir2_isblock( 577xfs_dir2_isblock(
650 xfs_trans_t *tp, /* transaction pointer */ 578 xfs_trans_t *tp,
651 xfs_inode_t *dp, /* incore directory inode */ 579 xfs_inode_t *dp,
652 int *vp) /* out: 1 is block, 0 is not block */ 580 int *vp) /* out: 1 is block, 0 is not block */
653{ 581{
654 xfs_fileoff_t last; /* last file offset */ 582 xfs_fileoff_t last; /* last file offset */
655 xfs_mount_t *mp; /* filesystem mount point */ 583 xfs_mount_t *mp;
656 int rval; /* return value */ 584 int rval;
657 585
658 mp = dp->i_mount; 586 mp = dp->i_mount;
659 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { 587 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))
660 return rval; 588 return rval;
661 }
662 rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize; 589 rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize;
663 ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize); 590 ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize);
664 *vp = rval; 591 *vp = rval;
@@ -668,20 +595,19 @@ xfs_dir2_isblock(
668/* 595/*
669 * See if the directory is a single-leaf form directory. 596 * See if the directory is a single-leaf form directory.
670 */ 597 */
671int /* error */ 598int
672xfs_dir2_isleaf( 599xfs_dir2_isleaf(
673 xfs_trans_t *tp, /* transaction pointer */ 600 xfs_trans_t *tp,
674 xfs_inode_t *dp, /* incore directory inode */ 601 xfs_inode_t *dp,
675 int *vp) /* out: 1 is leaf, 0 is not leaf */ 602 int *vp) /* out: 1 is leaf, 0 is not leaf */
676{ 603{
677 xfs_fileoff_t last; /* last file offset */ 604 xfs_fileoff_t last; /* last file offset */
678 xfs_mount_t *mp; /* filesystem mount point */ 605 xfs_mount_t *mp;
679 int rval; /* return value */ 606 int rval;
680 607
681 mp = dp->i_mount; 608 mp = dp->i_mount;
682 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { 609 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))
683 return rval; 610 return rval;
684 }
685 *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog); 611 *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog);
686 return 0; 612 return 0;
687} 613}
@@ -689,9 +615,9 @@ xfs_dir2_isleaf(
689/* 615/*
690 * Getdents put routine for 64-bit ABI, direct form. 616 * Getdents put routine for 64-bit ABI, direct form.
691 */ 617 */
692static int /* error */ 618static int
693xfs_dir2_put_dirent64_direct( 619xfs_dir2_put_dirent64_direct(
694 xfs_dir2_put_args_t *pa) /* argument bundle */ 620 xfs_dir2_put_args_t *pa)
695{ 621{
696 xfs_dirent_t *idbp; /* dirent pointer */ 622 xfs_dirent_t *idbp; /* dirent pointer */
697 iovec_t *iovp; /* io vector */ 623 iovec_t *iovp; /* io vector */
@@ -726,9 +652,9 @@ xfs_dir2_put_dirent64_direct(
726/* 652/*
727 * Getdents put routine for 64-bit ABI, uio form. 653 * Getdents put routine for 64-bit ABI, uio form.
728 */ 654 */
729static int /* error */ 655static int
730xfs_dir2_put_dirent64_uio( 656xfs_dir2_put_dirent64_uio(
731 xfs_dir2_put_args_t *pa) /* argument bundle */ 657 xfs_dir2_put_args_t *pa)
732{ 658{
733 xfs_dirent_t *idbp; /* dirent pointer */ 659 xfs_dirent_t *idbp; /* dirent pointer */
734 int namelen; /* entry name length */ 660 int namelen; /* entry name length */
@@ -764,17 +690,17 @@ xfs_dir2_put_dirent64_uio(
764 */ 690 */
765int 691int
766xfs_dir2_shrink_inode( 692xfs_dir2_shrink_inode(
767 xfs_da_args_t *args, /* operation arguments */ 693 xfs_da_args_t *args,
768 xfs_dir2_db_t db, /* directory block number */ 694 xfs_dir2_db_t db,
769 xfs_dabuf_t *bp) /* block's buffer */ 695 xfs_dabuf_t *bp)
770{ 696{
771 xfs_fileoff_t bno; /* directory file offset */ 697 xfs_fileoff_t bno; /* directory file offset */
772 xfs_dablk_t da; /* directory file offset */ 698 xfs_dablk_t da; /* directory file offset */
773 int done; /* bunmap is finished */ 699 int done; /* bunmap is finished */
774 xfs_inode_t *dp; /* incore directory inode */ 700 xfs_inode_t *dp;
775 int error; /* error return value */ 701 int error;
776 xfs_mount_t *mp; /* filesystem mount point */ 702 xfs_mount_t *mp;
777 xfs_trans_t *tp; /* transaction pointer */ 703 xfs_trans_t *tp;
778 704
779 xfs_dir2_trace_args_db("shrink_inode", args, db, bp); 705 xfs_dir2_trace_args_db("shrink_inode", args, db, bp);
780 dp = args->dp; 706 dp = args->dp;
@@ -786,7 +712,7 @@ xfs_dir2_shrink_inode(
786 */ 712 */
787 if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs, 713 if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs,
788 XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, 714 XFS_BMAPI_METADATA, 0, args->firstblock, args->flist,
789 &done))) { 715 NULL, &done))) {
790 /* 716 /*
791 * ENOSPC actually can happen if we're in a removename with 717 * ENOSPC actually can happen if we're in a removename with
792 * no space reservation, and the resulting block removal 718 * no space reservation, and the resulting block removal
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index 7dd364b1e038..86560b6f794c 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -22,7 +22,9 @@ struct uio;
22struct xfs_dabuf; 22struct xfs_dabuf;
23struct xfs_da_args; 23struct xfs_da_args;
24struct xfs_dir2_put_args; 24struct xfs_dir2_put_args;
25struct xfs_bmap_free;
25struct xfs_inode; 26struct xfs_inode;
27struct xfs_mount;
26struct xfs_trans; 28struct xfs_trans;
27 29
28/* 30/*
@@ -73,7 +75,35 @@ typedef struct xfs_dir2_put_args {
73} xfs_dir2_put_args_t; 75} xfs_dir2_put_args_t;
74 76
75/* 77/*
76 * Other interfaces used by the rest of the dir v2 code. 78 * Generic directory interface routines
79 */
80extern void xfs_dir_startup(void);
81extern void xfs_dir_mount(struct xfs_mount *mp);
82extern int xfs_dir_isempty(struct xfs_inode *dp);
83extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
84 struct xfs_inode *pdp);
85extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp,
86 char *name, int namelen, xfs_ino_t inum,
87 xfs_fsblock_t *first,
88 struct xfs_bmap_free *flist, xfs_extlen_t tot);
89extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp,
90 char *name, int namelen, xfs_ino_t *inum);
91extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
92 char *name, int namelen, xfs_ino_t ino,
93 xfs_fsblock_t *first,
94 struct xfs_bmap_free *flist, xfs_extlen_t tot);
95extern int xfs_dir_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
96 uio_t *uio, int *eofp);
97extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
98 char *name, int namelen, xfs_ino_t inum,
99 xfs_fsblock_t *first,
100 struct xfs_bmap_free *flist, xfs_extlen_t tot);
101extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
102 char *name, int namelen);
103extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
104
105/*
106 * Utility routines for v2 directories.
77 */ 107 */
78extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, 108extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
79 xfs_dir2_db_t *dbp); 109 xfs_dir2_db_t *dbp);
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 972ded595476..9d7438bba30d 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -22,19 +22,16 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
35#include "xfs_inode.h" 33#include "xfs_inode.h"
36#include "xfs_inode_item.h" 34#include "xfs_inode_item.h"
37#include "xfs_dir_leaf.h"
38#include "xfs_dir2_data.h" 35#include "xfs_dir2_data.h"
39#include "xfs_dir2_leaf.h" 36#include "xfs_dir2_leaf.h"
40#include "xfs_dir2_block.h" 37#include "xfs_dir2_block.h"
@@ -51,6 +48,18 @@ static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp,
51 int *entno); 48 int *entno);
52static int xfs_dir2_block_sort(const void *a, const void *b); 49static int xfs_dir2_block_sort(const void *a, const void *b);
53 50
51static xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
52
53/*
54 * One-time startup routine called from xfs_init().
55 */
56void
57xfs_dir_startup(void)
58{
59 xfs_dir_hash_dot = xfs_da_hashname(".", 1);
60 xfs_dir_hash_dotdot = xfs_da_hashname("..", 2);
61}
62
54/* 63/*
55 * Add an entry to a block directory. 64 * Add an entry to a block directory.
56 */ 65 */
@@ -400,7 +409,7 @@ xfs_dir2_block_addname(
400 /* 409 /*
401 * Create the new data entry. 410 * Create the new data entry.
402 */ 411 */
403 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 412 dep->inumber = cpu_to_be64(args->inumber);
404 dep->namelen = args->namelen; 413 dep->namelen = args->namelen;
405 memcpy(dep->name, args->name, args->namelen); 414 memcpy(dep->name, args->name, args->namelen);
406 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 415 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -508,7 +517,7 @@ xfs_dir2_block_getdents(
508 517
509 p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, 518 p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
510 ptr - (char *)block); 519 ptr - (char *)block);
511 p.ino = INT_GET(dep->inumber, ARCH_CONVERT); 520 p.ino = be64_to_cpu(dep->inumber);
512#if XFS_BIG_INUMS 521#if XFS_BIG_INUMS
513 p.ino += mp->m_inoadd; 522 p.ino += mp->m_inoadd;
514#endif 523#endif
@@ -626,7 +635,7 @@ xfs_dir2_block_lookup(
626 /* 635 /*
627 * Fill in inode number, release the block. 636 * Fill in inode number, release the block.
628 */ 637 */
629 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); 638 args->inumber = be64_to_cpu(dep->inumber);
630 xfs_da_brelse(args->trans, bp); 639 xfs_da_brelse(args->trans, bp);
631 return XFS_ERROR(EEXIST); 640 return XFS_ERROR(EEXIST);
632} 641}
@@ -844,11 +853,11 @@ xfs_dir2_block_replace(
844 */ 853 */
845 dep = (xfs_dir2_data_entry_t *) 854 dep = (xfs_dir2_data_entry_t *)
846 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address))); 855 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address)));
847 ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) != args->inumber); 856 ASSERT(be64_to_cpu(dep->inumber) != args->inumber);
848 /* 857 /*
849 * Change the inode number to the new value. 858 * Change the inode number to the new value.
850 */ 859 */
851 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 860 dep->inumber = cpu_to_be64(args->inumber);
852 xfs_dir2_data_log_entry(args->trans, bp, dep); 861 xfs_dir2_data_log_entry(args->trans, bp, dep);
853 xfs_dir2_data_check(dp, bp); 862 xfs_dir2_data_check(dp, bp);
854 xfs_da_buf_done(bp); 863 xfs_da_buf_done(bp);
@@ -1130,7 +1139,7 @@ xfs_dir2_sf_to_block(
1130 */ 1139 */
1131 dep = (xfs_dir2_data_entry_t *) 1140 dep = (xfs_dir2_data_entry_t *)
1132 ((char *)block + XFS_DIR2_DATA_DOT_OFFSET); 1141 ((char *)block + XFS_DIR2_DATA_DOT_OFFSET);
1133 INT_SET(dep->inumber, ARCH_CONVERT, dp->i_ino); 1142 dep->inumber = cpu_to_be64(dp->i_ino);
1134 dep->namelen = 1; 1143 dep->namelen = 1;
1135 dep->name[0] = '.'; 1144 dep->name[0] = '.';
1136 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 1145 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -1144,7 +1153,7 @@ xfs_dir2_sf_to_block(
1144 */ 1153 */
1145 dep = (xfs_dir2_data_entry_t *) 1154 dep = (xfs_dir2_data_entry_t *)
1146 ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); 1155 ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET);
1147 INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); 1156 dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
1148 dep->namelen = 2; 1157 dep->namelen = 2;
1149 dep->name[0] = dep->name[1] = '.'; 1158 dep->name[0] = dep->name[1] = '.';
1150 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 1159 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -1193,7 +1202,7 @@ xfs_dir2_sf_to_block(
1193 * Copy a real entry. 1202 * Copy a real entry.
1194 */ 1203 */
1195 dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); 1204 dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset);
1196 INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, 1205 dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp,
1197 XFS_DIR2_SF_INUMBERP(sfep))); 1206 XFS_DIR2_SF_INUMBERP(sfep)));
1198 dep->namelen = sfep->namelen; 1207 dep->namelen = sfep->namelen;
1199 memcpy(dep->name, sfep->name, dep->namelen); 1208 memcpy(dep->name, sfep->name, dep->namelen);
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index bb3d03ff002b..f7c799217072 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -22,18 +22,15 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
35#include "xfs_inode.h" 33#include "xfs_inode.h"
36#include "xfs_dir_leaf.h"
37#include "xfs_dir2_data.h" 34#include "xfs_dir2_data.h"
38#include "xfs_dir2_leaf.h" 35#include "xfs_dir2_leaf.h"
39#include "xfs_dir2_block.h" 36#include "xfs_dir2_block.h"
@@ -133,7 +130,7 @@ xfs_dir2_data_check(
133 */ 130 */
134 dep = (xfs_dir2_data_entry_t *)p; 131 dep = (xfs_dir2_data_entry_t *)p;
135 ASSERT(dep->namelen != 0); 132 ASSERT(dep->namelen != 0);
136 ASSERT(xfs_dir_ino_validate(mp, INT_GET(dep->inumber, ARCH_CONVERT)) == 0); 133 ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0);
137 ASSERT(be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) == 134 ASSERT(be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) ==
138 (char *)dep - (char *)d); 135 (char *)dep - (char *)d);
139 count++; 136 count++;
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h
index 0847cbb53e17..a6ae2d21c40a 100644
--- a/fs/xfs/xfs_dir2_data.h
+++ b/fs/xfs/xfs_dir2_data.h
@@ -85,11 +85,11 @@ typedef struct xfs_dir2_data_hdr {
85 * Tag appears as the last 2 bytes. 85 * Tag appears as the last 2 bytes.
86 */ 86 */
87typedef struct xfs_dir2_data_entry { 87typedef struct xfs_dir2_data_entry {
88 xfs_ino_t inumber; /* inode number */ 88 __be64 inumber; /* inode number */
89 __uint8_t namelen; /* name length */ 89 __u8 namelen; /* name length */
90 __uint8_t name[1]; /* name bytes, no null */ 90 __u8 name[1]; /* name bytes, no null */
91 /* variable offset */ 91 /* variable offset */
92 xfs_dir2_data_off_t tag; /* starting offset of us */ 92 __be16 tag; /* starting offset of us */
93} xfs_dir2_data_entry_t; 93} xfs_dir2_data_entry_t;
94 94
95/* 95/*
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 0f5e2f2ce6ec..b1cf1fbf423d 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_da_btree.h" 30#include "xfs_da_btree.h"
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_attr_sf.h" 32#include "xfs_attr_sf.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_dinode.h" 34#include "xfs_dinode.h"
37#include "xfs_inode.h" 35#include "xfs_inode.h"
@@ -407,7 +405,7 @@ xfs_dir2_leaf_addname(
407 * Initialize our new entry (at last). 405 * Initialize our new entry (at last).
408 */ 406 */
409 dep = (xfs_dir2_data_entry_t *)dup; 407 dep = (xfs_dir2_data_entry_t *)dup;
410 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 408 dep->inumber = cpu_to_be64(args->inumber);
411 dep->namelen = args->namelen; 409 dep->namelen = args->namelen;
412 memcpy(dep->name, args->name, dep->namelen); 410 memcpy(dep->name, args->name, dep->namelen);
413 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 411 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -884,7 +882,7 @@ xfs_dir2_leaf_getdents(
884 XFS_DIR2_BYTE_TO_DA(mp, 882 XFS_DIR2_BYTE_TO_DA(mp,
885 XFS_DIR2_LEAF_OFFSET) - map_off, 883 XFS_DIR2_LEAF_OFFSET) - map_off,
886 XFS_BMAPI_METADATA, NULL, 0, 884 XFS_BMAPI_METADATA, NULL, 0,
887 &map[map_valid], &nmap, NULL); 885 &map[map_valid], &nmap, NULL, NULL);
888 /* 886 /*
889 * Don't know if we should ignore this or 887 * Don't know if we should ignore this or
890 * try to return an error. 888 * try to return an error.
@@ -1098,7 +1096,7 @@ xfs_dir2_leaf_getdents(
1098 1096
1099 p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length); 1097 p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length);
1100 1098
1101 p->ino = INT_GET(dep->inumber, ARCH_CONVERT); 1099 p->ino = be64_to_cpu(dep->inumber);
1102#if XFS_BIG_INUMS 1100#if XFS_BIG_INUMS
1103 p->ino += mp->m_inoadd; 1101 p->ino += mp->m_inoadd;
1104#endif 1102#endif
@@ -1319,7 +1317,7 @@ xfs_dir2_leaf_lookup(
1319 /* 1317 /*
1320 * Return the found inode number. 1318 * Return the found inode number.
1321 */ 1319 */
1322 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); 1320 args->inumber = be64_to_cpu(dep->inumber);
1323 xfs_da_brelse(tp, dbp); 1321 xfs_da_brelse(tp, dbp);
1324 xfs_da_brelse(tp, lbp); 1322 xfs_da_brelse(tp, lbp);
1325 return XFS_ERROR(EEXIST); 1323 return XFS_ERROR(EEXIST);
@@ -1606,11 +1604,11 @@ xfs_dir2_leaf_replace(
1606 dep = (xfs_dir2_data_entry_t *) 1604 dep = (xfs_dir2_data_entry_t *)
1607 ((char *)dbp->data + 1605 ((char *)dbp->data +
1608 XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address))); 1606 XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address)));
1609 ASSERT(args->inumber != INT_GET(dep->inumber, ARCH_CONVERT)); 1607 ASSERT(args->inumber != be64_to_cpu(dep->inumber));
1610 /* 1608 /*
1611 * Put the new inode number in, log it. 1609 * Put the new inode number in, log it.
1612 */ 1610 */
1613 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 1611 dep->inumber = cpu_to_be64(args->inumber);
1614 tp = args->trans; 1612 tp = args->trans;
1615 xfs_dir2_data_log_entry(tp, dbp, dep); 1613 xfs_dir2_data_log_entry(tp, dbp, dep);
1616 xfs_da_buf_done(dbp); 1614 xfs_da_buf_done(dbp);
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index ac511ab9c52d..9ca71719b683 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -22,13 +22,11 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
@@ -505,7 +503,6 @@ xfs_dir2_leafn_lookup_int(
505 XFS_DATA_FORK))) { 503 XFS_DATA_FORK))) {
506 return error; 504 return error;
507 } 505 }
508 curfdb = newfdb;
509 free = curbp->data; 506 free = curbp->data;
510 ASSERT(be32_to_cpu(free->hdr.magic) == 507 ASSERT(be32_to_cpu(free->hdr.magic) ==
511 XFS_DIR2_FREE_MAGIC); 508 XFS_DIR2_FREE_MAGIC);
@@ -527,8 +524,11 @@ xfs_dir2_leafn_lookup_int(
527 if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) { 524 if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) {
528 XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", 525 XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
529 XFS_ERRLEVEL_LOW, mp); 526 XFS_ERRLEVEL_LOW, mp);
527 if (curfdb != newfdb)
528 xfs_da_brelse(tp, curbp);
530 return XFS_ERROR(EFSCORRUPTED); 529 return XFS_ERROR(EFSCORRUPTED);
531 } 530 }
531 curfdb = newfdb;
532 if (be16_to_cpu(free->bests[fi]) >= length) { 532 if (be16_to_cpu(free->bests[fi]) >= length) {
533 *indexp = index; 533 *indexp = index;
534 state->extravalid = 1; 534 state->extravalid = 1;
@@ -580,7 +580,7 @@ xfs_dir2_leafn_lookup_int(
580 if (dep->namelen == args->namelen && 580 if (dep->namelen == args->namelen &&
581 dep->name[0] == args->name[0] && 581 dep->name[0] == args->name[0] &&
582 memcmp(dep->name, args->name, args->namelen) == 0) { 582 memcmp(dep->name, args->name, args->namelen) == 0) {
583 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); 583 args->inumber = be64_to_cpu(dep->inumber);
584 *indexp = index; 584 *indexp = index;
585 state->extravalid = 1; 585 state->extravalid = 1;
586 state->extrablk.bp = curbp; 586 state->extrablk.bp = curbp;
@@ -970,7 +970,7 @@ xfs_dir2_leafn_remove(
970 /* 970 /*
971 * One less used entry in the free table. 971 * One less used entry in the free table.
972 */ 972 */
973 free->hdr.nused = cpu_to_be32(-1); 973 be32_add(&free->hdr.nused, -1);
974 xfs_dir2_free_log_header(tp, fbp); 974 xfs_dir2_free_log_header(tp, fbp);
975 /* 975 /*
976 * If this was the last entry in the table, we can 976 * If this was the last entry in the table, we can
@@ -1695,7 +1695,7 @@ xfs_dir2_node_addname_int(
1695 * Fill in the new entry and log it. 1695 * Fill in the new entry and log it.
1696 */ 1696 */
1697 dep = (xfs_dir2_data_entry_t *)dup; 1697 dep = (xfs_dir2_data_entry_t *)dup;
1698 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 1698 dep->inumber = cpu_to_be64(args->inumber);
1699 dep->namelen = args->namelen; 1699 dep->namelen = args->namelen;
1700 memcpy(dep->name, args->name, dep->namelen); 1700 memcpy(dep->name, args->name, dep->namelen);
1701 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 1701 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -1905,11 +1905,11 @@ xfs_dir2_node_replace(
1905 dep = (xfs_dir2_data_entry_t *) 1905 dep = (xfs_dir2_data_entry_t *)
1906 ((char *)data + 1906 ((char *)data +
1907 XFS_DIR2_DATAPTR_TO_OFF(state->mp, be32_to_cpu(lep->address))); 1907 XFS_DIR2_DATAPTR_TO_OFF(state->mp, be32_to_cpu(lep->address)));
1908 ASSERT(inum != INT_GET(dep->inumber, ARCH_CONVERT)); 1908 ASSERT(inum != be64_to_cpu(dep->inumber));
1909 /* 1909 /*
1910 * Fill in the new inode number and log the entry. 1910 * Fill in the new inode number and log the entry.
1911 */ 1911 */
1912 INT_SET(dep->inumber, ARCH_CONVERT, inum); 1912 dep->inumber = cpu_to_be64(inum);
1913 xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep); 1913 xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep);
1914 rval = 0; 1914 rval = 0;
1915 } 1915 }
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index d98a41d1fe63..0cd77b17bf92 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -22,19 +22,16 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
35#include "xfs_inode.h" 33#include "xfs_inode.h"
36#include "xfs_inode_item.h" 34#include "xfs_inode_item.h"
37#include "xfs_dir_leaf.h"
38#include "xfs_error.h" 35#include "xfs_error.h"
39#include "xfs_dir2_data.h" 36#include "xfs_dir2_data.h"
40#include "xfs_dir2_leaf.h" 37#include "xfs_dir2_leaf.h"
@@ -117,13 +114,13 @@ xfs_dir2_block_sfsize(
117 dep->name[0] == '.' && dep->name[1] == '.'; 114 dep->name[0] == '.' && dep->name[1] == '.';
118#if XFS_BIG_INUMS 115#if XFS_BIG_INUMS
119 if (!isdot) 116 if (!isdot)
120 i8count += INT_GET(dep->inumber, ARCH_CONVERT) > XFS_DIR2_MAX_SHORT_INUM; 117 i8count += be64_to_cpu(dep->inumber) > XFS_DIR2_MAX_SHORT_INUM;
121#endif 118#endif
122 if (!isdot && !isdotdot) { 119 if (!isdot && !isdotdot) {
123 count++; 120 count++;
124 namelen += dep->namelen; 121 namelen += dep->namelen;
125 } else if (isdotdot) 122 } else if (isdotdot)
126 parent = INT_GET(dep->inumber, ARCH_CONVERT); 123 parent = be64_to_cpu(dep->inumber);
127 /* 124 /*
128 * Calculate the new size, see if we should give up yet. 125 * Calculate the new size, see if we should give up yet.
129 */ 126 */
@@ -229,13 +226,13 @@ xfs_dir2_block_to_sf(
229 * Skip . 226 * Skip .
230 */ 227 */
231 if (dep->namelen == 1 && dep->name[0] == '.') 228 if (dep->namelen == 1 && dep->name[0] == '.')
232 ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) == dp->i_ino); 229 ASSERT(be64_to_cpu(dep->inumber) == dp->i_ino);
233 /* 230 /*
234 * Skip .., but make sure the inode number is right. 231 * Skip .., but make sure the inode number is right.
235 */ 232 */
236 else if (dep->namelen == 2 && 233 else if (dep->namelen == 2 &&
237 dep->name[0] == '.' && dep->name[1] == '.') 234 dep->name[0] == '.' && dep->name[1] == '.')
238 ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) == 235 ASSERT(be64_to_cpu(dep->inumber) ==
239 XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); 236 XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
240 /* 237 /*
241 * Normal entry, copy it into shortform. 238 * Normal entry, copy it into shortform.
@@ -246,7 +243,7 @@ xfs_dir2_block_to_sf(
246 (xfs_dir2_data_aoff_t) 243 (xfs_dir2_data_aoff_t)
247 ((char *)dep - (char *)block)); 244 ((char *)dep - (char *)block));
248 memcpy(sfep->name, dep->name, dep->namelen); 245 memcpy(sfep->name, dep->name, dep->namelen);
249 temp=INT_GET(dep->inumber, ARCH_CONVERT); 246 temp = be64_to_cpu(dep->inumber);
250 XFS_DIR2_SF_PUT_INUMBER(sfp, &temp, 247 XFS_DIR2_SF_PUT_INUMBER(sfp, &temp,
251 XFS_DIR2_SF_INUMBERP(sfep)); 248 XFS_DIR2_SF_INUMBERP(sfep));
252 sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); 249 sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep);
diff --git a/fs/xfs/xfs_dir2_trace.c b/fs/xfs/xfs_dir2_trace.c
index c626943b4112..f3fb2ffd6f5c 100644
--- a/fs/xfs/xfs_dir2_trace.c
+++ b/fs/xfs/xfs_dir2_trace.c
@@ -19,11 +19,9 @@
19#include "xfs_fs.h" 19#include "xfs_fs.h"
20#include "xfs_types.h" 20#include "xfs_types.h"
21#include "xfs_inum.h" 21#include "xfs_inum.h"
22#include "xfs_dir.h"
23#include "xfs_dir2.h" 22#include "xfs_dir2.h"
24#include "xfs_da_btree.h" 23#include "xfs_da_btree.h"
25#include "xfs_bmap_btree.h" 24#include "xfs_bmap_btree.h"
26#include "xfs_dir_sf.h"
27#include "xfs_dir2_sf.h" 25#include "xfs_dir2_sf.h"
28#include "xfs_attr_sf.h" 26#include "xfs_attr_sf.h"
29#include "xfs_dinode.h" 27#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c
deleted file mode 100644
index 6d711869262f..000000000000
--- a/fs/xfs/xfs_dir_leaf.c
+++ /dev/null
@@ -1,2213 +0,0 @@
1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_types.h"
21#include "xfs_log.h"
22#include "xfs_inum.h"
23#include "xfs_trans.h"
24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h"
27#include "xfs_dmapi.h"
28#include "xfs_mount.h"
29#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h"
32#include "xfs_ialloc_btree.h"
33#include "xfs_dir_sf.h"
34#include "xfs_dir2_sf.h"
35#include "xfs_attr_sf.h"
36#include "xfs_dinode.h"
37#include "xfs_inode.h"
38#include "xfs_inode_item.h"
39#include "xfs_alloc.h"
40#include "xfs_btree.h"
41#include "xfs_bmap.h"
42#include "xfs_dir_leaf.h"
43#include "xfs_error.h"
44
45/*
46 * xfs_dir_leaf.c
47 *
48 * Routines to implement leaf blocks of directories as Btrees of hashed names.
49 */
50
51/*========================================================================
52 * Function prototypes for the kernel.
53 *========================================================================*/
54
55/*
56 * Routines used for growing the Btree.
57 */
58STATIC void xfs_dir_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args,
59 int insertion_index,
60 int freemap_index);
61STATIC int xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer,
62 int musthave, int justcheck);
63STATIC void xfs_dir_leaf_rebalance(xfs_da_state_t *state,
64 xfs_da_state_blk_t *blk1,
65 xfs_da_state_blk_t *blk2);
66STATIC int xfs_dir_leaf_figure_balance(xfs_da_state_t *state,
67 xfs_da_state_blk_t *leaf_blk_1,
68 xfs_da_state_blk_t *leaf_blk_2,
69 int *number_entries_in_blk1,
70 int *number_namebytes_in_blk1);
71
72STATIC int xfs_dir_leaf_create(struct xfs_da_args *args,
73 xfs_dablk_t which_block,
74 struct xfs_dabuf **bpp);
75
76/*
77 * Utility routines.
78 */
79STATIC void xfs_dir_leaf_moveents(xfs_dir_leafblock_t *src_leaf,
80 int src_start,
81 xfs_dir_leafblock_t *dst_leaf,
82 int dst_start, int move_count,
83 xfs_mount_t *mp);
84
85
86/*========================================================================
87 * External routines when dirsize < XFS_IFORK_DSIZE(dp).
88 *========================================================================*/
89
90
91/*
92 * Validate a given inode number.
93 */
94int
95xfs_dir_ino_validate(xfs_mount_t *mp, xfs_ino_t ino)
96{
97 xfs_agblock_t agblkno;
98 xfs_agino_t agino;
99 xfs_agnumber_t agno;
100 int ino_ok;
101 int ioff;
102
103 agno = XFS_INO_TO_AGNO(mp, ino);
104 agblkno = XFS_INO_TO_AGBNO(mp, ino);
105 ioff = XFS_INO_TO_OFFSET(mp, ino);
106 agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff);
107 ino_ok =
108 agno < mp->m_sb.sb_agcount &&
109 agblkno < mp->m_sb.sb_agblocks &&
110 agblkno != 0 &&
111 ioff < (1 << mp->m_sb.sb_inopblog) &&
112 XFS_AGINO_TO_INO(mp, agno, agino) == ino;
113 if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,
114 XFS_RANDOM_DIR_INO_VALIDATE))) {
115 xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx",
116 (unsigned long long) ino);
117 XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp);
118 return XFS_ERROR(EFSCORRUPTED);
119 }
120 return 0;
121}
122
123/*
124 * Create the initial contents of a shortform directory.
125 */
126int
127xfs_dir_shortform_create(xfs_da_args_t *args, xfs_ino_t parent)
128{
129 xfs_dir_sf_hdr_t *hdr;
130 xfs_inode_t *dp;
131
132 dp = args->dp;
133 ASSERT(dp != NULL);
134 ASSERT(dp->i_d.di_size == 0);
135 if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) {
136 dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */
137 dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
138 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
139 dp->i_df.if_flags |= XFS_IFINLINE;
140 }
141 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
142 ASSERT(dp->i_df.if_bytes == 0);
143 xfs_idata_realloc(dp, sizeof(*hdr), XFS_DATA_FORK);
144 hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data;
145 XFS_DIR_SF_PUT_DIRINO(&parent, &hdr->parent);
146
147 hdr->count = 0;
148 dp->i_d.di_size = sizeof(*hdr);
149 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
150 return 0;
151}
152
153/*
154 * Add a name to the shortform directory structure.
155 * Overflow from the inode has already been checked for.
156 */
157int
158xfs_dir_shortform_addname(xfs_da_args_t *args)
159{
160 xfs_dir_shortform_t *sf;
161 xfs_dir_sf_entry_t *sfe;
162 int i, offset, size;
163 xfs_inode_t *dp;
164
165 dp = args->dp;
166 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
167 /*
168 * Catch the case where the conversion from shortform to leaf
169 * failed part way through.
170 */
171 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
172 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
173 return XFS_ERROR(EIO);
174 }
175 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
176 ASSERT(dp->i_df.if_u1.if_data != NULL);
177 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
178 sfe = &sf->list[0];
179 for (i = sf->hdr.count-1; i >= 0; i--) {
180 if (sfe->namelen == args->namelen &&
181 args->name[0] == sfe->name[0] &&
182 memcmp(args->name, sfe->name, args->namelen) == 0)
183 return XFS_ERROR(EEXIST);
184 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
185 }
186
187 offset = (int)((char *)sfe - (char *)sf);
188 size = XFS_DIR_SF_ENTSIZE_BYNAME(args->namelen);
189 xfs_idata_realloc(dp, size, XFS_DATA_FORK);
190 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
191 sfe = (xfs_dir_sf_entry_t *)((char *)sf + offset);
192
193 XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber);
194 sfe->namelen = args->namelen;
195 memcpy(sfe->name, args->name, sfe->namelen);
196 sf->hdr.count++;
197
198 dp->i_d.di_size += size;
199 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
200
201 return 0;
202}
203
204/*
205 * Remove a name from the shortform directory structure.
206 */
207int
208xfs_dir_shortform_removename(xfs_da_args_t *args)
209{
210 xfs_dir_shortform_t *sf;
211 xfs_dir_sf_entry_t *sfe;
212 int base, size = 0, i;
213 xfs_inode_t *dp;
214
215 dp = args->dp;
216 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
217 /*
218 * Catch the case where the conversion from shortform to leaf
219 * failed part way through.
220 */
221 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
222 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
223 return XFS_ERROR(EIO);
224 }
225 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
226 ASSERT(dp->i_df.if_u1.if_data != NULL);
227 base = sizeof(xfs_dir_sf_hdr_t);
228 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
229 sfe = &sf->list[0];
230 for (i = sf->hdr.count-1; i >= 0; i--) {
231 size = XFS_DIR_SF_ENTSIZE_BYENTRY(sfe);
232 if (sfe->namelen == args->namelen &&
233 sfe->name[0] == args->name[0] &&
234 memcmp(sfe->name, args->name, args->namelen) == 0)
235 break;
236 base += size;
237 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
238 }
239 if (i < 0) {
240 ASSERT(args->oknoent);
241 return XFS_ERROR(ENOENT);
242 }
243
244 if ((base + size) != dp->i_d.di_size) {
245 memmove(&((char *)sf)[base], &((char *)sf)[base+size],
246 dp->i_d.di_size - (base+size));
247 }
248 sf->hdr.count--;
249
250 xfs_idata_realloc(dp, -size, XFS_DATA_FORK);
251 dp->i_d.di_size -= size;
252 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
253
254 return 0;
255}
256
257/*
258 * Look up a name in a shortform directory structure.
259 */
260int
261xfs_dir_shortform_lookup(xfs_da_args_t *args)
262{
263 xfs_dir_shortform_t *sf;
264 xfs_dir_sf_entry_t *sfe;
265 int i;
266 xfs_inode_t *dp;
267
268 dp = args->dp;
269 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
270 /*
271 * Catch the case where the conversion from shortform to leaf
272 * failed part way through.
273 */
274 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
275 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
276 return XFS_ERROR(EIO);
277 }
278 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
279 ASSERT(dp->i_df.if_u1.if_data != NULL);
280 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
281 if (args->namelen == 2 &&
282 args->name[0] == '.' && args->name[1] == '.') {
283 XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &args->inumber);
284 return(XFS_ERROR(EEXIST));
285 }
286 if (args->namelen == 1 && args->name[0] == '.') {
287 args->inumber = dp->i_ino;
288 return(XFS_ERROR(EEXIST));
289 }
290 sfe = &sf->list[0];
291 for (i = sf->hdr.count-1; i >= 0; i--) {
292 if (sfe->namelen == args->namelen &&
293 sfe->name[0] == args->name[0] &&
294 memcmp(args->name, sfe->name, args->namelen) == 0) {
295 XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args->inumber);
296 return(XFS_ERROR(EEXIST));
297 }
298 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
299 }
300 ASSERT(args->oknoent);
301 return(XFS_ERROR(ENOENT));
302}
303
304/*
305 * Convert from using the shortform to the leaf.
306 */
307int
308xfs_dir_shortform_to_leaf(xfs_da_args_t *iargs)
309{
310 xfs_inode_t *dp;
311 xfs_dir_shortform_t *sf;
312 xfs_dir_sf_entry_t *sfe;
313 xfs_da_args_t args;
314 xfs_ino_t inumber;
315 char *tmpbuffer;
316 int retval, i, size;
317 xfs_dablk_t blkno;
318 xfs_dabuf_t *bp;
319
320 dp = iargs->dp;
321 /*
322 * Catch the case where the conversion from shortform to leaf
323 * failed part way through.
324 */
325 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
326 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
327 return XFS_ERROR(EIO);
328 }
329 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
330 ASSERT(dp->i_df.if_u1.if_data != NULL);
331 size = dp->i_df.if_bytes;
332 tmpbuffer = kmem_alloc(size, KM_SLEEP);
333 ASSERT(tmpbuffer != NULL);
334
335 memcpy(tmpbuffer, dp->i_df.if_u1.if_data, size);
336
337 sf = (xfs_dir_shortform_t *)tmpbuffer;
338 XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &inumber);
339
340 xfs_idata_realloc(dp, -size, XFS_DATA_FORK);
341 dp->i_d.di_size = 0;
342 xfs_trans_log_inode(iargs->trans, dp, XFS_ILOG_CORE);
343 retval = xfs_da_grow_inode(iargs, &blkno);
344 if (retval)
345 goto out;
346
347 ASSERT(blkno == 0);
348 retval = xfs_dir_leaf_create(iargs, blkno, &bp);
349 if (retval)
350 goto out;
351 xfs_da_buf_done(bp);
352
353 args.name = ".";
354 args.namelen = 1;
355 args.hashval = xfs_dir_hash_dot;
356 args.inumber = dp->i_ino;
357 args.dp = dp;
358 args.firstblock = iargs->firstblock;
359 args.flist = iargs->flist;
360 args.total = iargs->total;
361 args.whichfork = XFS_DATA_FORK;
362 args.trans = iargs->trans;
363 args.justcheck = 0;
364 args.addname = args.oknoent = 1;
365 retval = xfs_dir_leaf_addname(&args);
366 if (retval)
367 goto out;
368
369 args.name = "..";
370 args.namelen = 2;
371 args.hashval = xfs_dir_hash_dotdot;
372 args.inumber = inumber;
373 retval = xfs_dir_leaf_addname(&args);
374 if (retval)
375 goto out;
376
377 sfe = &sf->list[0];
378 for (i = 0; i < sf->hdr.count; i++) {
379 args.name = (char *)(sfe->name);
380 args.namelen = sfe->namelen;
381 args.hashval = xfs_da_hashname((char *)(sfe->name),
382 sfe->namelen);
383 XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args.inumber);
384 retval = xfs_dir_leaf_addname(&args);
385 if (retval)
386 goto out;
387 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
388 }
389 retval = 0;
390
391out:
392 kmem_free(tmpbuffer, size);
393 return retval;
394}
395
396STATIC int
397xfs_dir_shortform_compare(const void *a, const void *b)
398{
399 xfs_dir_sf_sort_t *sa, *sb;
400
401 sa = (xfs_dir_sf_sort_t *)a;
402 sb = (xfs_dir_sf_sort_t *)b;
403 if (sa->hash < sb->hash)
404 return -1;
405 else if (sa->hash > sb->hash)
406 return 1;
407 else
408 return sa->entno - sb->entno;
409}
410
411/*
412 * Copy out directory entries for getdents(), for shortform directories.
413 */
414/*ARGSUSED*/
415int
416xfs_dir_shortform_getdents(xfs_inode_t *dp, uio_t *uio, int *eofp,
417 xfs_dirent_t *dbp, xfs_dir_put_t put)
418{
419 xfs_dir_shortform_t *sf;
420 xfs_dir_sf_entry_t *sfe;
421 int retval, i, sbsize, nsbuf, lastresid=0, want_entno;
422 xfs_mount_t *mp;
423 xfs_dahash_t cookhash, hash;
424 xfs_dir_put_args_t p;
425 xfs_dir_sf_sort_t *sbuf, *sbp;
426
427 mp = dp->i_mount;
428 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
429 cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);
430 want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset);
431 nsbuf = sf->hdr.count + 2;
432 sbsize = (nsbuf + 1) * sizeof(*sbuf);
433 sbp = sbuf = kmem_alloc(sbsize, KM_SLEEP);
434
435 xfs_dir_trace_g_du("sf: start", dp, uio);
436
437 /*
438 * Collect all the entries into the buffer.
439 * Entry 0 is .
440 */
441 sbp->entno = 0;
442 sbp->seqno = 0;
443 sbp->hash = xfs_dir_hash_dot;
444 sbp->ino = dp->i_ino;
445 sbp->name = ".";
446 sbp->namelen = 1;
447 sbp++;
448
449 /*
450 * Entry 1 is ..
451 */
452 sbp->entno = 1;
453 sbp->seqno = 0;
454 sbp->hash = xfs_dir_hash_dotdot;
455 sbp->ino = XFS_GET_DIR_INO8(sf->hdr.parent);
456 sbp->name = "..";
457 sbp->namelen = 2;
458 sbp++;
459
460 /*
461 * Scan the directory data for the rest of the entries.
462 */
463 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
464
465 if (unlikely(
466 ((char *)sfe < (char *)sf) ||
467 ((char *)sfe >= ((char *)sf + dp->i_df.if_bytes)))) {
468 xfs_dir_trace_g_du("sf: corrupted", dp, uio);
469 XFS_CORRUPTION_ERROR("xfs_dir_shortform_getdents",
470 XFS_ERRLEVEL_LOW, mp, sfe);
471 kmem_free(sbuf, sbsize);
472 return XFS_ERROR(EFSCORRUPTED);
473 }
474
475 sbp->entno = i + 2;
476 sbp->seqno = 0;
477 sbp->hash = xfs_da_hashname((char *)sfe->name, sfe->namelen);
478 sbp->ino = XFS_GET_DIR_INO8(sfe->inumber);
479 sbp->name = (char *)sfe->name;
480 sbp->namelen = sfe->namelen;
481 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
482 sbp++;
483 }
484
485 /*
486 * Sort the entries on hash then entno.
487 */
488 xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_dir_shortform_compare);
489 /*
490 * Stuff in last entry.
491 */
492 sbp->entno = nsbuf;
493 sbp->hash = XFS_DA_MAXHASH;
494 sbp->seqno = 0;
495 /*
496 * Figure out the sequence numbers in case there's a hash duplicate.
497 */
498 for (hash = sbuf->hash, sbp = sbuf + 1;
499 sbp < &sbuf[nsbuf + 1]; sbp++) {
500 if (sbp->hash == hash)
501 sbp->seqno = sbp[-1].seqno + 1;
502 else
503 hash = sbp->hash;
504 }
505
506 /*
507 * Set up put routine.
508 */
509 p.dbp = dbp;
510 p.put = put;
511 p.uio = uio;
512
513 /*
514 * Find our place.
515 */
516 for (sbp = sbuf; sbp < &sbuf[nsbuf + 1]; sbp++) {
517 if (sbp->hash > cookhash ||
518 (sbp->hash == cookhash && sbp->seqno >= want_entno))
519 break;
520 }
521
522 /*
523 * Did we fail to find anything? We stop at the last entry,
524 * the one we put maxhash into.
525 */
526 if (sbp == &sbuf[nsbuf]) {
527 kmem_free(sbuf, sbsize);
528 xfs_dir_trace_g_du("sf: hash beyond end", dp, uio);
529 uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH);
530 *eofp = 1;
531 return 0;
532 }
533
534 /*
535 * Loop putting entries into the user buffer.
536 */
537 while (sbp < &sbuf[nsbuf]) {
538 /*
539 * Save the first resid in a run of equal-hashval entries
540 * so that we can back them out if they don't all fit.
541 */
542 if (sbp->seqno == 0 || sbp == sbuf)
543 lastresid = uio->uio_resid;
544 XFS_PUT_COOKIE(p.cook, mp, 0, sbp[1].seqno, sbp[1].hash);
545 p.ino = sbp->ino;
546#if XFS_BIG_INUMS
547 p.ino += mp->m_inoadd;
548#endif
549 p.name = sbp->name;
550 p.namelen = sbp->namelen;
551 retval = p.put(&p);
552 if (!p.done) {
553 uio->uio_offset =
554 XFS_DA_MAKE_COOKIE(mp, 0, 0, sbp->hash);
555 kmem_free(sbuf, sbsize);
556 uio->uio_resid = lastresid;
557 xfs_dir_trace_g_du("sf: E-O-B", dp, uio);
558 return retval;
559 }
560 sbp++;
561 }
562 kmem_free(sbuf, sbsize);
563 uio->uio_offset = p.cook.o;
564 *eofp = 1;
565 xfs_dir_trace_g_du("sf: E-O-F", dp, uio);
566 return 0;
567}
568
569/*
570 * Look up a name in a shortform directory structure, replace the inode number.
571 */
572int
573xfs_dir_shortform_replace(xfs_da_args_t *args)
574{
575 xfs_dir_shortform_t *sf;
576 xfs_dir_sf_entry_t *sfe;
577 xfs_inode_t *dp;
578 int i;
579
580 dp = args->dp;
581 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
582 /*
583 * Catch the case where the conversion from shortform to leaf
584 * failed part way through.
585 */
586 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
587 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
588 return XFS_ERROR(EIO);
589 }
590 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
591 ASSERT(dp->i_df.if_u1.if_data != NULL);
592 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
593 if (args->namelen == 2 &&
594 args->name[0] == '.' && args->name[1] == '.') {
595 /* XXX - replace assert? */
596 XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sf->hdr.parent);
597 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA);
598 return 0;
599 }
600 ASSERT(args->namelen != 1 || args->name[0] != '.');
601 sfe = &sf->list[0];
602 for (i = sf->hdr.count-1; i >= 0; i--) {
603 if (sfe->namelen == args->namelen &&
604 sfe->name[0] == args->name[0] &&
605 memcmp(args->name, sfe->name, args->namelen) == 0) {
606 ASSERT(memcmp((char *)&args->inumber,
607 (char *)&sfe->inumber, sizeof(xfs_ino_t)));
608 XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber);
609 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA);
610 return 0;
611 }
612 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
613 }
614 ASSERT(args->oknoent);
615 return XFS_ERROR(ENOENT);
616}
617
618/*
619 * Convert a leaf directory to shortform structure
620 */
621int
622xfs_dir_leaf_to_shortform(xfs_da_args_t *iargs)
623{
624 xfs_dir_leafblock_t *leaf;
625 xfs_dir_leaf_hdr_t *hdr;
626 xfs_dir_leaf_entry_t *entry;
627 xfs_dir_leaf_name_t *namest;
628 xfs_da_args_t args;
629 xfs_inode_t *dp;
630 xfs_ino_t parent = 0;
631 char *tmpbuffer;
632 int retval, i;
633 xfs_dabuf_t *bp;
634
635 dp = iargs->dp;
636 tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP);
637 ASSERT(tmpbuffer != NULL);
638
639 retval = xfs_da_read_buf(iargs->trans, iargs->dp, 0, -1, &bp,
640 XFS_DATA_FORK);
641 if (retval)
642 goto out;
643 ASSERT(bp != NULL);
644 memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount));
645 leaf = (xfs_dir_leafblock_t *)tmpbuffer;
646 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
647 memset(bp->data, 0, XFS_LBSIZE(dp->i_mount));
648
649 /*
650 * Find and special case the parent inode number
651 */
652 hdr = &leaf->hdr;
653 entry = &leaf->entries[0];
654 for (i = INT_GET(hdr->count, ARCH_CONVERT)-1; i >= 0; entry++, i--) {
655 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
656 if ((entry->namelen == 2) &&
657 (namest->name[0] == '.') &&
658 (namest->name[1] == '.')) {
659 XFS_DIR_SF_GET_DIRINO(&namest->inumber, &parent);
660 entry->nameidx = 0;
661 } else if ((entry->namelen == 1) && (namest->name[0] == '.')) {
662 entry->nameidx = 0;
663 }
664 }
665 retval = xfs_da_shrink_inode(iargs, 0, bp);
666 if (retval)
667 goto out;
668 retval = xfs_dir_shortform_create(iargs, parent);
669 if (retval)
670 goto out;
671
672 /*
673 * Copy the rest of the filenames
674 */
675 entry = &leaf->entries[0];
676 args.dp = dp;
677 args.firstblock = iargs->firstblock;
678 args.flist = iargs->flist;
679 args.total = iargs->total;
680 args.whichfork = XFS_DATA_FORK;
681 args.trans = iargs->trans;
682 args.justcheck = 0;
683 args.addname = args.oknoent = 1;
684 for (i = 0; i < INT_GET(hdr->count, ARCH_CONVERT); entry++, i++) {
685 if (!entry->nameidx)
686 continue;
687 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
688 args.name = (char *)(namest->name);
689 args.namelen = entry->namelen;
690 args.hashval = INT_GET(entry->hashval, ARCH_CONVERT);
691 XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args.inumber);
692 xfs_dir_shortform_addname(&args);
693 }
694
695out:
696 kmem_free(tmpbuffer, XFS_LBSIZE(dp->i_mount));
697 return retval;
698}
699
700/*
701 * Convert from using a single leaf to a root node and a leaf.
702 */
703int
704xfs_dir_leaf_to_node(xfs_da_args_t *args)
705{
706 xfs_dir_leafblock_t *leaf;
707 xfs_da_intnode_t *node;
708 xfs_inode_t *dp;
709 xfs_dabuf_t *bp1, *bp2;
710 xfs_dablk_t blkno;
711 int retval;
712
713 dp = args->dp;
714 retval = xfs_da_grow_inode(args, &blkno);
715 ASSERT(blkno == 1);
716 if (retval)
717 return retval;
718 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp1,
719 XFS_DATA_FORK);
720 if (retval)
721 return retval;
722 ASSERT(bp1 != NULL);
723 retval = xfs_da_get_buf(args->trans, args->dp, 1, -1, &bp2,
724 XFS_DATA_FORK);
725 if (retval) {
726 xfs_da_buf_done(bp1);
727 return retval;
728 }
729 ASSERT(bp2 != NULL);
730 memcpy(bp2->data, bp1->data, XFS_LBSIZE(dp->i_mount));
731 xfs_da_buf_done(bp1);
732 xfs_da_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1);
733
734 /*
735 * Set up the new root node.
736 */
737 retval = xfs_da_node_create(args, 0, 1, &bp1, XFS_DATA_FORK);
738 if (retval) {
739 xfs_da_buf_done(bp2);
740 return retval;
741 }
742 node = bp1->data;
743 leaf = bp2->data;
744 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
745 node->btree[0].hashval = cpu_to_be32(
746 INT_GET(leaf->entries[
747 INT_GET(leaf->hdr.count, ARCH_CONVERT)-1].hashval, ARCH_CONVERT));
748 xfs_da_buf_done(bp2);
749 node->btree[0].before = cpu_to_be32(blkno);
750 node->hdr.count = cpu_to_be16(1);
751 xfs_da_log_buf(args->trans, bp1,
752 XFS_DA_LOGRANGE(node, &node->btree[0], sizeof(node->btree[0])));
753 xfs_da_buf_done(bp1);
754
755 return retval;
756}
757
758
759/*========================================================================
760 * Routines used for growing the Btree.
761 *========================================================================*/
762
763/*
764 * Create the initial contents of a leaf directory
765 * or a leaf in a node directory.
766 */
767STATIC int
768xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp)
769{
770 xfs_dir_leafblock_t *leaf;
771 xfs_dir_leaf_hdr_t *hdr;
772 xfs_inode_t *dp;
773 xfs_dabuf_t *bp;
774 int retval;
775
776 dp = args->dp;
777 ASSERT(dp != NULL);
778 retval = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp, XFS_DATA_FORK);
779 if (retval)
780 return retval;
781 ASSERT(bp != NULL);
782 leaf = bp->data;
783 memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount));
784 hdr = &leaf->hdr;
785 hdr->info.magic = cpu_to_be16(XFS_DIR_LEAF_MAGIC);
786 INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount));
787 if (!hdr->firstused)
788 INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount) - 1);
789 INT_SET(hdr->freemap[0].base, ARCH_CONVERT, sizeof(xfs_dir_leaf_hdr_t));
790 INT_SET(hdr->freemap[0].size, ARCH_CONVERT, INT_GET(hdr->firstused, ARCH_CONVERT) - INT_GET(hdr->freemap[0].base, ARCH_CONVERT));
791
792 xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1);
793
794 *bpp = bp;
795 return 0;
796}
797
798/*
799 * Split the leaf node, rebalance, then add the new entry.
800 */
801int
802xfs_dir_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
803 xfs_da_state_blk_t *newblk)
804{
805 xfs_dablk_t blkno;
806 xfs_da_args_t *args;
807 int error;
808
809 /*
810 * Allocate space for a new leaf node.
811 */
812 args = state->args;
813 ASSERT(args != NULL);
814 ASSERT(oldblk->magic == XFS_DIR_LEAF_MAGIC);
815 error = xfs_da_grow_inode(args, &blkno);
816 if (error)
817 return error;
818 error = xfs_dir_leaf_create(args, blkno, &newblk->bp);
819 if (error)
820 return error;
821 newblk->blkno = blkno;
822 newblk->magic = XFS_DIR_LEAF_MAGIC;
823
824 /*
825 * Rebalance the entries across the two leaves.
826 */
827 xfs_dir_leaf_rebalance(state, oldblk, newblk);
828 error = xfs_da_blk_link(state, oldblk, newblk);
829 if (error)
830 return error;
831
832 /*
833 * Insert the new entry in the correct block.
834 */
835 if (state->inleaf) {
836 error = xfs_dir_leaf_add(oldblk->bp, args, oldblk->index);
837 } else {
838 error = xfs_dir_leaf_add(newblk->bp, args, newblk->index);
839 }
840
841 /*
842 * Update last hashval in each block since we added the name.
843 */
844 oldblk->hashval = xfs_dir_leaf_lasthash(oldblk->bp, NULL);
845 newblk->hashval = xfs_dir_leaf_lasthash(newblk->bp, NULL);
846 return error;
847}
848
849/*
850 * Add a name to the leaf directory structure.
851 *
852 * Must take into account fragmented leaves and leaves where spacemap has
853 * lost some freespace information (ie: holes).
854 */
855int
856xfs_dir_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index)
857{
858 xfs_dir_leafblock_t *leaf;
859 xfs_dir_leaf_hdr_t *hdr;
860 xfs_dir_leaf_map_t *map;
861 int tablesize, entsize, sum, i, tmp, error;
862
863 leaf = bp->data;
864 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
865 ASSERT((index >= 0) && (index <= INT_GET(leaf->hdr.count, ARCH_CONVERT)));
866 hdr = &leaf->hdr;
867 entsize = XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen);
868
869 /*
870 * Search through freemap for first-fit on new name length.
871 * (may need to figure in size of entry struct too)
872 */
873 tablesize = (INT_GET(hdr->count, ARCH_CONVERT) + 1) * (uint)sizeof(xfs_dir_leaf_entry_t)
874 + (uint)sizeof(xfs_dir_leaf_hdr_t);
875 map = &hdr->freemap[XFS_DIR_LEAF_MAPSIZE-1];
876 for (sum = 0, i = XFS_DIR_LEAF_MAPSIZE-1; i >= 0; map--, i--) {
877 if (tablesize > INT_GET(hdr->firstused, ARCH_CONVERT)) {
878 sum += INT_GET(map->size, ARCH_CONVERT);
879 continue;
880 }
881 if (!map->size)
882 continue; /* no space in this map */
883 tmp = entsize;
884 if (INT_GET(map->base, ARCH_CONVERT) < INT_GET(hdr->firstused, ARCH_CONVERT))
885 tmp += (uint)sizeof(xfs_dir_leaf_entry_t);
886 if (INT_GET(map->size, ARCH_CONVERT) >= tmp) {
887 if (!args->justcheck)
888 xfs_dir_leaf_add_work(bp, args, index, i);
889 return 0;
890 }
891 sum += INT_GET(map->size, ARCH_CONVERT);
892 }
893
894 /*
895 * If there are no holes in the address space of the block,
896 * and we don't have enough freespace, then compaction will do us
897 * no good and we should just give up.
898 */
899 if (!hdr->holes && (sum < entsize))
900 return XFS_ERROR(ENOSPC);
901
902 /*
903 * Compact the entries to coalesce free space.
904 * Pass the justcheck flag so the checking pass can return
905 * an error, without changing anything, if it won't fit.
906 */
907 error = xfs_dir_leaf_compact(args->trans, bp,
908 args->total == 0 ?
909 entsize +
910 (uint)sizeof(xfs_dir_leaf_entry_t) : 0,
911 args->justcheck);
912 if (error)
913 return error;
914 /*
915 * After compaction, the block is guaranteed to have only one
916 * free region, in freemap[0]. If it is not big enough, give up.
917 */
918 if (INT_GET(hdr->freemap[0].size, ARCH_CONVERT) <
919 (entsize + (uint)sizeof(xfs_dir_leaf_entry_t)))
920 return XFS_ERROR(ENOSPC);
921
922 if (!args->justcheck)
923 xfs_dir_leaf_add_work(bp, args, index, 0);
924 return 0;
925}
926
927/*
928 * Add a name to a leaf directory structure.
929 */
930STATIC void
931xfs_dir_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int index,
932 int mapindex)
933{
934 xfs_dir_leafblock_t *leaf;
935 xfs_dir_leaf_hdr_t *hdr;
936 xfs_dir_leaf_entry_t *entry;
937 xfs_dir_leaf_name_t *namest;
938 xfs_dir_leaf_map_t *map;
939 /* REFERENCED */
940 xfs_mount_t *mp;
941 int tmp, i;
942
943 leaf = bp->data;
944 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
945 hdr = &leaf->hdr;
946 ASSERT((mapindex >= 0) && (mapindex < XFS_DIR_LEAF_MAPSIZE));
947 ASSERT((index >= 0) && (index <= INT_GET(hdr->count, ARCH_CONVERT)));
948
949 /*
950 * Force open some space in the entry array and fill it in.
951 */
952 entry = &leaf->entries[index];
953 if (index < INT_GET(hdr->count, ARCH_CONVERT)) {
954 tmp = INT_GET(hdr->count, ARCH_CONVERT) - index;
955 tmp *= (uint)sizeof(xfs_dir_leaf_entry_t);
956 memmove(entry + 1, entry, tmp);
957 xfs_da_log_buf(args->trans, bp,
958 XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry)));
959 }
960 INT_MOD(hdr->count, ARCH_CONVERT, +1);
961
962 /*
963 * Allocate space for the new string (at the end of the run).
964 */
965 map = &hdr->freemap[mapindex];
966 mp = args->trans->t_mountp;
967 ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp));
968 ASSERT(INT_GET(map->size, ARCH_CONVERT) >= XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen));
969 ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp));
970 INT_MOD(map->size, ARCH_CONVERT, -(XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen)));
971 INT_SET(entry->nameidx, ARCH_CONVERT, INT_GET(map->base, ARCH_CONVERT) + INT_GET(map->size, ARCH_CONVERT));
972 INT_SET(entry->hashval, ARCH_CONVERT, args->hashval);
973 entry->namelen = args->namelen;
974 xfs_da_log_buf(args->trans, bp,
975 XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
976
977 /*
978 * Copy the string and inode number into the new space.
979 */
980 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
981 XFS_DIR_SF_PUT_DIRINO(&args->inumber, &namest->inumber);
982 memcpy(namest->name, args->name, args->namelen);
983 xfs_da_log_buf(args->trans, bp,
984 XFS_DA_LOGRANGE(leaf, namest, XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry)));
985
986 /*
987 * Update the control info for this leaf node
988 */
989 if (INT_GET(entry->nameidx, ARCH_CONVERT) < INT_GET(hdr->firstused, ARCH_CONVERT))
990 INT_COPY(hdr->firstused, entry->nameidx, ARCH_CONVERT);
991 ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) >= ((INT_GET(hdr->count, ARCH_CONVERT)*sizeof(*entry))+sizeof(*hdr)));
992 tmp = (INT_GET(hdr->count, ARCH_CONVERT)-1) * (uint)sizeof(xfs_dir_leaf_entry_t)
993 + (uint)sizeof(xfs_dir_leaf_hdr_t);
994 map = &hdr->freemap[0];
995 for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) {
996 if (INT_GET(map->base, ARCH_CONVERT) == tmp) {
997 INT_MOD(map->base, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_entry_t));
998 INT_MOD(map->size, ARCH_CONVERT, -((uint)sizeof(xfs_dir_leaf_entry_t)));
999 }
1000 }
1001 INT_MOD(hdr->namebytes, ARCH_CONVERT, args->namelen);
1002 xfs_da_log_buf(args->trans, bp,
1003 XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
1004}
1005
1006/*
1007 * Garbage collect a leaf directory block by copying it to a new buffer.
1008 */
1009STATIC int
1010xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp, int musthave,
1011 int justcheck)
1012{
1013 xfs_dir_leafblock_t *leaf_s, *leaf_d;
1014 xfs_dir_leaf_hdr_t *hdr_s, *hdr_d;
1015 xfs_mount_t *mp;
1016 char *tmpbuffer;
1017 char *tmpbuffer2=NULL;
1018 int rval;
1019 int lbsize;
1020
1021 mp = trans->t_mountp;
1022 lbsize = XFS_LBSIZE(mp);
1023 tmpbuffer = kmem_alloc(lbsize, KM_SLEEP);
1024 ASSERT(tmpbuffer != NULL);
1025 memcpy(tmpbuffer, bp->data, lbsize);
1026
1027 /*
1028 * Make a second copy in case xfs_dir_leaf_moveents()
1029 * below destroys the original.
1030 */
1031 if (musthave || justcheck) {
1032 tmpbuffer2 = kmem_alloc(lbsize, KM_SLEEP);
1033 memcpy(tmpbuffer2, bp->data, lbsize);
1034 }
1035 memset(bp->data, 0, lbsize);
1036
1037 /*
1038 * Copy basic information
1039 */
1040 leaf_s = (xfs_dir_leafblock_t *)tmpbuffer;
1041 leaf_d = bp->data;
1042 hdr_s = &leaf_s->hdr;
1043 hdr_d = &leaf_d->hdr;
1044 hdr_d->info = hdr_s->info; /* struct copy */
1045 INT_SET(hdr_d->firstused, ARCH_CONVERT, lbsize);
1046 if (!hdr_d->firstused)
1047 INT_SET(hdr_d->firstused, ARCH_CONVERT, lbsize - 1);
1048 hdr_d->namebytes = 0;
1049 hdr_d->count = 0;
1050 hdr_d->holes = 0;
1051 INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, sizeof(xfs_dir_leaf_hdr_t));
1052 INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, INT_GET(hdr_d->firstused, ARCH_CONVERT) - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT));
1053
1054 /*
1055 * Copy all entry's in the same (sorted) order,
1056 * but allocate filenames packed and in sequence.
1057 * This changes the source (leaf_s) as well.
1058 */
1059 xfs_dir_leaf_moveents(leaf_s, 0, leaf_d, 0, (int)INT_GET(hdr_s->count, ARCH_CONVERT), mp);
1060
1061 if (musthave && INT_GET(hdr_d->freemap[0].size, ARCH_CONVERT) < musthave)
1062 rval = XFS_ERROR(ENOSPC);
1063 else
1064 rval = 0;
1065
1066 if (justcheck || rval == ENOSPC) {
1067 ASSERT(tmpbuffer2);
1068 memcpy(bp->data, tmpbuffer2, lbsize);
1069 } else {
1070 xfs_da_log_buf(trans, bp, 0, lbsize - 1);
1071 }
1072
1073 kmem_free(tmpbuffer, lbsize);
1074 if (musthave || justcheck)
1075 kmem_free(tmpbuffer2, lbsize);
1076 return rval;
1077}
1078
1079/*
1080 * Redistribute the directory entries between two leaf nodes,
1081 * taking into account the size of the new entry.
1082 *
1083 * NOTE: if new block is empty, then it will get the upper half of old block.
1084 */
1085STATIC void
1086xfs_dir_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
1087 xfs_da_state_blk_t *blk2)
1088{
1089 xfs_da_state_blk_t *tmp_blk;
1090 xfs_dir_leafblock_t *leaf1, *leaf2;
1091 xfs_dir_leaf_hdr_t *hdr1, *hdr2;
1092 int count, totallen, max, space, swap;
1093
1094 /*
1095 * Set up environment.
1096 */
1097 ASSERT(blk1->magic == XFS_DIR_LEAF_MAGIC);
1098 ASSERT(blk2->magic == XFS_DIR_LEAF_MAGIC);
1099 leaf1 = blk1->bp->data;
1100 leaf2 = blk2->bp->data;
1101 ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1102 ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1103
1104 /*
1105 * Check ordering of blocks, reverse if it makes things simpler.
1106 */
1107 swap = 0;
1108 if (xfs_dir_leaf_order(blk1->bp, blk2->bp)) {
1109 tmp_blk = blk1;
1110 blk1 = blk2;
1111 blk2 = tmp_blk;
1112 leaf1 = blk1->bp->data;
1113 leaf2 = blk2->bp->data;
1114 swap = 1;
1115 }
1116 hdr1 = &leaf1->hdr;
1117 hdr2 = &leaf2->hdr;
1118
1119 /*
1120 * Examine entries until we reduce the absolute difference in
1121 * byte usage between the two blocks to a minimum. Then get
1122 * the direction to copy and the number of elements to move.
1123 */
1124 state->inleaf = xfs_dir_leaf_figure_balance(state, blk1, blk2,
1125 &count, &totallen);
1126 if (swap)
1127 state->inleaf = !state->inleaf;
1128
1129 /*
1130 * Move any entries required from leaf to leaf:
1131 */
1132 if (count < INT_GET(hdr1->count, ARCH_CONVERT)) {
1133 /*
1134 * Figure the total bytes to be added to the destination leaf.
1135 */
1136 count = INT_GET(hdr1->count, ARCH_CONVERT) - count; /* number entries being moved */
1137 space = INT_GET(hdr1->namebytes, ARCH_CONVERT) - totallen;
1138 space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1);
1139 space += count * (uint)sizeof(xfs_dir_leaf_entry_t);
1140
1141 /*
1142 * leaf2 is the destination, compact it if it looks tight.
1143 */
1144 max = INT_GET(hdr2->firstused, ARCH_CONVERT) - (uint)sizeof(xfs_dir_leaf_hdr_t);
1145 max -= INT_GET(hdr2->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t);
1146 if (space > max) {
1147 xfs_dir_leaf_compact(state->args->trans, blk2->bp,
1148 0, 0);
1149 }
1150
1151 /*
1152 * Move high entries from leaf1 to low end of leaf2.
1153 */
1154 xfs_dir_leaf_moveents(leaf1, INT_GET(hdr1->count, ARCH_CONVERT) - count,
1155 leaf2, 0, count, state->mp);
1156
1157 xfs_da_log_buf(state->args->trans, blk1->bp, 0,
1158 state->blocksize-1);
1159 xfs_da_log_buf(state->args->trans, blk2->bp, 0,
1160 state->blocksize-1);
1161
1162 } else if (count > INT_GET(hdr1->count, ARCH_CONVERT)) {
1163 /*
1164 * Figure the total bytes to be added to the destination leaf.
1165 */
1166 count -= INT_GET(hdr1->count, ARCH_CONVERT); /* number entries being moved */
1167 space = totallen - INT_GET(hdr1->namebytes, ARCH_CONVERT);
1168 space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1);
1169 space += count * (uint)sizeof(xfs_dir_leaf_entry_t);
1170
1171 /*
1172 * leaf1 is the destination, compact it if it looks tight.
1173 */
1174 max = INT_GET(hdr1->firstused, ARCH_CONVERT) - (uint)sizeof(xfs_dir_leaf_hdr_t);
1175 max -= INT_GET(hdr1->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t);
1176 if (space > max) {
1177 xfs_dir_leaf_compact(state->args->trans, blk1->bp,
1178 0, 0);
1179 }
1180
1181 /*
1182 * Move low entries from leaf2 to high end of leaf1.
1183 */
1184 xfs_dir_leaf_moveents(leaf2, 0, leaf1, (int)INT_GET(hdr1->count, ARCH_CONVERT),
1185 count, state->mp);
1186
1187 xfs_da_log_buf(state->args->trans, blk1->bp, 0,
1188 state->blocksize-1);
1189 xfs_da_log_buf(state->args->trans, blk2->bp, 0,
1190 state->blocksize-1);
1191 }
1192
1193 /*
1194 * Copy out last hashval in each block for B-tree code.
1195 */
1196 blk1->hashval = INT_GET(leaf1->entries[ INT_GET(leaf1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
1197 blk2->hashval = INT_GET(leaf2->entries[ INT_GET(leaf2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
1198
1199 /*
1200 * Adjust the expected index for insertion.
1201 * GROT: this doesn't work unless blk2 was originally empty.
1202 */
1203 if (!state->inleaf) {
1204 blk2->index = blk1->index - INT_GET(leaf1->hdr.count, ARCH_CONVERT);
1205 }
1206}
1207
1208/*
1209 * Examine entries until we reduce the absolute difference in
1210 * byte usage between the two blocks to a minimum.
1211 * GROT: Is this really necessary? With other than a 512 byte blocksize,
1212 * GROT: there will always be enough room in either block for a new entry.
1213 * GROT: Do a double-split for this case?
1214 */
1215STATIC int
1216xfs_dir_leaf_figure_balance(xfs_da_state_t *state,
1217 xfs_da_state_blk_t *blk1,
1218 xfs_da_state_blk_t *blk2,
1219 int *countarg, int *namebytesarg)
1220{
1221 xfs_dir_leafblock_t *leaf1, *leaf2;
1222 xfs_dir_leaf_hdr_t *hdr1, *hdr2;
1223 xfs_dir_leaf_entry_t *entry;
1224 int count, max, totallen, half;
1225 int lastdelta, foundit, tmp;
1226
1227 /*
1228 * Set up environment.
1229 */
1230 leaf1 = blk1->bp->data;
1231 leaf2 = blk2->bp->data;
1232 hdr1 = &leaf1->hdr;
1233 hdr2 = &leaf2->hdr;
1234 foundit = 0;
1235 totallen = 0;
1236
1237 /*
1238 * Examine entries until we reduce the absolute difference in
1239 * byte usage between the two blocks to a minimum.
1240 */
1241 max = INT_GET(hdr1->count, ARCH_CONVERT) + INT_GET(hdr2->count, ARCH_CONVERT);
1242 half = (max+1) * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1);
1243 half += INT_GET(hdr1->namebytes, ARCH_CONVERT) + INT_GET(hdr2->namebytes, ARCH_CONVERT) + state->args->namelen;
1244 half /= 2;
1245 lastdelta = state->blocksize;
1246 entry = &leaf1->entries[0];
1247 for (count = 0; count < max; entry++, count++) {
1248
1249#define XFS_DIR_ABS(A) (((A) < 0) ? -(A) : (A))
1250 /*
1251 * The new entry is in the first block, account for it.
1252 */
1253 if (count == blk1->index) {
1254 tmp = totallen + (uint)sizeof(*entry)
1255 + XFS_DIR_LEAF_ENTSIZE_BYNAME(state->args->namelen);
1256 if (XFS_DIR_ABS(half - tmp) > lastdelta)
1257 break;
1258 lastdelta = XFS_DIR_ABS(half - tmp);
1259 totallen = tmp;
1260 foundit = 1;
1261 }
1262
1263 /*
1264 * Wrap around into the second block if necessary.
1265 */
1266 if (count == INT_GET(hdr1->count, ARCH_CONVERT)) {
1267 leaf1 = leaf2;
1268 entry = &leaf1->entries[0];
1269 }
1270
1271 /*
1272 * Figure out if next leaf entry would be too much.
1273 */
1274 tmp = totallen + (uint)sizeof(*entry)
1275 + XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry);
1276 if (XFS_DIR_ABS(half - tmp) > lastdelta)
1277 break;
1278 lastdelta = XFS_DIR_ABS(half - tmp);
1279 totallen = tmp;
1280#undef XFS_DIR_ABS
1281 }
1282
1283 /*
1284 * Calculate the number of namebytes that will end up in lower block.
1285 * If new entry not in lower block, fix up the count.
1286 */
1287 totallen -=
1288 count * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1);
1289 if (foundit) {
1290 totallen -= (sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1) +
1291 state->args->namelen;
1292 }
1293
1294 *countarg = count;
1295 *namebytesarg = totallen;
1296 return foundit;
1297}
1298
1299/*========================================================================
1300 * Routines used for shrinking the Btree.
1301 *========================================================================*/
1302
1303/*
1304 * Check a leaf block and its neighbors to see if the block should be
1305 * collapsed into one or the other neighbor. Always keep the block
1306 * with the smaller block number.
1307 * If the current block is over 50% full, don't try to join it, return 0.
1308 * If the block is empty, fill in the state structure and return 2.
1309 * If it can be collapsed, fill in the state structure and return 1.
1310 * If nothing can be done, return 0.
1311 */
1312int
1313xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action)
1314{
1315 xfs_dir_leafblock_t *leaf;
1316 xfs_da_state_blk_t *blk;
1317 xfs_da_blkinfo_t *info;
1318 int count, bytes, forward, error, retval, i;
1319 xfs_dablk_t blkno;
1320 xfs_dabuf_t *bp;
1321
1322 /*
1323 * Check for the degenerate case of the block being over 50% full.
1324 * If so, it's not worth even looking to see if we might be able
1325 * to coalesce with a sibling.
1326 */
1327 blk = &state->path.blk[ state->path.active-1 ];
1328 info = blk->bp->data;
1329 ASSERT(be16_to_cpu(info->magic) == XFS_DIR_LEAF_MAGIC);
1330 leaf = (xfs_dir_leafblock_t *)info;
1331 count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
1332 bytes = (uint)sizeof(xfs_dir_leaf_hdr_t) +
1333 count * (uint)sizeof(xfs_dir_leaf_entry_t) +
1334 count * ((uint)sizeof(xfs_dir_leaf_name_t)-1) +
1335 INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
1336 if (bytes > (state->blocksize >> 1)) {
1337 *action = 0; /* blk over 50%, don't try to join */
1338 return 0;
1339 }
1340
1341 /*
1342 * Check for the degenerate case of the block being empty.
1343 * If the block is empty, we'll simply delete it, no need to
1344 * coalesce it with a sibling block. We choose (arbitrarily)
1345 * to merge with the forward block unless it is NULL.
1346 */
1347 if (count == 0) {
1348 /*
1349 * Make altpath point to the block we want to keep and
1350 * path point to the block we want to drop (this one).
1351 */
1352 forward = (info->forw != 0);
1353 memcpy(&state->altpath, &state->path, sizeof(state->path));
1354 error = xfs_da_path_shift(state, &state->altpath, forward,
1355 0, &retval);
1356 if (error)
1357 return error;
1358 if (retval) {
1359 *action = 0;
1360 } else {
1361 *action = 2;
1362 }
1363 return 0;
1364 }
1365
1366 /*
1367 * Examine each sibling block to see if we can coalesce with
1368 * at least 25% free space to spare. We need to figure out
1369 * whether to merge with the forward or the backward block.
1370 * We prefer coalescing with the lower numbered sibling so as
1371 * to shrink a directory over time.
1372 */
1373 forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); /* start with smaller blk num */
1374 for (i = 0; i < 2; forward = !forward, i++) {
1375 if (forward)
1376 blkno = be32_to_cpu(info->forw);
1377 else
1378 blkno = be32_to_cpu(info->back);
1379 if (blkno == 0)
1380 continue;
1381 error = xfs_da_read_buf(state->args->trans, state->args->dp,
1382 blkno, -1, &bp,
1383 XFS_DATA_FORK);
1384 if (error)
1385 return error;
1386 ASSERT(bp != NULL);
1387
1388 leaf = (xfs_dir_leafblock_t *)info;
1389 count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
1390 bytes = state->blocksize - (state->blocksize>>2);
1391 bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
1392 leaf = bp->data;
1393 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1394 count += INT_GET(leaf->hdr.count, ARCH_CONVERT);
1395 bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
1396 bytes -= count * ((uint)sizeof(xfs_dir_leaf_name_t) - 1);
1397 bytes -= count * (uint)sizeof(xfs_dir_leaf_entry_t);
1398 bytes -= (uint)sizeof(xfs_dir_leaf_hdr_t);
1399 if (bytes >= 0)
1400 break; /* fits with at least 25% to spare */
1401
1402 xfs_da_brelse(state->args->trans, bp);
1403 }
1404 if (i >= 2) {
1405 *action = 0;
1406 return 0;
1407 }
1408 xfs_da_buf_done(bp);
1409
1410 /*
1411 * Make altpath point to the block we want to keep (the lower
1412 * numbered block) and path point to the block we want to drop.
1413 */
1414 memcpy(&state->altpath, &state->path, sizeof(state->path));
1415 if (blkno < blk->blkno) {
1416 error = xfs_da_path_shift(state, &state->altpath, forward,
1417 0, &retval);
1418 } else {
1419 error = xfs_da_path_shift(state, &state->path, forward,
1420 0, &retval);
1421 }
1422 if (error)
1423 return error;
1424 if (retval) {
1425 *action = 0;
1426 } else {
1427 *action = 1;
1428 }
1429 return 0;
1430}
1431
1432/*
1433 * Remove a name from the leaf directory structure.
1434 *
1435 * Return 1 if leaf is less than 37% full, 0 if >= 37% full.
1436 * If two leaves are 37% full, when combined they will leave 25% free.
1437 */
1438int
1439xfs_dir_leaf_remove(xfs_trans_t *trans, xfs_dabuf_t *bp, int index)
1440{
1441 xfs_dir_leafblock_t *leaf;
1442 xfs_dir_leaf_hdr_t *hdr;
1443 xfs_dir_leaf_map_t *map;
1444 xfs_dir_leaf_entry_t *entry;
1445 xfs_dir_leaf_name_t *namest;
1446 int before, after, smallest, entsize;
1447 int tablesize, tmp, i;
1448 xfs_mount_t *mp;
1449
1450 leaf = bp->data;
1451 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1452 hdr = &leaf->hdr;
1453 mp = trans->t_mountp;
1454 ASSERT((INT_GET(hdr->count, ARCH_CONVERT) > 0) && (INT_GET(hdr->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8)));
1455 ASSERT((index >= 0) && (index < INT_GET(hdr->count, ARCH_CONVERT)));
1456 ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) >= ((INT_GET(hdr->count, ARCH_CONVERT)*sizeof(*entry))+sizeof(*hdr)));
1457 entry = &leaf->entries[index];
1458 ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) >= INT_GET(hdr->firstused, ARCH_CONVERT));
1459 ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) < XFS_LBSIZE(mp));
1460
1461 /*
1462 * Scan through free region table:
1463 * check for adjacency of free'd entry with an existing one,
1464 * find smallest free region in case we need to replace it,
1465 * adjust any map that borders the entry table,
1466 */
1467 tablesize = INT_GET(hdr->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t)
1468 + (uint)sizeof(xfs_dir_leaf_hdr_t);
1469 map = &hdr->freemap[0];
1470 tmp = INT_GET(map->size, ARCH_CONVERT);
1471 before = after = -1;
1472 smallest = XFS_DIR_LEAF_MAPSIZE - 1;
1473 entsize = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry);
1474 for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) {
1475 ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp));
1476 ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp));
1477 if (INT_GET(map->base, ARCH_CONVERT) == tablesize) {
1478 INT_MOD(map->base, ARCH_CONVERT, -((uint)sizeof(xfs_dir_leaf_entry_t)));
1479 INT_MOD(map->size, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_entry_t));
1480 }
1481
1482 if ((INT_GET(map->base, ARCH_CONVERT) + INT_GET(map->size, ARCH_CONVERT)) == INT_GET(entry->nameidx, ARCH_CONVERT)) {
1483 before = i;
1484 } else if (INT_GET(map->base, ARCH_CONVERT) == (INT_GET(entry->nameidx, ARCH_CONVERT) + entsize)) {
1485 after = i;
1486 } else if (INT_GET(map->size, ARCH_CONVERT) < tmp) {
1487 tmp = INT_GET(map->size, ARCH_CONVERT);
1488 smallest = i;
1489 }
1490 }
1491
1492 /*
1493 * Coalesce adjacent freemap regions,
1494 * or replace the smallest region.
1495 */
1496 if ((before >= 0) || (after >= 0)) {
1497 if ((before >= 0) && (after >= 0)) {
1498 map = &hdr->freemap[before];
1499 INT_MOD(map->size, ARCH_CONVERT, entsize);
1500 INT_MOD(map->size, ARCH_CONVERT, INT_GET(hdr->freemap[after].size, ARCH_CONVERT));
1501 hdr->freemap[after].base = 0;
1502 hdr->freemap[after].size = 0;
1503 } else if (before >= 0) {
1504 map = &hdr->freemap[before];
1505 INT_MOD(map->size, ARCH_CONVERT, entsize);
1506 } else {
1507 map = &hdr->freemap[after];
1508 INT_COPY(map->base, entry->nameidx, ARCH_CONVERT);
1509 INT_MOD(map->size, ARCH_CONVERT, entsize);
1510 }
1511 } else {
1512 /*
1513 * Replace smallest region (if it is smaller than free'd entry)
1514 */
1515 map = &hdr->freemap[smallest];
1516 if (INT_GET(map->size, ARCH_CONVERT) < entsize) {
1517 INT_COPY(map->base, entry->nameidx, ARCH_CONVERT);
1518 INT_SET(map->size, ARCH_CONVERT, entsize);
1519 }
1520 }
1521
1522 /*
1523 * Did we remove the first entry?
1524 */
1525 if (INT_GET(entry->nameidx, ARCH_CONVERT) == INT_GET(hdr->firstused, ARCH_CONVERT))
1526 smallest = 1;
1527 else
1528 smallest = 0;
1529
1530 /*
1531 * Compress the remaining entries and zero out the removed stuff.
1532 */
1533 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
1534 memset((char *)namest, 0, entsize);
1535 xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, namest, entsize));
1536
1537 INT_MOD(hdr->namebytes, ARCH_CONVERT, -(entry->namelen));
1538 tmp = (INT_GET(hdr->count, ARCH_CONVERT) - index) * (uint)sizeof(xfs_dir_leaf_entry_t);
1539 memmove(entry, entry + 1, tmp);
1540 INT_MOD(hdr->count, ARCH_CONVERT, -1);
1541 xfs_da_log_buf(trans, bp,
1542 XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry)));
1543 entry = &leaf->entries[INT_GET(hdr->count, ARCH_CONVERT)];
1544 memset((char *)entry, 0, sizeof(xfs_dir_leaf_entry_t));
1545
1546 /*
1547 * If we removed the first entry, re-find the first used byte
1548 * in the name area. Note that if the entry was the "firstused",
1549 * then we don't have a "hole" in our block resulting from
1550 * removing the name.
1551 */
1552 if (smallest) {
1553 tmp = XFS_LBSIZE(mp);
1554 entry = &leaf->entries[0];
1555 for (i = INT_GET(hdr->count, ARCH_CONVERT)-1; i >= 0; entry++, i--) {
1556 ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) >= INT_GET(hdr->firstused, ARCH_CONVERT));
1557 ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) < XFS_LBSIZE(mp));
1558 if (INT_GET(entry->nameidx, ARCH_CONVERT) < tmp)
1559 tmp = INT_GET(entry->nameidx, ARCH_CONVERT);
1560 }
1561 INT_SET(hdr->firstused, ARCH_CONVERT, tmp);
1562 if (!hdr->firstused)
1563 INT_SET(hdr->firstused, ARCH_CONVERT, tmp - 1);
1564 } else {
1565 hdr->holes = 1; /* mark as needing compaction */
1566 }
1567
1568 xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
1569
1570 /*
1571 * Check if leaf is less than 50% full, caller may want to
1572 * "join" the leaf with a sibling if so.
1573 */
1574 tmp = (uint)sizeof(xfs_dir_leaf_hdr_t);
1575 tmp += INT_GET(leaf->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t);
1576 tmp += INT_GET(leaf->hdr.count, ARCH_CONVERT) * ((uint)sizeof(xfs_dir_leaf_name_t) - 1);
1577 tmp += INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
1578 if (tmp < mp->m_dir_magicpct)
1579 return 1; /* leaf is < 37% full */
1580 return 0;
1581}
1582
1583/*
1584 * Move all the directory entries from drop_leaf into save_leaf.
1585 */
1586void
1587xfs_dir_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
1588 xfs_da_state_blk_t *save_blk)
1589{
1590 xfs_dir_leafblock_t *drop_leaf, *save_leaf, *tmp_leaf;
1591 xfs_dir_leaf_hdr_t *drop_hdr, *save_hdr, *tmp_hdr;
1592 xfs_mount_t *mp;
1593 char *tmpbuffer;
1594
1595 /*
1596 * Set up environment.
1597 */
1598 mp = state->mp;
1599 ASSERT(drop_blk->magic == XFS_DIR_LEAF_MAGIC);
1600 ASSERT(save_blk->magic == XFS_DIR_LEAF_MAGIC);
1601 drop_leaf = drop_blk->bp->data;
1602 save_leaf = save_blk->bp->data;
1603 ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1604 ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1605 drop_hdr = &drop_leaf->hdr;
1606 save_hdr = &save_leaf->hdr;
1607
1608 /*
1609 * Save last hashval from dying block for later Btree fixup.
1610 */
1611 drop_blk->hashval = INT_GET(drop_leaf->entries[ drop_leaf->hdr.count-1 ].hashval, ARCH_CONVERT);
1612
1613 /*
1614 * Check if we need a temp buffer, or can we do it in place.
1615 * Note that we don't check "leaf" for holes because we will
1616 * always be dropping it, toosmall() decided that for us already.
1617 */
1618 if (save_hdr->holes == 0) {
1619 /*
1620 * dest leaf has no holes, so we add there. May need
1621 * to make some room in the entry array.
1622 */
1623 if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) {
1624 xfs_dir_leaf_moveents(drop_leaf, 0, save_leaf, 0,
1625 (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
1626 } else {
1627 xfs_dir_leaf_moveents(drop_leaf, 0,
1628 save_leaf, INT_GET(save_hdr->count, ARCH_CONVERT),
1629 (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
1630 }
1631 } else {
1632 /*
1633 * Destination has holes, so we make a temporary copy
1634 * of the leaf and add them both to that.
1635 */
1636 tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP);
1637 ASSERT(tmpbuffer != NULL);
1638 memset(tmpbuffer, 0, state->blocksize);
1639 tmp_leaf = (xfs_dir_leafblock_t *)tmpbuffer;
1640 tmp_hdr = &tmp_leaf->hdr;
1641 tmp_hdr->info = save_hdr->info; /* struct copy */
1642 tmp_hdr->count = 0;
1643 INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize);
1644 if (!tmp_hdr->firstused)
1645 INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize - 1);
1646 tmp_hdr->namebytes = 0;
1647 if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) {
1648 xfs_dir_leaf_moveents(drop_leaf, 0, tmp_leaf, 0,
1649 (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
1650 xfs_dir_leaf_moveents(save_leaf, 0,
1651 tmp_leaf, INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT),
1652 (int)INT_GET(save_hdr->count, ARCH_CONVERT), mp);
1653 } else {
1654 xfs_dir_leaf_moveents(save_leaf, 0, tmp_leaf, 0,
1655 (int)INT_GET(save_hdr->count, ARCH_CONVERT), mp);
1656 xfs_dir_leaf_moveents(drop_leaf, 0,
1657 tmp_leaf, INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT),
1658 (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
1659 }
1660 memcpy(save_leaf, tmp_leaf, state->blocksize);
1661 kmem_free(tmpbuffer, state->blocksize);
1662 }
1663
1664 xfs_da_log_buf(state->args->trans, save_blk->bp, 0,
1665 state->blocksize - 1);
1666
1667 /*
1668 * Copy out last hashval in each block for B-tree code.
1669 */
1670 save_blk->hashval = INT_GET(save_leaf->entries[ INT_GET(save_leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
1671}
1672
1673/*========================================================================
1674 * Routines used for finding things in the Btree.
1675 *========================================================================*/
1676
1677/*
1678 * Look up a name in a leaf directory structure.
1679 * This is the internal routine, it uses the caller's buffer.
1680 *
1681 * Note that duplicate keys are allowed, but only check within the
1682 * current leaf node. The Btree code must check in adjacent leaf nodes.
1683 *
1684 * Return in *index the index into the entry[] array of either the found
1685 * entry, or where the entry should have been (insert before that entry).
1686 *
1687 * Don't change the args->inumber unless we find the filename.
1688 */
1689int
1690xfs_dir_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args, int *index)
1691{
1692 xfs_dir_leafblock_t *leaf;
1693 xfs_dir_leaf_entry_t *entry;
1694 xfs_dir_leaf_name_t *namest;
1695 int probe, span;
1696 xfs_dahash_t hashval;
1697
1698 leaf = bp->data;
1699 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1700 ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) < (XFS_LBSIZE(args->dp->i_mount)/8));
1701
1702 /*
1703 * Binary search. (note: small blocks will skip this loop)
1704 */
1705 hashval = args->hashval;
1706 probe = span = INT_GET(leaf->hdr.count, ARCH_CONVERT) / 2;
1707 for (entry = &leaf->entries[probe]; span > 4;
1708 entry = &leaf->entries[probe]) {
1709 span /= 2;
1710 if (INT_GET(entry->hashval, ARCH_CONVERT) < hashval)
1711 probe += span;
1712 else if (INT_GET(entry->hashval, ARCH_CONVERT) > hashval)
1713 probe -= span;
1714 else
1715 break;
1716 }
1717 ASSERT((probe >= 0) && \
1718 ((!leaf->hdr.count) || (probe < INT_GET(leaf->hdr.count, ARCH_CONVERT))));
1719 ASSERT((span <= 4) || (INT_GET(entry->hashval, ARCH_CONVERT) == hashval));
1720
1721 /*
1722 * Since we may have duplicate hashval's, find the first matching
1723 * hashval in the leaf.
1724 */
1725 while ((probe > 0) && (INT_GET(entry->hashval, ARCH_CONVERT) >= hashval)) {
1726 entry--;
1727 probe--;
1728 }
1729 while ((probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) && (INT_GET(entry->hashval, ARCH_CONVERT) < hashval)) {
1730 entry++;
1731 probe++;
1732 }
1733 if ((probe == INT_GET(leaf->hdr.count, ARCH_CONVERT)) || (INT_GET(entry->hashval, ARCH_CONVERT) != hashval)) {
1734 *index = probe;
1735 ASSERT(args->oknoent);
1736 return XFS_ERROR(ENOENT);
1737 }
1738
1739 /*
1740 * Duplicate keys may be present, so search all of them for a match.
1741 */
1742 while ((probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) && (INT_GET(entry->hashval, ARCH_CONVERT) == hashval)) {
1743 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
1744 if (entry->namelen == args->namelen &&
1745 namest->name[0] == args->name[0] &&
1746 memcmp(args->name, namest->name, args->namelen) == 0) {
1747 XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args->inumber);
1748 *index = probe;
1749 return XFS_ERROR(EEXIST);
1750 }
1751 entry++;
1752 probe++;
1753 }
1754 *index = probe;
1755 ASSERT(probe == INT_GET(leaf->hdr.count, ARCH_CONVERT) || args->oknoent);
1756 return XFS_ERROR(ENOENT);
1757}
1758
1759/*========================================================================
1760 * Utility routines.
1761 *========================================================================*/
1762
1763/*
1764 * Move the indicated entries from one leaf to another.
1765 * NOTE: this routine modifies both source and destination leaves.
1766 */
1767/* ARGSUSED */
1768STATIC void
1769xfs_dir_leaf_moveents(xfs_dir_leafblock_t *leaf_s, int start_s,
1770 xfs_dir_leafblock_t *leaf_d, int start_d,
1771 int count, xfs_mount_t *mp)
1772{
1773 xfs_dir_leaf_hdr_t *hdr_s, *hdr_d;
1774 xfs_dir_leaf_entry_t *entry_s, *entry_d;
1775 int tmp, i;
1776
1777 /*
1778 * Check for nothing to do.
1779 */
1780 if (count == 0)
1781 return;
1782
1783 /*
1784 * Set up environment.
1785 */
1786 ASSERT(be16_to_cpu(leaf_s->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1787 ASSERT(be16_to_cpu(leaf_d->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1788 hdr_s = &leaf_s->hdr;
1789 hdr_d = &leaf_d->hdr;
1790 ASSERT((INT_GET(hdr_s->count, ARCH_CONVERT) > 0) && (INT_GET(hdr_s->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8)));
1791 ASSERT(INT_GET(hdr_s->firstused, ARCH_CONVERT) >=
1792 ((INT_GET(hdr_s->count, ARCH_CONVERT)*sizeof(*entry_s))+sizeof(*hdr_s)));
1793 ASSERT(INT_GET(hdr_d->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8));
1794 ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >=
1795 ((INT_GET(hdr_d->count, ARCH_CONVERT)*sizeof(*entry_d))+sizeof(*hdr_d)));
1796
1797 ASSERT(start_s < INT_GET(hdr_s->count, ARCH_CONVERT));
1798 ASSERT(start_d <= INT_GET(hdr_d->count, ARCH_CONVERT));
1799 ASSERT(count <= INT_GET(hdr_s->count, ARCH_CONVERT));
1800
1801 /*
1802 * Move the entries in the destination leaf up to make a hole?
1803 */
1804 if (start_d < INT_GET(hdr_d->count, ARCH_CONVERT)) {
1805 tmp = INT_GET(hdr_d->count, ARCH_CONVERT) - start_d;
1806 tmp *= (uint)sizeof(xfs_dir_leaf_entry_t);
1807 entry_s = &leaf_d->entries[start_d];
1808 entry_d = &leaf_d->entries[start_d + count];
1809 memcpy(entry_d, entry_s, tmp);
1810 }
1811
1812 /*
1813 * Copy all entry's in the same (sorted) order,
1814 * but allocate filenames packed and in sequence.
1815 */
1816 entry_s = &leaf_s->entries[start_s];
1817 entry_d = &leaf_d->entries[start_d];
1818 for (i = 0; i < count; entry_s++, entry_d++, i++) {
1819 ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) >= INT_GET(hdr_s->firstused, ARCH_CONVERT));
1820 tmp = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry_s);
1821 INT_MOD(hdr_d->firstused, ARCH_CONVERT, -(tmp));
1822 entry_d->hashval = entry_s->hashval; /* INT_: direct copy */
1823 INT_COPY(entry_d->nameidx, hdr_d->firstused, ARCH_CONVERT);
1824 entry_d->namelen = entry_s->namelen;
1825 ASSERT(INT_GET(entry_d->nameidx, ARCH_CONVERT) + tmp <= XFS_LBSIZE(mp));
1826 memcpy(XFS_DIR_LEAF_NAMESTRUCT(leaf_d, INT_GET(entry_d->nameidx, ARCH_CONVERT)),
1827 XFS_DIR_LEAF_NAMESTRUCT(leaf_s, INT_GET(entry_s->nameidx, ARCH_CONVERT)), tmp);
1828 ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) + tmp <= XFS_LBSIZE(mp));
1829 memset((char *)XFS_DIR_LEAF_NAMESTRUCT(leaf_s, INT_GET(entry_s->nameidx, ARCH_CONVERT)),
1830 0, tmp);
1831 INT_MOD(hdr_s->namebytes, ARCH_CONVERT, -(entry_d->namelen));
1832 INT_MOD(hdr_d->namebytes, ARCH_CONVERT, entry_d->namelen);
1833 INT_MOD(hdr_s->count, ARCH_CONVERT, -1);
1834 INT_MOD(hdr_d->count, ARCH_CONVERT, +1);
1835 tmp = INT_GET(hdr_d->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t)
1836 + (uint)sizeof(xfs_dir_leaf_hdr_t);
1837 ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >= tmp);
1838
1839 }
1840
1841 /*
1842 * Zero out the entries we just copied.
1843 */
1844 if (start_s == INT_GET(hdr_s->count, ARCH_CONVERT)) {
1845 tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t);
1846 entry_s = &leaf_s->entries[start_s];
1847 ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp));
1848 memset((char *)entry_s, 0, tmp);
1849 } else {
1850 /*
1851 * Move the remaining entries down to fill the hole,
1852 * then zero the entries at the top.
1853 */
1854 tmp = INT_GET(hdr_s->count, ARCH_CONVERT) - count;
1855 tmp *= (uint)sizeof(xfs_dir_leaf_entry_t);
1856 entry_s = &leaf_s->entries[start_s + count];
1857 entry_d = &leaf_s->entries[start_s];
1858 memcpy(entry_d, entry_s, tmp);
1859
1860 tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t);
1861 entry_s = &leaf_s->entries[INT_GET(hdr_s->count, ARCH_CONVERT)];
1862 ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp));
1863 memset((char *)entry_s, 0, tmp);
1864 }
1865
1866 /*
1867 * Fill in the freemap information
1868 */
1869 INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_hdr_t));
1870 INT_MOD(hdr_d->freemap[0].base, ARCH_CONVERT, INT_GET(hdr_d->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t));
1871 INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, INT_GET(hdr_d->firstused, ARCH_CONVERT) - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT));
1872 INT_SET(hdr_d->freemap[1].base, ARCH_CONVERT, (hdr_d->freemap[2].base = 0));
1873 INT_SET(hdr_d->freemap[1].size, ARCH_CONVERT, (hdr_d->freemap[2].size = 0));
1874 hdr_s->holes = 1; /* leaf may not be compact */
1875}
1876
1877/*
1878 * Compare two leaf blocks "order".
1879 */
1880int
1881xfs_dir_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp)
1882{
1883 xfs_dir_leafblock_t *leaf1, *leaf2;
1884
1885 leaf1 = leaf1_bp->data;
1886 leaf2 = leaf2_bp->data;
1887 ASSERT((be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC) &&
1888 (be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC));
1889 if ((INT_GET(leaf1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(leaf2->hdr.count, ARCH_CONVERT) > 0) &&
1890 ((INT_GET(leaf2->entries[ 0 ].hashval, ARCH_CONVERT) <
1891 INT_GET(leaf1->entries[ 0 ].hashval, ARCH_CONVERT)) ||
1892 (INT_GET(leaf2->entries[ INT_GET(leaf2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) <
1893 INT_GET(leaf1->entries[ INT_GET(leaf1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) {
1894 return 1;
1895 }
1896 return 0;
1897}
1898
1899/*
1900 * Pick up the last hashvalue from a leaf block.
1901 */
1902xfs_dahash_t
1903xfs_dir_leaf_lasthash(xfs_dabuf_t *bp, int *count)
1904{
1905 xfs_dir_leafblock_t *leaf;
1906
1907 leaf = bp->data;
1908 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1909 if (count)
1910 *count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
1911 if (!leaf->hdr.count)
1912 return(0);
1913 return(INT_GET(leaf->entries[ INT_GET(leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT));
1914}
1915
1916/*
1917 * Copy out directory entries for getdents(), for leaf directories.
1918 */
1919int
1920xfs_dir_leaf_getdents_int(
1921 xfs_dabuf_t *bp,
1922 xfs_inode_t *dp,
1923 xfs_dablk_t bno,
1924 uio_t *uio,
1925 int *eobp,
1926 xfs_dirent_t *dbp,
1927 xfs_dir_put_t put,
1928 xfs_daddr_t nextda)
1929{
1930 xfs_dir_leafblock_t *leaf;
1931 xfs_dir_leaf_entry_t *entry;
1932 xfs_dir_leaf_name_t *namest;
1933 int entno, want_entno, i, nextentno;
1934 xfs_mount_t *mp;
1935 xfs_dahash_t cookhash;
1936 xfs_dahash_t nexthash = 0;
1937#if (BITS_PER_LONG == 32)
1938 xfs_dahash_t lasthash = XFS_DA_MAXHASH;
1939#endif
1940 xfs_dir_put_args_t p;
1941
1942 mp = dp->i_mount;
1943 leaf = bp->data;
1944 if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) {
1945 *eobp = 1;
1946 return XFS_ERROR(ENOENT); /* XXX wrong code */
1947 }
1948
1949 want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset);
1950
1951 cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);
1952
1953 xfs_dir_trace_g_dul("leaf: start", dp, uio, leaf);
1954
1955 /*
1956 * Re-find our place.
1957 */
1958 for (i = entno = 0, entry = &leaf->entries[0];
1959 i < INT_GET(leaf->hdr.count, ARCH_CONVERT);
1960 entry++, i++) {
1961
1962 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf,
1963 INT_GET(entry->nameidx, ARCH_CONVERT));
1964
1965 if (unlikely(
1966 ((char *)namest < (char *)leaf) ||
1967 ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) {
1968 XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(1)",
1969 XFS_ERRLEVEL_LOW, mp, leaf);
1970 xfs_dir_trace_g_du("leaf: corrupted", dp, uio);
1971 return XFS_ERROR(EFSCORRUPTED);
1972 }
1973 if (INT_GET(entry->hashval, ARCH_CONVERT) >= cookhash) {
1974 if ( entno < want_entno
1975 && INT_GET(entry->hashval, ARCH_CONVERT)
1976 == cookhash) {
1977 /*
1978 * Trying to get to a particular offset in a
1979 * run of equal-hashval entries.
1980 */
1981 entno++;
1982 } else if ( want_entno > 0
1983 && entno == want_entno
1984 && INT_GET(entry->hashval, ARCH_CONVERT)
1985 == cookhash) {
1986 break;
1987 } else {
1988 entno = 0;
1989 break;
1990 }
1991 }
1992 }
1993
1994 if (i == INT_GET(leaf->hdr.count, ARCH_CONVERT)) {
1995 xfs_dir_trace_g_du("leaf: hash not found", dp, uio);
1996 if (!leaf->hdr.info.forw)
1997 uio->uio_offset =
1998 XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH);
1999 /*
2000 * Don't set uio_offset if there's another block:
2001 * the node code will be setting uio_offset anyway.
2002 */
2003 *eobp = 0;
2004 return 0;
2005 }
2006 xfs_dir_trace_g_due("leaf: hash found", dp, uio, entry);
2007
2008 p.dbp = dbp;
2009 p.put = put;
2010 p.uio = uio;
2011
2012 /*
2013 * We're synchronized, start copying entries out to the user.
2014 */
2015 for (; entno >= 0 && i < INT_GET(leaf->hdr.count, ARCH_CONVERT);
2016 entry++, i++, (entno = nextentno)) {
2017 int lastresid=0, retval;
2018 xfs_dircook_t lastoffset;
2019 xfs_dahash_t thishash;
2020
2021 /*
2022 * Check for a damaged directory leaf block and pick up
2023 * the inode number from this entry.
2024 */
2025 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf,
2026 INT_GET(entry->nameidx, ARCH_CONVERT));
2027
2028 if (unlikely(
2029 ((char *)namest < (char *)leaf) ||
2030 ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) {
2031 XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(2)",
2032 XFS_ERRLEVEL_LOW, mp, leaf);
2033 xfs_dir_trace_g_du("leaf: corrupted", dp, uio);
2034 return XFS_ERROR(EFSCORRUPTED);
2035 }
2036
2037 xfs_dir_trace_g_duc("leaf: middle cookie ",
2038 dp, uio, p.cook.o);
2039
2040 if (i < (INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1)) {
2041 nexthash = INT_GET(entry[1].hashval, ARCH_CONVERT);
2042
2043 if (nexthash == INT_GET(entry->hashval, ARCH_CONVERT))
2044 nextentno = entno + 1;
2045 else
2046 nextentno = 0;
2047 XFS_PUT_COOKIE(p.cook, mp, bno, nextentno, nexthash);
2048 xfs_dir_trace_g_duc("leaf: middle cookie ",
2049 dp, uio, p.cook.o);
2050
2051 } else if ((thishash = be32_to_cpu(leaf->hdr.info.forw))) {
2052 xfs_dabuf_t *bp2;
2053 xfs_dir_leafblock_t *leaf2;
2054
2055 ASSERT(nextda != -1);
2056
2057 retval = xfs_da_read_buf(dp->i_transp, dp, thishash,
2058 nextda, &bp2, XFS_DATA_FORK);
2059 if (retval)
2060 return retval;
2061
2062 ASSERT(bp2 != NULL);
2063
2064 leaf2 = bp2->data;
2065
2066 if (unlikely(
2067 (be16_to_cpu(leaf2->hdr.info.magic)
2068 != XFS_DIR_LEAF_MAGIC)
2069 || (be32_to_cpu(leaf2->hdr.info.back)
2070 != bno))) { /* GROT */
2071 XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(3)",
2072 XFS_ERRLEVEL_LOW, mp,
2073 leaf2);
2074 xfs_da_brelse(dp->i_transp, bp2);
2075
2076 return XFS_ERROR(EFSCORRUPTED);
2077 }
2078
2079 nexthash = INT_GET(leaf2->entries[0].hashval,
2080 ARCH_CONVERT);
2081 nextentno = -1;
2082 XFS_PUT_COOKIE(p.cook, mp, thishash, 0, nexthash);
2083 xfs_da_brelse(dp->i_transp, bp2);
2084 xfs_dir_trace_g_duc("leaf: next blk cookie",
2085 dp, uio, p.cook.o);
2086 } else {
2087 nextentno = -1;
2088 XFS_PUT_COOKIE(p.cook, mp, 0, 0, XFS_DA_MAXHASH);
2089 }
2090
2091 /*
2092 * Save off the cookie so we can fall back should the
2093 * 'put' into the outgoing buffer fails. To handle a run
2094 * of equal-hashvals, the off_t structure on 64bit
2095 * builds has entno built into the cookie to ID the
2096 * entry. On 32bit builds, we only have space for the
2097 * hashval so we can't ID specific entries within a group
2098 * of same hashval entries. For this, lastoffset is set
2099 * to the first in the run of equal hashvals so we don't
2100 * include any entries unless we can include all entries
2101 * that share the same hashval. Hopefully the buffer
2102 * provided is big enough to handle it (see pv763517).
2103 */
2104#if (BITS_PER_LONG == 32)
2105 if ((thishash = INT_GET(entry->hashval, ARCH_CONVERT))
2106 != lasthash) {
2107 XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash);
2108 lastresid = uio->uio_resid;
2109 lasthash = thishash;
2110 } else {
2111 xfs_dir_trace_g_duc("leaf: DUP COOKIES, skipped",
2112 dp, uio, p.cook.o);
2113 }
2114#else
2115 thishash = INT_GET(entry->hashval, ARCH_CONVERT);
2116 XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash);
2117 lastresid = uio->uio_resid;
2118#endif /* BITS_PER_LONG == 32 */
2119
2120 /*
2121 * Put the current entry into the outgoing buffer. If we fail
2122 * then restore the UIO to the first entry in the current
2123 * run of equal-hashval entries (probably one 1 entry long).
2124 */
2125 p.ino = XFS_GET_DIR_INO8(namest->inumber);
2126#if XFS_BIG_INUMS
2127 p.ino += mp->m_inoadd;
2128#endif
2129 p.name = (char *)namest->name;
2130 p.namelen = entry->namelen;
2131
2132 retval = p.put(&p);
2133
2134 if (!p.done) {
2135 uio->uio_offset = lastoffset.o;
2136 uio->uio_resid = lastresid;
2137
2138 *eobp = 1;
2139
2140 xfs_dir_trace_g_du("leaf: E-O-B", dp, uio);
2141
2142 return retval;
2143 }
2144 }
2145
2146 uio->uio_offset = p.cook.o;
2147
2148 *eobp = 0;
2149
2150 xfs_dir_trace_g_du("leaf: E-O-F", dp, uio);
2151
2152 return 0;
2153}
2154
2155/*
2156 * Format a dirent64 structure and copy it out the the user's buffer.
2157 */
2158int
2159xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa)
2160{
2161 iovec_t *iovp;
2162 int reclen, namelen;
2163 xfs_dirent_t *idbp;
2164 uio_t *uio;
2165
2166 namelen = pa->namelen;
2167 reclen = DIRENTSIZE(namelen);
2168 uio = pa->uio;
2169 if (reclen > uio->uio_resid) {
2170 pa->done = 0;
2171 return 0;
2172 }
2173 iovp = uio->uio_iov;
2174 idbp = (xfs_dirent_t *)iovp->iov_base;
2175 iovp->iov_base = (char *)idbp + reclen;
2176 iovp->iov_len -= reclen;
2177 uio->uio_resid -= reclen;
2178 idbp->d_reclen = reclen;
2179 idbp->d_ino = pa->ino;
2180 idbp->d_off = pa->cook.o;
2181 idbp->d_name[namelen] = '\0';
2182 pa->done = 1;
2183 memcpy(idbp->d_name, pa->name, namelen);
2184 return 0;
2185}
2186
2187/*
2188 * Format a dirent64 structure and copy it out the the user's buffer.
2189 */
2190int
2191xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa)
2192{
2193 int retval, reclen, namelen;
2194 xfs_dirent_t *idbp;
2195 uio_t *uio;
2196
2197 namelen = pa->namelen;
2198 reclen = DIRENTSIZE(namelen);
2199 uio = pa->uio;
2200 if (reclen > uio->uio_resid) {
2201 pa->done = 0;
2202 return 0;
2203 }
2204 idbp = pa->dbp;
2205 idbp->d_reclen = reclen;
2206 idbp->d_ino = pa->ino;
2207 idbp->d_off = pa->cook.o;
2208 idbp->d_name[namelen] = '\0';
2209 memcpy(idbp->d_name, pa->name, namelen);
2210 retval = uio_read((caddr_t)idbp, reclen, uio);
2211 pa->done = (retval == 0);
2212 return retval;
2213}
diff --git a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h
deleted file mode 100644
index eb8cd9a4667f..000000000000
--- a/fs/xfs/xfs_dir_leaf.h
+++ /dev/null
@@ -1,231 +0,0 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR_LEAF_H__
19#define __XFS_DIR_LEAF_H__
20
21/*
22 * Directory layout, internal structure, access macros, etc.
23 *
24 * Large directories are structured around Btrees where all the data
25 * elements are in the leaf nodes. Filenames are hashed into an int,
26 * then that int is used as the index into the Btree. Since the hashval
27 * of a filename may not be unique, we may have duplicate keys. The
28 * internal links in the Btree are logical block offsets into the file.
29 */
30
31struct uio;
32struct xfs_bmap_free;
33struct xfs_dabuf;
34struct xfs_da_args;
35struct xfs_da_state;
36struct xfs_da_state_blk;
37struct xfs_dir_put_args;
38struct xfs_inode;
39struct xfs_mount;
40struct xfs_trans;
41
42/*========================================================================
43 * Directory Structure when equal to XFS_LBSIZE(mp) bytes.
44 *========================================================================*/
45
46/*
47 * This is the structure of the leaf nodes in the Btree.
48 *
49 * Struct leaf_entry's are packed from the top. Names grow from the bottom
50 * but are not packed. The freemap contains run-length-encoded entries
51 * for the free bytes after the leaf_entry's, but only the N largest such,
52 * smaller runs are dropped. When the freemap doesn't show enough space
53 * for an allocation, we compact the namelist area and try again. If we
54 * still don't have enough space, then we have to split the block.
55 *
56 * Since we have duplicate hash keys, for each key that matches, compare
57 * the actual string. The root and intermediate node search always takes
58 * the first-in-the-block key match found, so we should only have to work
59 * "forw"ard. If none matches, continue with the "forw"ard leaf nodes
60 * until the hash key changes or the filename is found.
61 *
62 * The parent directory and the self-pointer are explicitly represented
63 * (ie: there are entries for "." and "..").
64 *
65 * Note that the count being a __uint16_t limits us to something like a
66 * blocksize of 1.3MB in the face of worst case (short) filenames.
67 */
68#define XFS_DIR_LEAF_MAPSIZE 3 /* how many freespace slots */
69
70typedef struct xfs_dir_leaf_map { /* RLE map of free bytes */
71 __uint16_t base; /* base of free region */
72 __uint16_t size; /* run length of free region */
73} xfs_dir_leaf_map_t;
74
75typedef struct xfs_dir_leaf_hdr { /* constant-structure header block */
76 xfs_da_blkinfo_t info; /* block type, links, etc. */
77 __uint16_t count; /* count of active leaf_entry's */
78 __uint16_t namebytes; /* num bytes of name strings stored */
79 __uint16_t firstused; /* first used byte in name area */
80 __uint8_t holes; /* != 0 if blk needs compaction */
81 __uint8_t pad1;
82 xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE];
83} xfs_dir_leaf_hdr_t;
84
85typedef struct xfs_dir_leaf_entry { /* sorted on key, not name */
86 xfs_dahash_t hashval; /* hash value of name */
87 __uint16_t nameidx; /* index into buffer of name */
88 __uint8_t namelen; /* length of name string */
89 __uint8_t pad2;
90} xfs_dir_leaf_entry_t;
91
92typedef struct xfs_dir_leaf_name {
93 xfs_dir_ino_t inumber; /* inode number for this key */
94 __uint8_t name[1]; /* name string itself */
95} xfs_dir_leaf_name_t;
96
97typedef struct xfs_dir_leafblock {
98 xfs_dir_leaf_hdr_t hdr; /* constant-structure header block */
99 xfs_dir_leaf_entry_t entries[1]; /* var sized array */
100 xfs_dir_leaf_name_t namelist[1]; /* grows from bottom of buf */
101} xfs_dir_leafblock_t;
102
103/*
104 * Length of name for which a 512-byte block filesystem
105 * can get a double split.
106 */
107#define XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN \
108 (512 - (uint)sizeof(xfs_dir_leaf_hdr_t) - \
109 (uint)sizeof(xfs_dir_leaf_entry_t) * 2 - \
110 (uint)sizeof(xfs_dir_leaf_name_t) * 2 - (MAXNAMELEN - 2) + 1 + 1)
111
112typedef int (*xfs_dir_put_t)(struct xfs_dir_put_args *pa);
113
114typedef union {
115 xfs_off_t o; /* offset (cookie) */
116 /*
117 * Watch the order here (endian-ness dependent).
118 */
119 struct {
120#ifndef XFS_NATIVE_HOST
121 xfs_dahash_t h; /* hash value */
122 __uint32_t be; /* block and entry */
123#else
124 __uint32_t be; /* block and entry */
125 xfs_dahash_t h; /* hash value */
126#endif /* XFS_NATIVE_HOST */
127 } s;
128} xfs_dircook_t;
129
130#define XFS_PUT_COOKIE(c,mp,bno,entry,hash) \
131 ((c).s.be = XFS_DA_MAKE_BNOENTRY(mp, bno, entry), (c).s.h = (hash))
132
133typedef struct xfs_dir_put_args {
134 xfs_dircook_t cook; /* cookie of (next) entry */
135 xfs_intino_t ino; /* inode number */
136 struct xfs_dirent *dbp; /* buffer pointer */
137 char *name; /* directory entry name */
138 int namelen; /* length of name */
139 int done; /* output: set if value was stored */
140 xfs_dir_put_t put; /* put function ptr (i/o) */
141 struct uio *uio; /* uio control structure */
142} xfs_dir_put_args_t;
143
144#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len) \
145 xfs_dir_leaf_entsize_byname(len)
146static inline int xfs_dir_leaf_entsize_byname(int len)
147{
148 return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len;
149}
150
151#define XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry) \
152 xfs_dir_leaf_entsize_byentry(entry)
153static inline int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry)
154{
155 return (uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen;
156}
157
158#define XFS_DIR_LEAF_NAMESTRUCT(leafp,offset) \
159 xfs_dir_leaf_namestruct(leafp,offset)
160static inline xfs_dir_leaf_name_t *
161xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset)
162{
163 return (xfs_dir_leaf_name_t *)&((char *)(leafp))[offset];
164}
165
166/*========================================================================
167 * Function prototypes for the kernel.
168 *========================================================================*/
169
170/*
171 * Internal routines when dirsize < XFS_LITINO(mp).
172 */
173int xfs_dir_shortform_create(struct xfs_da_args *args, xfs_ino_t parent);
174int xfs_dir_shortform_addname(struct xfs_da_args *args);
175int xfs_dir_shortform_lookup(struct xfs_da_args *args);
176int xfs_dir_shortform_to_leaf(struct xfs_da_args *args);
177int xfs_dir_shortform_removename(struct xfs_da_args *args);
178int xfs_dir_shortform_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp,
179 struct xfs_dirent *dbp, xfs_dir_put_t put);
180int xfs_dir_shortform_replace(struct xfs_da_args *args);
181
182/*
183 * Internal routines when dirsize == XFS_LBSIZE(mp).
184 */
185int xfs_dir_leaf_to_node(struct xfs_da_args *args);
186int xfs_dir_leaf_to_shortform(struct xfs_da_args *args);
187
188/*
189 * Routines used for growing the Btree.
190 */
191int xfs_dir_leaf_split(struct xfs_da_state *state,
192 struct xfs_da_state_blk *oldblk,
193 struct xfs_da_state_blk *newblk);
194int xfs_dir_leaf_add(struct xfs_dabuf *leaf_buffer,
195 struct xfs_da_args *args, int insertion_index);
196int xfs_dir_leaf_addname(struct xfs_da_args *args);
197int xfs_dir_leaf_lookup_int(struct xfs_dabuf *leaf_buffer,
198 struct xfs_da_args *args,
199 int *index_found_at);
200int xfs_dir_leaf_remove(struct xfs_trans *trans,
201 struct xfs_dabuf *leaf_buffer,
202 int index_to_remove);
203int xfs_dir_leaf_getdents_int(struct xfs_dabuf *bp, struct xfs_inode *dp,
204 xfs_dablk_t bno, struct uio *uio,
205 int *eobp, struct xfs_dirent *dbp,
206 xfs_dir_put_t put, xfs_daddr_t nextda);
207
208/*
209 * Routines used for shrinking the Btree.
210 */
211int xfs_dir_leaf_toosmall(struct xfs_da_state *state, int *retval);
212void xfs_dir_leaf_unbalance(struct xfs_da_state *state,
213 struct xfs_da_state_blk *drop_blk,
214 struct xfs_da_state_blk *save_blk);
215
216/*
217 * Utility routines.
218 */
219uint xfs_dir_leaf_lasthash(struct xfs_dabuf *bp, int *count);
220int xfs_dir_leaf_order(struct xfs_dabuf *leaf1_bp,
221 struct xfs_dabuf *leaf2_bp);
222int xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa);
223int xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa);
224int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
225
226/*
227 * Global data.
228 */
229extern xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
230
231#endif /* __XFS_DIR_LEAF_H__ */
diff --git a/fs/xfs/xfs_dir_sf.h b/fs/xfs/xfs_dir_sf.h
deleted file mode 100644
index 5b20b4d3f57d..000000000000
--- a/fs/xfs/xfs_dir_sf.h
+++ /dev/null
@@ -1,155 +0,0 @@
1/*
2 * Copyright (c) 2000,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR_SF_H__
19#define __XFS_DIR_SF_H__
20
21/*
22 * Directory layout when stored internal to an inode.
23 *
24 * Small directories are packed as tightly as possible so as to
25 * fit into the literal area of the inode.
26 */
27
28typedef struct { __uint8_t i[sizeof(xfs_ino_t)]; } xfs_dir_ino_t;
29
30/*
31 * The parent directory has a dedicated field, and the self-pointer must
32 * be calculated on the fly.
33 *
34 * Entries are packed toward the top as tight as possible. The header
35 * and the elements much be memcpy'd out into a work area to get correct
36 * alignment for the inode number fields.
37 */
38typedef struct xfs_dir_sf_hdr { /* constant-structure header block */
39 xfs_dir_ino_t parent; /* parent dir inode number */
40 __uint8_t count; /* count of active entries */
41} xfs_dir_sf_hdr_t;
42
43typedef struct xfs_dir_sf_entry {
44 xfs_dir_ino_t inumber; /* referenced inode number */
45 __uint8_t namelen; /* actual length of name (no NULL) */
46 __uint8_t name[1]; /* name */
47} xfs_dir_sf_entry_t;
48
49typedef struct xfs_dir_shortform {
50 xfs_dir_sf_hdr_t hdr;
51 xfs_dir_sf_entry_t list[1]; /* variable sized array */
52} xfs_dir_shortform_t;
53
54/*
55 * We generate this then sort it, so that readdirs are returned in
56 * hash-order. Else seekdir won't work.
57 */
58typedef struct xfs_dir_sf_sort {
59 __uint8_t entno; /* .=0, ..=1, else entry# + 2 */
60 __uint8_t seqno; /* sequence # with same hash value */
61 __uint8_t namelen; /* length of name value (no null) */
62 xfs_dahash_t hash; /* this entry's hash value */
63 xfs_intino_t ino; /* this entry's inode number */
64 char *name; /* name value, pointer into buffer */
65} xfs_dir_sf_sort_t;
66
67#define XFS_DIR_SF_GET_DIRINO(from,to) xfs_dir_sf_get_dirino(from, to)
68static inline void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to)
69{
70 *(to) = XFS_GET_DIR_INO8(*from);
71}
72
73#define XFS_DIR_SF_PUT_DIRINO(from,to) xfs_dir_sf_put_dirino(from, to)
74static inline void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to)
75{
76 XFS_PUT_DIR_INO8(*(from), *(to));
77}
78
79#define XFS_DIR_SF_ENTSIZE_BYNAME(len) xfs_dir_sf_entsize_byname(len)
80static inline int xfs_dir_sf_entsize_byname(int len)
81{
82 return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (len);
83}
84
85#define XFS_DIR_SF_ENTSIZE_BYENTRY(sfep) xfs_dir_sf_entsize_byentry(sfep)
86static inline int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep)
87{
88 return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (sfep)->namelen;
89}
90
91#define XFS_DIR_SF_NEXTENTRY(sfep) xfs_dir_sf_nextentry(sfep)
92static inline xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep)
93{
94 return (xfs_dir_sf_entry_t *) \
95 ((char *)(sfep) + XFS_DIR_SF_ENTSIZE_BYENTRY(sfep));
96}
97
98#define XFS_DIR_SF_ALLFIT(count,totallen) \
99 xfs_dir_sf_allfit(count,totallen)
100static inline int xfs_dir_sf_allfit(int count, int totallen)
101{
102 return ((uint)sizeof(xfs_dir_sf_hdr_t) + \
103 ((uint)sizeof(xfs_dir_sf_entry_t)-1)*(count) + (totallen));
104}
105
106#if defined(XFS_DIR_TRACE)
107
108/*
109 * Kernel tracing support for directories.
110 */
111struct uio;
112struct xfs_inode;
113struct xfs_da_intnode;
114struct xfs_dinode;
115struct xfs_dir_leafblock;
116struct xfs_dir_leaf_entry;
117
118#define XFS_DIR_TRACE_SIZE 4096 /* size of global trace buffer */
119extern ktrace_t *xfs_dir_trace_buf;
120
121/*
122 * Trace record types.
123 */
124#define XFS_DIR_KTRACE_G_DU 1 /* dp, uio */
125#define XFS_DIR_KTRACE_G_DUB 2 /* dp, uio, bno */
126#define XFS_DIR_KTRACE_G_DUN 3 /* dp, uio, node */
127#define XFS_DIR_KTRACE_G_DUL 4 /* dp, uio, leaf */
128#define XFS_DIR_KTRACE_G_DUE 5 /* dp, uio, leaf entry */
129#define XFS_DIR_KTRACE_G_DUC 6 /* dp, uio, cookie */
130
131void xfs_dir_trace_g_du(char *where, struct xfs_inode *dp, struct uio *uio);
132void xfs_dir_trace_g_dub(char *where, struct xfs_inode *dp, struct uio *uio,
133 xfs_dablk_t bno);
134void xfs_dir_trace_g_dun(char *where, struct xfs_inode *dp, struct uio *uio,
135 struct xfs_da_intnode *node);
136void xfs_dir_trace_g_dul(char *where, struct xfs_inode *dp, struct uio *uio,
137 struct xfs_dir_leafblock *leaf);
138void xfs_dir_trace_g_due(char *where, struct xfs_inode *dp, struct uio *uio,
139 struct xfs_dir_leaf_entry *entry);
140void xfs_dir_trace_g_duc(char *where, struct xfs_inode *dp, struct uio *uio,
141 xfs_off_t cookie);
142void xfs_dir_trace_enter(int type, char *where,
143 void *a0, void *a1, void *a2, void *a3,
144 void *a4, void *a5, void *a6, void *a7,
145 void *a8, void *a9, void *a10, void *a11);
146#else
147#define xfs_dir_trace_g_du(w,d,u)
148#define xfs_dir_trace_g_dub(w,d,u,b)
149#define xfs_dir_trace_g_dun(w,d,u,n)
150#define xfs_dir_trace_g_dul(w,d,u,l)
151#define xfs_dir_trace_g_due(w,d,u,e)
152#define xfs_dir_trace_g_duc(w,d,u,c)
153#endif /* DEBUG */
154
155#endif /* __XFS_DIR_SF_H__ */
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index 00b1540f8108..4e7865ad6f0e 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -189,6 +189,6 @@ typedef enum {
189#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0) 189#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0)
190 190
191 191
192extern struct bhv_vfsops xfs_dmops; 192extern struct bhv_module_vfsops xfs_dmops;
193 193
194#endif /* __XFS_DMAPI_H__ */ 194#endif /* __XFS_DMAPI_H__ */
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c
index 629795b3b3d5..1e4a35ddf7f9 100644
--- a/fs/xfs/xfs_dmops.c
+++ b/fs/xfs/xfs_dmops.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
29#include "xfs_mount.h" 28#include "xfs_mount.h"
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index 2a21c5024017..b95681b03d81 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -22,12 +22,10 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_dir_sf.h"
31#include "xfs_dir2_sf.h" 29#include "xfs_dir2_sf.h"
32#include "xfs_attr_sf.h" 30#include "xfs_attr_sf.h"
33#include "xfs_dinode.h" 31#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index f19282ec8549..6cf6d8769b97 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_buf_item.h" 24#include "xfs_buf_item.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_dir.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_trans_priv.h" 28#include "xfs_trans_priv.h"
@@ -294,6 +293,62 @@ xfs_efi_init(xfs_mount_t *mp,
294} 293}
295 294
296/* 295/*
296 * Copy an EFI format buffer from the given buf, and into the destination
297 * EFI format structure.
298 * The given buffer can be in 32 bit or 64 bit form (which has different padding),
299 * one of which will be the native format for this kernel.
300 * It will handle the conversion of formats if necessary.
301 */
302int
303xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
304{
305 xfs_efi_log_format_t *src_efi_fmt = (xfs_efi_log_format_t *)buf->i_addr;
306 uint i;
307 uint len = sizeof(xfs_efi_log_format_t) +
308 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_t);
309 uint len32 = sizeof(xfs_efi_log_format_32_t) +
310 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_32_t);
311 uint len64 = sizeof(xfs_efi_log_format_64_t) +
312 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_64_t);
313
314 if (buf->i_len == len) {
315 memcpy((char *)dst_efi_fmt, (char*)src_efi_fmt, len);
316 return 0;
317 } else if (buf->i_len == len32) {
318 xfs_efi_log_format_32_t *src_efi_fmt_32 =
319 (xfs_efi_log_format_32_t *)buf->i_addr;
320
321 dst_efi_fmt->efi_type = src_efi_fmt_32->efi_type;
322 dst_efi_fmt->efi_size = src_efi_fmt_32->efi_size;
323 dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents;
324 dst_efi_fmt->efi_id = src_efi_fmt_32->efi_id;
325 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
326 dst_efi_fmt->efi_extents[i].ext_start =
327 src_efi_fmt_32->efi_extents[i].ext_start;
328 dst_efi_fmt->efi_extents[i].ext_len =
329 src_efi_fmt_32->efi_extents[i].ext_len;
330 }
331 return 0;
332 } else if (buf->i_len == len64) {
333 xfs_efi_log_format_64_t *src_efi_fmt_64 =
334 (xfs_efi_log_format_64_t *)buf->i_addr;
335
336 dst_efi_fmt->efi_type = src_efi_fmt_64->efi_type;
337 dst_efi_fmt->efi_size = src_efi_fmt_64->efi_size;
338 dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents;
339 dst_efi_fmt->efi_id = src_efi_fmt_64->efi_id;
340 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
341 dst_efi_fmt->efi_extents[i].ext_start =
342 src_efi_fmt_64->efi_extents[i].ext_start;
343 dst_efi_fmt->efi_extents[i].ext_len =
344 src_efi_fmt_64->efi_extents[i].ext_len;
345 }
346 return 0;
347 }
348 return EFSCORRUPTED;
349}
350
351/*
297 * This is called by the efd item code below to release references to 352 * This is called by the efd item code below to release references to
298 * the given efi item. Each efd calls this with the number of 353 * the given efi item. Each efd calls this with the number of
299 * extents that it has logged, and when the sum of these reaches 354 * extents that it has logged, and when the sum of these reaches
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h
index 5bf681708fec..0ea45edaab03 100644
--- a/fs/xfs/xfs_extfree_item.h
+++ b/fs/xfs/xfs_extfree_item.h
@@ -27,6 +27,24 @@ typedef struct xfs_extent {
27} xfs_extent_t; 27} xfs_extent_t;
28 28
29/* 29/*
30 * Since an xfs_extent_t has types (start:64, len: 32)
31 * there are different alignments on 32 bit and 64 bit kernels.
32 * So we provide the different variants for use by a
33 * conversion routine.
34 */
35
36typedef struct xfs_extent_32 {
37 xfs_dfsbno_t ext_start;
38 xfs_extlen_t ext_len;
39} __attribute__((packed)) xfs_extent_32_t;
40
41typedef struct xfs_extent_64 {
42 xfs_dfsbno_t ext_start;
43 xfs_extlen_t ext_len;
44 __uint32_t ext_pad;
45} xfs_extent_64_t;
46
47/*
30 * This is the structure used to lay out an efi log item in the 48 * This is the structure used to lay out an efi log item in the
31 * log. The efi_extents field is a variable size array whose 49 * log. The efi_extents field is a variable size array whose
32 * size is given by efi_nextents. 50 * size is given by efi_nextents.
@@ -39,6 +57,22 @@ typedef struct xfs_efi_log_format {
39 xfs_extent_t efi_extents[1]; /* array of extents to free */ 57 xfs_extent_t efi_extents[1]; /* array of extents to free */
40} xfs_efi_log_format_t; 58} xfs_efi_log_format_t;
41 59
60typedef struct xfs_efi_log_format_32 {
61 unsigned short efi_type; /* efi log item type */
62 unsigned short efi_size; /* size of this item */
63 uint efi_nextents; /* # extents to free */
64 __uint64_t efi_id; /* efi identifier */
65 xfs_extent_32_t efi_extents[1]; /* array of extents to free */
66} __attribute__((packed)) xfs_efi_log_format_32_t;
67
68typedef struct xfs_efi_log_format_64 {
69 unsigned short efi_type; /* efi log item type */
70 unsigned short efi_size; /* size of this item */
71 uint efi_nextents; /* # extents to free */
72 __uint64_t efi_id; /* efi identifier */
73 xfs_extent_64_t efi_extents[1]; /* array of extents to free */
74} xfs_efi_log_format_64_t;
75
42/* 76/*
43 * This is the structure used to lay out an efd log item in the 77 * This is the structure used to lay out an efd log item in the
44 * log. The efd_extents array is a variable size array whose 78 * log. The efd_extents array is a variable size array whose
@@ -52,6 +86,22 @@ typedef struct xfs_efd_log_format {
52 xfs_extent_t efd_extents[1]; /* array of extents freed */ 86 xfs_extent_t efd_extents[1]; /* array of extents freed */
53} xfs_efd_log_format_t; 87} xfs_efd_log_format_t;
54 88
89typedef struct xfs_efd_log_format_32 {
90 unsigned short efd_type; /* efd log item type */
91 unsigned short efd_size; /* size of this item */
92 uint efd_nextents; /* # of extents freed */
93 __uint64_t efd_efi_id; /* id of corresponding efi */
94 xfs_extent_32_t efd_extents[1]; /* array of extents freed */
95} __attribute__((packed)) xfs_efd_log_format_32_t;
96
97typedef struct xfs_efd_log_format_64 {
98 unsigned short efd_type; /* efd log item type */
99 unsigned short efd_size; /* size of this item */
100 uint efd_nextents; /* # of extents freed */
101 __uint64_t efd_efi_id; /* id of corresponding efi */
102 xfs_extent_64_t efd_extents[1]; /* array of extents freed */
103} xfs_efd_log_format_64_t;
104
55 105
56#ifdef __KERNEL__ 106#ifdef __KERNEL__
57 107
@@ -103,7 +153,8 @@ extern struct kmem_zone *xfs_efd_zone;
103xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint); 153xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint);
104xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *, 154xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
105 uint); 155 uint);
106 156int xfs_efi_copy_format(xfs_log_iovec_t *buf,
157 xfs_efi_log_format_t *dst_efi_fmt);
107void xfs_efi_item_free(xfs_efi_log_item_t *); 158void xfs_efi_item_free(xfs_efi_log_item_t *);
108 159
109#endif /* __KERNEL__ */ 160#endif /* __KERNEL__ */
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 14010f1fa82f..0f0ad1535951 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -67,14 +67,15 @@ struct fsxattr {
67#define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */ 67#define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */
68#define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */ 68#define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
69#define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ 69#define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
70#define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
70#define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ 71#define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
71 72
72/* 73/*
73 * Structure for XFS_IOC_GETBMAP. 74 * Structure for XFS_IOC_GETBMAP.
74 * On input, fill in bmv_offset and bmv_length of the first structure 75 * On input, fill in bmv_offset and bmv_length of the first structure
75 * to indicate the area of interest in the file, and bmv_entry with the 76 * to indicate the area of interest in the file, and bmv_entries with
76 * number of array elements given. The first structure is updated on 77 * the number of array elements given back. The first structure is
77 * return to give the offset and length for the next call. 78 * updated on return to give the offset and length for the next call.
78 */ 79 */
79#ifndef HAVE_GETBMAP 80#ifndef HAVE_GETBMAP
80struct getbmap { 81struct getbmap {
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index dfa3527b20a7..077629bab532 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -542,14 +540,13 @@ xfs_reserve_blocks(
542} 540}
543 541
544void 542void
545xfs_fs_log_dummy(xfs_mount_t *mp) 543xfs_fs_log_dummy(
544 xfs_mount_t *mp)
546{ 545{
547 xfs_trans_t *tp; 546 xfs_trans_t *tp;
548 xfs_inode_t *ip; 547 xfs_inode_t *ip;
549
550 548
551 tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1); 549 tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
552 atomic_inc(&mp->m_active_trans);
553 if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) { 550 if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) {
554 xfs_trans_cancel(tp, 0); 551 xfs_trans_cancel(tp, 0);
555 return; 552 return;
@@ -574,21 +571,22 @@ xfs_fs_goingdown(
574{ 571{
575 switch (inflags) { 572 switch (inflags) {
576 case XFS_FSOP_GOING_FLAGS_DEFAULT: { 573 case XFS_FSOP_GOING_FLAGS_DEFAULT: {
577 struct vfs *vfsp = XFS_MTOVFS(mp); 574 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
578 struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev); 575 struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev);
579 576
580 if (sb && !IS_ERR(sb)) { 577 if (sb && !IS_ERR(sb)) {
581 xfs_force_shutdown(mp, XFS_FORCE_UMOUNT); 578 xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
582 thaw_bdev(sb->s_bdev, sb); 579 thaw_bdev(sb->s_bdev, sb);
583 } 580 }
584 581
585 break; 582 break;
586 } 583 }
587 case XFS_FSOP_GOING_FLAGS_LOGFLUSH: 584 case XFS_FSOP_GOING_FLAGS_LOGFLUSH:
588 xfs_force_shutdown(mp, XFS_FORCE_UMOUNT); 585 xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
589 break; 586 break;
590 case XFS_FSOP_GOING_FLAGS_NOLOGFLUSH: 587 case XFS_FSOP_GOING_FLAGS_NOLOGFLUSH:
591 xfs_force_shutdown(mp, XFS_FORCE_UMOUNT|XFS_LOG_IO_ERROR); 588 xfs_force_shutdown(mp,
589 SHUTDOWN_FORCE_UMOUNT | SHUTDOWN_LOG_IO_ERROR);
592 break; 590 break;
593 default: 591 default:
594 return XFS_ERROR(EINVAL); 592 return XFS_ERROR(EINVAL);
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index deddbd03c166..33164a85aa9d 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -1174,6 +1172,9 @@ xfs_dilocate(
1174 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks || 1172 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
1175 ino != XFS_AGINO_TO_INO(mp, agno, agino)) { 1173 ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
1176#ifdef DEBUG 1174#ifdef DEBUG
1175 /* no diagnostics for bulkstat, ino comes from userspace */
1176 if (flags & XFS_IMAP_BULKSTAT)
1177 return XFS_ERROR(EINVAL);
1177 if (agno >= mp->m_sb.sb_agcount) { 1178 if (agno >= mp->m_sb.sb_agcount) {
1178 xfs_fs_cmn_err(CE_ALERT, mp, 1179 xfs_fs_cmn_err(CE_ALERT, mp,
1179 "xfs_dilocate: agno (%d) >= " 1180 "xfs_dilocate: agno (%d) >= "
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index 60c65683462d..616eeeb6953e 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index b53854325266..0724df7fabb7 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -186,7 +184,7 @@ xfs_ihash_promote(
186 */ 184 */
187STATIC int 185STATIC int
188xfs_iget_core( 186xfs_iget_core(
189 vnode_t *vp, 187 bhv_vnode_t *vp,
190 xfs_mount_t *mp, 188 xfs_mount_t *mp,
191 xfs_trans_t *tp, 189 xfs_trans_t *tp,
192 xfs_ino_t ino, 190 xfs_ino_t ino,
@@ -198,7 +196,7 @@ xfs_iget_core(
198 xfs_ihash_t *ih; 196 xfs_ihash_t *ih;
199 xfs_inode_t *ip; 197 xfs_inode_t *ip;
200 xfs_inode_t *iq; 198 xfs_inode_t *iq;
201 vnode_t *inode_vp; 199 bhv_vnode_t *inode_vp;
202 ulong version; 200 ulong version;
203 int error; 201 int error;
204 /* REFERENCED */ 202 /* REFERENCED */
@@ -468,7 +466,7 @@ finish_inode:
468 * If we have a real type for an on-disk inode, we can set ops(&unlock) 466 * If we have a real type for an on-disk inode, we can set ops(&unlock)
469 * now. If it's a new inode being created, xfs_ialloc will handle it. 467 * now. If it's a new inode being created, xfs_ialloc will handle it.
470 */ 468 */
471 VFS_INIT_VNODE(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1); 469 bhv_vfs_init_vnode(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1);
472 470
473 return 0; 471 return 0;
474} 472}
@@ -489,7 +487,7 @@ xfs_iget(
489 xfs_daddr_t bno) 487 xfs_daddr_t bno)
490{ 488{
491 struct inode *inode; 489 struct inode *inode;
492 vnode_t *vp = NULL; 490 bhv_vnode_t *vp = NULL;
493 int error; 491 int error;
494 492
495 XFS_STATS_INC(xs_ig_attempts); 493 XFS_STATS_INC(xs_ig_attempts);
@@ -543,7 +541,7 @@ retry:
543void 541void
544xfs_inode_lock_init( 542xfs_inode_lock_init(
545 xfs_inode_t *ip, 543 xfs_inode_t *ip,
546 vnode_t *vp) 544 bhv_vnode_t *vp)
547{ 545{
548 mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, 546 mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
549 "xfsino", (long)vp->v_number); 547 "xfsino", (long)vp->v_number);
@@ -603,12 +601,10 @@ void
603xfs_iput(xfs_inode_t *ip, 601xfs_iput(xfs_inode_t *ip,
604 uint lock_flags) 602 uint lock_flags)
605{ 603{
606 vnode_t *vp = XFS_ITOV(ip); 604 bhv_vnode_t *vp = XFS_ITOV(ip);
607 605
608 vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address); 606 vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address);
609
610 xfs_iunlock(ip, lock_flags); 607 xfs_iunlock(ip, lock_flags);
611
612 VN_RELE(vp); 608 VN_RELE(vp);
613} 609}
614 610
@@ -619,7 +615,7 @@ void
619xfs_iput_new(xfs_inode_t *ip, 615xfs_iput_new(xfs_inode_t *ip,
620 uint lock_flags) 616 uint lock_flags)
621{ 617{
622 vnode_t *vp = XFS_ITOV(ip); 618 bhv_vnode_t *vp = XFS_ITOV(ip);
623 struct inode *inode = vn_to_inode(vp); 619 struct inode *inode = vn_to_inode(vp);
624 620
625 vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address); 621 vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
@@ -645,7 +641,7 @@ xfs_iput_new(xfs_inode_t *ip,
645void 641void
646xfs_ireclaim(xfs_inode_t *ip) 642xfs_ireclaim(xfs_inode_t *ip)
647{ 643{
648 vnode_t *vp; 644 bhv_vnode_t *vp;
649 645
650 /* 646 /*
651 * Remove from old hash list and mount list. 647 * Remove from old hash list and mount list.
@@ -1033,6 +1029,6 @@ xfs_iflock_nowait(xfs_inode_t *ip)
1033void 1029void
1034xfs_ifunlock(xfs_inode_t *ip) 1030xfs_ifunlock(xfs_inode_t *ip)
1035{ 1031{
1036 ASSERT(valusema(&(ip->i_flock)) <= 0); 1032 ASSERT(issemalocked(&(ip->i_flock)));
1037 vsema(&(ip->i_flock)); 1033 vsema(&(ip->i_flock));
1038} 1034}
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 94b60dd03801..5fa0adb7e173 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -26,14 +26,12 @@
26#include "xfs_trans_priv.h" 26#include "xfs_trans_priv.h"
27#include "xfs_sb.h" 27#include "xfs_sb.h"
28#include "xfs_ag.h" 28#include "xfs_ag.h"
29#include "xfs_dir.h"
30#include "xfs_dir2.h" 29#include "xfs_dir2.h"
31#include "xfs_dmapi.h" 30#include "xfs_dmapi.h"
32#include "xfs_mount.h" 31#include "xfs_mount.h"
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -256,13 +254,11 @@ xfs_itobp(
256 xfs_daddr_t bno, 254 xfs_daddr_t bno,
257 uint imap_flags) 255 uint imap_flags)
258{ 256{
257 xfs_imap_t imap;
259 xfs_buf_t *bp; 258 xfs_buf_t *bp;
260 int error; 259 int error;
261 xfs_imap_t imap;
262#ifdef __KERNEL__
263 int i; 260 int i;
264 int ni; 261 int ni;
265#endif
266 262
267 if (ip->i_blkno == (xfs_daddr_t)0) { 263 if (ip->i_blkno == (xfs_daddr_t)0) {
268 /* 264 /*
@@ -319,7 +315,6 @@ xfs_itobp(
319 */ 315 */
320 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno, 316 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno,
321 (int)imap.im_len, XFS_BUF_LOCK, &bp); 317 (int)imap.im_len, XFS_BUF_LOCK, &bp);
322
323 if (error) { 318 if (error) {
324#ifdef DEBUG 319#ifdef DEBUG
325 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: " 320 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: "
@@ -330,17 +325,21 @@ xfs_itobp(
330#endif /* DEBUG */ 325#endif /* DEBUG */
331 return error; 326 return error;
332 } 327 }
333#ifdef __KERNEL__ 328
334 /* 329 /*
335 * Validate the magic number and version of every inode in the buffer 330 * Validate the magic number and version of every inode in the buffer
336 * (if DEBUG kernel) or the first inode in the buffer, otherwise. 331 * (if DEBUG kernel) or the first inode in the buffer, otherwise.
332 * No validation is done here in userspace (xfs_repair).
337 */ 333 */
338#ifdef DEBUG 334#if !defined(__KERNEL__)
335 ni = 0;
336#elif defined(DEBUG)
339 ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 337 ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 :
340 (BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog); 338 (BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog);
341#else 339#else /* usual case */
342 ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1; 340 ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1;
343#endif 341#endif
342
344 for (i = 0; i < ni; i++) { 343 for (i = 0; i < ni; i++) {
345 int di_ok; 344 int di_ok;
346 xfs_dinode_t *dip; 345 xfs_dinode_t *dip;
@@ -352,8 +351,11 @@ xfs_itobp(
352 if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, 351 if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
353 XFS_RANDOM_ITOBP_INOTOBP))) { 352 XFS_RANDOM_ITOBP_INOTOBP))) {
354#ifdef DEBUG 353#ifdef DEBUG
355 prdev("bad inode magic/vsn daddr %lld #%d (magic=%x)", 354 if (!(imap_flags & XFS_IMAP_BULKSTAT))
356 mp->m_ddev_targp, 355 cmn_err(CE_ALERT,
356 "Device %s - bad inode magic/vsn "
357 "daddr %lld #%d (magic=%x)",
358 XFS_BUFTARG_NAME(mp->m_ddev_targp),
357 (unsigned long long)imap.im_blkno, i, 359 (unsigned long long)imap.im_blkno, i,
358 INT_GET(dip->di_core.di_magic, ARCH_CONVERT)); 360 INT_GET(dip->di_core.di_magic, ARCH_CONVERT));
359#endif 361#endif
@@ -363,7 +365,6 @@ xfs_itobp(
363 return XFS_ERROR(EFSCORRUPTED); 365 return XFS_ERROR(EFSCORRUPTED);
364 } 366 }
365 } 367 }
366#endif /* __KERNEL__ */
367 368
368 xfs_inobp_check(mp, bp); 369 xfs_inobp_check(mp, bp);
369 370
@@ -782,7 +783,6 @@ xfs_xlate_dinode_core(
782 783
783STATIC uint 784STATIC uint
784_xfs_dic2xflags( 785_xfs_dic2xflags(
785 xfs_dinode_core_t *dic,
786 __uint16_t di_flags) 786 __uint16_t di_flags)
787{ 787{
788 uint flags = 0; 788 uint flags = 0;
@@ -812,6 +812,8 @@ _xfs_dic2xflags(
812 flags |= XFS_XFLAG_EXTSIZE; 812 flags |= XFS_XFLAG_EXTSIZE;
813 if (di_flags & XFS_DIFLAG_EXTSZINHERIT) 813 if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
814 flags |= XFS_XFLAG_EXTSZINHERIT; 814 flags |= XFS_XFLAG_EXTSZINHERIT;
815 if (di_flags & XFS_DIFLAG_NODEFRAG)
816 flags |= XFS_XFLAG_NODEFRAG;
815 } 817 }
816 818
817 return flags; 819 return flags;
@@ -823,16 +825,16 @@ xfs_ip2xflags(
823{ 825{
824 xfs_dinode_core_t *dic = &ip->i_d; 826 xfs_dinode_core_t *dic = &ip->i_d;
825 827
826 return _xfs_dic2xflags(dic, dic->di_flags) | 828 return _xfs_dic2xflags(dic->di_flags) |
827 (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0); 829 (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0);
828} 830}
829 831
830uint 832uint
831xfs_dic2xflags( 833xfs_dic2xflags(
832 xfs_dinode_core_t *dic) 834 xfs_dinode_core_t *dic)
833{ 835{
834 return _xfs_dic2xflags(dic, INT_GET(dic->di_flags, ARCH_CONVERT)) | 836 return _xfs_dic2xflags(INT_GET(dic->di_flags, ARCH_CONVERT)) |
835 (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0); 837 (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0);
836} 838}
837 839
838/* 840/*
@@ -1083,7 +1085,7 @@ xfs_ialloc(
1083{ 1085{
1084 xfs_ino_t ino; 1086 xfs_ino_t ino;
1085 xfs_inode_t *ip; 1087 xfs_inode_t *ip;
1086 vnode_t *vp; 1088 bhv_vnode_t *vp;
1087 uint flags; 1089 uint flags;
1088 int error; 1090 int error;
1089 1091
@@ -1221,6 +1223,9 @@ xfs_ialloc(
1221 di_flags |= XFS_DIFLAG_NOSYMLINKS; 1223 di_flags |= XFS_DIFLAG_NOSYMLINKS;
1222 if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) 1224 if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
1223 di_flags |= XFS_DIFLAG_PROJINHERIT; 1225 di_flags |= XFS_DIFLAG_PROJINHERIT;
1226 if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) &&
1227 xfs_inherit_nodefrag)
1228 di_flags |= XFS_DIFLAG_NODEFRAG;
1224 ip->i_d.di_flags |= di_flags; 1229 ip->i_d.di_flags |= di_flags;
1225 } 1230 }
1226 /* FALLTHROUGH */ 1231 /* FALLTHROUGH */
@@ -1244,8 +1249,8 @@ xfs_ialloc(
1244 */ 1249 */
1245 xfs_trans_log_inode(tp, ip, flags); 1250 xfs_trans_log_inode(tp, ip, flags);
1246 1251
1247 /* now that we have an i_mode we can set Linux inode ops (& unlock) */ 1252 /* now that we have an i_mode we can setup inode ops and unlock */
1248 VFS_INIT_VNODE(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1); 1253 bhv_vfs_init_vnode(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1);
1249 1254
1250 *ipp = ip; 1255 *ipp = ip;
1251 return 0; 1256 return 0;
@@ -1285,7 +1290,7 @@ xfs_isize_check(
1285 (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) - 1290 (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) -
1286 map_first), 1291 map_first),
1287 XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps, 1292 XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps,
1288 NULL)) 1293 NULL, NULL))
1289 return; 1294 return;
1290 ASSERT(nimaps == 1); 1295 ASSERT(nimaps == 1);
1291 ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK); 1296 ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK);
@@ -1421,7 +1426,7 @@ xfs_itruncate_start(
1421 xfs_fsize_t last_byte; 1426 xfs_fsize_t last_byte;
1422 xfs_off_t toss_start; 1427 xfs_off_t toss_start;
1423 xfs_mount_t *mp; 1428 xfs_mount_t *mp;
1424 vnode_t *vp; 1429 bhv_vnode_t *vp;
1425 1430
1426 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); 1431 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
1427 ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size)); 1432 ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size));
@@ -1434,9 +1439,9 @@ xfs_itruncate_start(
1434 vn_iowait(vp); /* wait for the completion of any pending DIOs */ 1439 vn_iowait(vp); /* wait for the completion of any pending DIOs */
1435 1440
1436 /* 1441 /*
1437 * Call VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES() to get rid of pages and buffers 1442 * Call toss_pages or flushinval_pages to get rid of pages
1438 * overlapping the region being removed. We have to use 1443 * overlapping the region being removed. We have to use
1439 * the less efficient VOP_FLUSHINVAL_PAGES() in the case that the 1444 * the less efficient flushinval_pages in the case that the
1440 * caller may not be able to finish the truncate without 1445 * caller may not be able to finish the truncate without
1441 * dropping the inode's I/O lock. Make sure 1446 * dropping the inode's I/O lock. Make sure
1442 * to catch any pages brought in by buffers overlapping 1447 * to catch any pages brought in by buffers overlapping
@@ -1445,10 +1450,10 @@ xfs_itruncate_start(
1445 * so that we don't toss things on the same block as 1450 * so that we don't toss things on the same block as
1446 * new_size but before it. 1451 * new_size but before it.
1447 * 1452 *
1448 * Before calling VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES(), make sure to 1453 * Before calling toss_page or flushinval_pages, make sure to
1449 * call remapf() over the same region if the file is mapped. 1454 * call remapf() over the same region if the file is mapped.
1450 * This frees up mapped file references to the pages in the 1455 * This frees up mapped file references to the pages in the
1451 * given range and for the VOP_FLUSHINVAL_PAGES() case it ensures 1456 * given range and for the flushinval_pages case it ensures
1452 * that we get the latest mapped changes flushed out. 1457 * that we get the latest mapped changes flushed out.
1453 */ 1458 */
1454 toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size); 1459 toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
@@ -1466,9 +1471,9 @@ xfs_itruncate_start(
1466 last_byte); 1471 last_byte);
1467 if (last_byte > toss_start) { 1472 if (last_byte > toss_start) {
1468 if (flags & XFS_ITRUNC_DEFINITE) { 1473 if (flags & XFS_ITRUNC_DEFINITE) {
1469 VOP_TOSS_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED); 1474 bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
1470 } else { 1475 } else {
1471 VOP_FLUSHINVAL_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED); 1476 bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
1472 } 1477 }
1473 } 1478 }
1474 1479
@@ -1666,12 +1671,13 @@ xfs_itruncate_finish(
1666 * runs. 1671 * runs.
1667 */ 1672 */
1668 XFS_BMAP_INIT(&free_list, &first_block); 1673 XFS_BMAP_INIT(&free_list, &first_block);
1669 error = xfs_bunmapi(ntp, ip, first_unmap_block, 1674 error = XFS_BUNMAPI(mp, ntp, &ip->i_iocore,
1670 unmap_len, 1675 first_unmap_block, unmap_len,
1671 XFS_BMAPI_AFLAG(fork) | 1676 XFS_BMAPI_AFLAG(fork) |
1672 (sync ? 0 : XFS_BMAPI_ASYNC), 1677 (sync ? 0 : XFS_BMAPI_ASYNC),
1673 XFS_ITRUNC_MAX_EXTENTS, 1678 XFS_ITRUNC_MAX_EXTENTS,
1674 &first_block, &free_list, &done); 1679 &first_block, &free_list,
1680 NULL, &done);
1675 if (error) { 1681 if (error) {
1676 /* 1682 /*
1677 * If the bunmapi call encounters an error, 1683 * If the bunmapi call encounters an error,
@@ -2745,13 +2751,14 @@ xfs_iunpin(
2745 * the inode to become unpinned. 2751 * the inode to become unpinned.
2746 */ 2752 */
2747 if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { 2753 if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
2748 vnode_t *vp = XFS_ITOV_NULL(ip); 2754 bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
2749 2755
2750 /* make sync come back and flush this inode */ 2756 /* make sync come back and flush this inode */
2751 if (vp) { 2757 if (vp) {
2752 struct inode *inode = vn_to_inode(vp); 2758 struct inode *inode = vn_to_inode(vp);
2753 2759
2754 if (!(inode->i_state & I_NEW)) 2760 if (!(inode->i_state &
2761 (I_NEW|I_FREEING|I_CLEAR)))
2755 mark_inode_dirty_sync(inode); 2762 mark_inode_dirty_sync(inode);
2756 } 2763 }
2757 } 2764 }
@@ -2916,13 +2923,6 @@ xfs_iflush_fork(
2916 ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); 2923 ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
2917 memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes); 2924 memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
2918 } 2925 }
2919 if (whichfork == XFS_DATA_FORK) {
2920 if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) {
2921 XFS_ERROR_REPORT("xfs_iflush_fork",
2922 XFS_ERRLEVEL_LOW, mp);
2923 return XFS_ERROR(EFSCORRUPTED);
2924 }
2925 }
2926 break; 2926 break;
2927 2927
2928 case XFS_DINODE_FMT_EXTENTS: 2928 case XFS_DINODE_FMT_EXTENTS:
@@ -3006,7 +3006,7 @@ xfs_iflush(
3006 XFS_STATS_INC(xs_iflush_count); 3006 XFS_STATS_INC(xs_iflush_count);
3007 3007
3008 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); 3008 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
3009 ASSERT(valusema(&ip->i_flock) <= 0); 3009 ASSERT(issemalocked(&(ip->i_flock)));
3010 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || 3010 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
3011 ip->i_d.di_nextents > ip->i_df.if_ext_max); 3011 ip->i_d.di_nextents > ip->i_df.if_ext_max);
3012 3012
@@ -3199,7 +3199,7 @@ xfs_iflush(
3199 3199
3200corrupt_out: 3200corrupt_out:
3201 xfs_buf_relse(bp); 3201 xfs_buf_relse(bp);
3202 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 3202 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
3203 xfs_iflush_abort(ip); 3203 xfs_iflush_abort(ip);
3204 /* 3204 /*
3205 * Unlocks the flush lock 3205 * Unlocks the flush lock
@@ -3221,7 +3221,7 @@ cluster_corrupt_out:
3221 xfs_buf_relse(bp); 3221 xfs_buf_relse(bp);
3222 } 3222 }
3223 3223
3224 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 3224 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
3225 3225
3226 if(!bufwasdelwri) { 3226 if(!bufwasdelwri) {
3227 /* 3227 /*
@@ -3264,7 +3264,7 @@ xfs_iflush_int(
3264 SPLDECL(s); 3264 SPLDECL(s);
3265 3265
3266 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); 3266 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
3267 ASSERT(valusema(&ip->i_flock) <= 0); 3267 ASSERT(issemalocked(&(ip->i_flock)));
3268 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || 3268 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
3269 ip->i_d.di_nextents > ip->i_df.if_ext_max); 3269 ip->i_d.di_nextents > ip->i_df.if_ext_max);
3270 3270
@@ -3504,7 +3504,7 @@ xfs_iflush_all(
3504 xfs_mount_t *mp) 3504 xfs_mount_t *mp)
3505{ 3505{
3506 xfs_inode_t *ip; 3506 xfs_inode_t *ip;
3507 vnode_t *vp; 3507 bhv_vnode_t *vp;
3508 3508
3509 again: 3509 again:
3510 XFS_MOUNT_ILOCK(mp); 3510 XFS_MOUNT_ILOCK(mp);
@@ -4180,7 +4180,7 @@ xfs_iext_direct_to_inline(
4180 */ 4180 */
4181 memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, 4181 memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents,
4182 nextents * sizeof(xfs_bmbt_rec_t)); 4182 nextents * sizeof(xfs_bmbt_rec_t));
4183 kmem_free(ifp->if_u1.if_extents, KM_SLEEP); 4183 kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes);
4184 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; 4184 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
4185 ifp->if_real_bytes = 0; 4185 ifp->if_real_bytes = 0;
4186} 4186}
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 3b544db1790b..d10b76ed1e5b 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -102,9 +102,9 @@ typedef struct xfs_ifork {
102 102
103#ifdef __KERNEL__ 103#ifdef __KERNEL__
104struct bhv_desc; 104struct bhv_desc;
105struct bhv_vnode;
105struct cred; 106struct cred;
106struct ktrace; 107struct ktrace;
107struct vnode;
108struct xfs_buf; 108struct xfs_buf;
109struct xfs_bmap_free; 109struct xfs_bmap_free;
110struct xfs_bmbt_irec; 110struct xfs_bmbt_irec;
@@ -400,7 +400,7 @@ void xfs_chash_init(struct xfs_mount *);
400void xfs_chash_free(struct xfs_mount *); 400void xfs_chash_free(struct xfs_mount *);
401xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, 401xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t,
402 struct xfs_trans *); 402 struct xfs_trans *);
403void xfs_inode_lock_init(xfs_inode_t *, struct vnode *); 403void xfs_inode_lock_init(xfs_inode_t *, struct bhv_vnode *);
404int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, 404int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
405 uint, uint, xfs_inode_t **, xfs_daddr_t); 405 uint, uint, xfs_inode_t **, xfs_daddr_t);
406void xfs_iput(xfs_inode_t *, uint); 406void xfs_iput(xfs_inode_t *, uint);
@@ -461,7 +461,7 @@ void xfs_ichgtime(xfs_inode_t *, int);
461xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); 461xfs_fsize_t xfs_file_last_byte(xfs_inode_t *);
462void xfs_lock_inodes(xfs_inode_t **, int, int, uint); 462void xfs_lock_inodes(xfs_inode_t **, int, int, uint);
463 463
464xfs_inode_t *xfs_vtoi(struct vnode *vp); 464xfs_inode_t *xfs_vtoi(struct bhv_vnode *vp);
465 465
466void xfs_synchronize_atime(xfs_inode_t *); 466void xfs_synchronize_atime(xfs_inode_t *);
467 467
@@ -509,7 +509,6 @@ extern struct kmem_zone *xfs_chashlist_zone;
509extern struct kmem_zone *xfs_ifork_zone; 509extern struct kmem_zone *xfs_ifork_zone;
510extern struct kmem_zone *xfs_inode_zone; 510extern struct kmem_zone *xfs_inode_zone;
511extern struct kmem_zone *xfs_ili_zone; 511extern struct kmem_zone *xfs_ili_zone;
512extern struct vnodeops xfs_vnodeops;
513 512
514#endif /* __KERNEL__ */ 513#endif /* __KERNEL__ */
515 514
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 7497a481b2f5..f8e80d8e7237 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -25,7 +25,6 @@
25#include "xfs_buf_item.h" 25#include "xfs_buf_item.h"
26#include "xfs_sb.h" 26#include "xfs_sb.h"
27#include "xfs_ag.h" 27#include "xfs_ag.h"
28#include "xfs_dir.h"
29#include "xfs_dir2.h" 28#include "xfs_dir2.h"
30#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
31#include "xfs_mount.h" 30#include "xfs_mount.h"
@@ -33,7 +32,6 @@
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -794,7 +792,7 @@ xfs_inode_item_pushbuf(
794 * inode flush completed and the inode was taken off the AIL. 792 * inode flush completed and the inode was taken off the AIL.
795 * So, just get out. 793 * So, just get out.
796 */ 794 */
797 if ((valusema(&(ip->i_flock)) > 0) || 795 if (!issemalocked(&(ip->i_flock)) ||
798 ((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) { 796 ((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) {
799 iip->ili_pushbuf_flag = 0; 797 iip->ili_pushbuf_flag = 0;
800 xfs_iunlock(ip, XFS_ILOCK_SHARED); 798 xfs_iunlock(ip, XFS_ILOCK_SHARED);
@@ -816,7 +814,7 @@ xfs_inode_item_pushbuf(
816 * If not, we can flush it async. 814 * If not, we can flush it async.
817 */ 815 */
818 dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) && 816 dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) &&
819 (valusema(&(ip->i_flock)) <= 0)); 817 issemalocked(&(ip->i_flock)));
820 iip->ili_pushbuf_flag = 0; 818 iip->ili_pushbuf_flag = 0;
821 xfs_iunlock(ip, XFS_ILOCK_SHARED); 819 xfs_iunlock(ip, XFS_ILOCK_SHARED);
822 xfs_buftrace("INODE ITEM PUSH", bp); 820 xfs_buftrace("INODE ITEM PUSH", bp);
@@ -864,7 +862,7 @@ xfs_inode_item_push(
864 ip = iip->ili_inode; 862 ip = iip->ili_inode;
865 863
866 ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS)); 864 ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS));
867 ASSERT(valusema(&(ip->i_flock)) <= 0); 865 ASSERT(issemalocked(&(ip->i_flock)));
868 /* 866 /*
869 * Since we were able to lock the inode's flush lock and 867 * Since we were able to lock the inode's flush lock and
870 * we found it on the AIL, the inode must be dirty. This 868 * we found it on the AIL, the inode must be dirty. This
@@ -1084,3 +1082,52 @@ xfs_istale_done(
1084{ 1082{
1085 xfs_iflush_abort(iip->ili_inode); 1083 xfs_iflush_abort(iip->ili_inode);
1086} 1084}
1085
1086/*
1087 * convert an xfs_inode_log_format struct from either 32 or 64 bit versions
1088 * (which can have different field alignments) to the native version
1089 */
1090int
1091xfs_inode_item_format_convert(
1092 xfs_log_iovec_t *buf,
1093 xfs_inode_log_format_t *in_f)
1094{
1095 if (buf->i_len == sizeof(xfs_inode_log_format_32_t)) {
1096 xfs_inode_log_format_32_t *in_f32;
1097
1098 in_f32 = (xfs_inode_log_format_32_t *)buf->i_addr;
1099 in_f->ilf_type = in_f32->ilf_type;
1100 in_f->ilf_size = in_f32->ilf_size;
1101 in_f->ilf_fields = in_f32->ilf_fields;
1102 in_f->ilf_asize = in_f32->ilf_asize;
1103 in_f->ilf_dsize = in_f32->ilf_dsize;
1104 in_f->ilf_ino = in_f32->ilf_ino;
1105 /* copy biggest field of ilf_u */
1106 memcpy(in_f->ilf_u.ilfu_uuid.__u_bits,
1107 in_f32->ilf_u.ilfu_uuid.__u_bits,
1108 sizeof(uuid_t));
1109 in_f->ilf_blkno = in_f32->ilf_blkno;
1110 in_f->ilf_len = in_f32->ilf_len;
1111 in_f->ilf_boffset = in_f32->ilf_boffset;
1112 return 0;
1113 } else if (buf->i_len == sizeof(xfs_inode_log_format_64_t)){
1114 xfs_inode_log_format_64_t *in_f64;
1115
1116 in_f64 = (xfs_inode_log_format_64_t *)buf->i_addr;
1117 in_f->ilf_type = in_f64->ilf_type;
1118 in_f->ilf_size = in_f64->ilf_size;
1119 in_f->ilf_fields = in_f64->ilf_fields;
1120 in_f->ilf_asize = in_f64->ilf_asize;
1121 in_f->ilf_dsize = in_f64->ilf_dsize;
1122 in_f->ilf_ino = in_f64->ilf_ino;
1123 /* copy biggest field of ilf_u */
1124 memcpy(in_f->ilf_u.ilfu_uuid.__u_bits,
1125 in_f64->ilf_u.ilfu_uuid.__u_bits,
1126 sizeof(uuid_t));
1127 in_f->ilf_blkno = in_f64->ilf_blkno;
1128 in_f->ilf_len = in_f64->ilf_len;
1129 in_f->ilf_boffset = in_f64->ilf_boffset;
1130 return 0;
1131 }
1132 return EFSCORRUPTED;
1133}
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h
index c5dbf93b6661..5db6cd1b4cf3 100644
--- a/fs/xfs/xfs_inode_item.h
+++ b/fs/xfs/xfs_inode_item.h
@@ -23,25 +23,6 @@
23 * log. The size of the inline data/extents/b-tree root to be logged 23 * log. The size of the inline data/extents/b-tree root to be logged
24 * (if any) is indicated in the ilf_dsize field. Changes to this structure 24 * (if any) is indicated in the ilf_dsize field. Changes to this structure
25 * must be added on to the end. 25 * must be added on to the end.
26 *
27 * Convention for naming inode log item versions : The current version
28 * is always named XFS_LI_INODE. When an inode log item gets superseded,
29 * add the latest version of IRIX that will generate logs with that item
30 * to the version name.
31 *
32 * -Version 1 of this structure (XFS_LI_5_3_INODE) included up to the first
33 * union (ilf_u) field. This was released with IRIX 5.3-XFS.
34 * -Version 2 of this structure (XFS_LI_6_1_INODE) is currently the entire
35 * structure. This was released with IRIX 6.0.1-XFS and IRIX 6.1.
36 * -Version 3 of this structure (XFS_LI_INODE) is the same as version 2
37 * so a new structure definition wasn't necessary. However, we had
38 * to add a new type because the inode cluster size changed from 4K
39 * to 8K and the version number had to be rev'ved to keep older kernels
40 * from trying to recover logs with the 8K buffers in them. The logging
41 * code can handle recovery on different-sized clusters now so hopefully
42 * this'll be the last time we need to change the inode log item just
43 * for a change in the inode cluster size. This new version was
44 * released with IRIX 6.2.
45 */ 26 */
46typedef struct xfs_inode_log_format { 27typedef struct xfs_inode_log_format {
47 unsigned short ilf_type; /* inode log item type */ 28 unsigned short ilf_type; /* inode log item type */
@@ -59,18 +40,38 @@ typedef struct xfs_inode_log_format {
59 int ilf_boffset; /* off of inode in buffer */ 40 int ilf_boffset; /* off of inode in buffer */
60} xfs_inode_log_format_t; 41} xfs_inode_log_format_t;
61 42
62/* Initial version shipped with IRIX 5.3-XFS */ 43typedef struct xfs_inode_log_format_32 {
63typedef struct xfs_inode_log_format_v1 { 44 unsigned short ilf_type; /* 16: inode log item type */
64 unsigned short ilf_type; /* inode log item type */ 45 unsigned short ilf_size; /* 16: size of this item */
65 unsigned short ilf_size; /* size of this item */ 46 uint ilf_fields; /* 32: flags for fields logged */
66 uint ilf_fields; /* flags for fields logged */ 47 ushort ilf_asize; /* 32: size of attr d/ext/root */
67 uint ilf_dsize; /* size of data/ext/root */ 48 ushort ilf_dsize; /* 32: size of data/ext/root */
68 xfs_ino_t ilf_ino; /* inode number */ 49 xfs_ino_t ilf_ino; /* 64: inode number */
69 union { 50 union {
70 xfs_dev_t ilfu_rdev; /* rdev value for dev inode*/ 51 xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
71 uuid_t ilfu_uuid; /* mount point value */ 52 uuid_t ilfu_uuid; /* 128: mount point value */
53 } ilf_u;
54 __int64_t ilf_blkno; /* 64: blkno of inode buffer */
55 int ilf_len; /* 32: len of inode buffer */
56 int ilf_boffset; /* 32: off of inode in buffer */
57} __attribute__((packed)) xfs_inode_log_format_32_t;
58
59typedef struct xfs_inode_log_format_64 {
60 unsigned short ilf_type; /* 16: inode log item type */
61 unsigned short ilf_size; /* 16: size of this item */
62 uint ilf_fields; /* 32: flags for fields logged */
63 ushort ilf_asize; /* 32: size of attr d/ext/root */
64 ushort ilf_dsize; /* 32: size of data/ext/root */
65 __uint32_t ilf_pad; /* 32: pad for 64 bit boundary */
66 xfs_ino_t ilf_ino; /* 64: inode number */
67 union {
68 xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
69 uuid_t ilfu_uuid; /* 128: mount point value */
72 } ilf_u; 70 } ilf_u;
73} xfs_inode_log_format_t_v1; 71 __int64_t ilf_blkno; /* 64: blkno of inode buffer */
72 int ilf_len; /* 32: len of inode buffer */
73 int ilf_boffset; /* 32: off of inode in buffer */
74} xfs_inode_log_format_64_t;
74 75
75/* 76/*
76 * Flags for xfs_trans_log_inode flags field. 77 * Flags for xfs_trans_log_inode flags field.
@@ -172,6 +173,8 @@ extern void xfs_inode_item_destroy(struct xfs_inode *);
172extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *); 173extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *);
173extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *); 174extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *);
174extern void xfs_iflush_abort(struct xfs_inode *); 175extern void xfs_iflush_abort(struct xfs_inode *);
176extern int xfs_inode_item_format_convert(xfs_log_iovec_t *,
177 xfs_inode_log_format_t *);
175 178
176#endif /* __KERNEL__ */ 179#endif /* __KERNEL__ */
177 180
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c
index a07815661a8c..06d710c9ce4b 100644
--- a/fs/xfs/xfs_iocore.c
+++ b/fs/xfs/xfs_iocore.c
@@ -24,14 +24,13 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
28#include "xfs_dfrag.h"
29#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
30#include "xfs_mount.h" 30#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -58,7 +57,7 @@ xfs_size_fn(
58 57
59STATIC int 58STATIC int
60xfs_ioinit( 59xfs_ioinit(
61 struct vfs *vfsp, 60 struct bhv_vfs *vfsp,
62 struct xfs_mount_args *mntargs, 61 struct xfs_mount_args *mntargs,
63 int flags) 62 int flags)
64{ 63{
@@ -68,6 +67,7 @@ xfs_ioinit(
68xfs_ioops_t xfs_iocore_xfs = { 67xfs_ioops_t xfs_iocore_xfs = {
69 .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit, 68 .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit,
70 .xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi, 69 .xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi,
70 .xfs_bunmapi_func = (xfs_bunmapi_t) xfs_bunmapi,
71 .xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof, 71 .xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof,
72 .xfs_iomap_write_direct = 72 .xfs_iomap_write_direct =
73 (xfs_iomap_write_direct_t) xfs_iomap_write_direct, 73 (xfs_iomap_write_direct_t) xfs_iomap_write_direct,
@@ -84,6 +84,7 @@ xfs_ioops_t xfs_iocore_xfs = {
84 .xfs_unlock = (xfs_unlk_t) xfs_iunlock, 84 .xfs_unlock = (xfs_unlk_t) xfs_iunlock,
85 .xfs_size_func = (xfs_size_t) xfs_size_fn, 85 .xfs_size_func = (xfs_size_t) xfs_size_fn,
86 .xfs_iodone = (xfs_iodone_t) fs_noerr, 86 .xfs_iodone = (xfs_iodone_t) fs_noerr,
87 .xfs_swap_extents_func = (xfs_swap_extents_t) xfs_swap_extents,
87}; 88};
88 89
89void 90void
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index d5dfedcb8922..f1949c16df15 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -252,7 +250,7 @@ xfs_iomap(
252 error = XFS_BMAPI(mp, NULL, io, offset_fsb, 250 error = XFS_BMAPI(mp, NULL, io, offset_fsb,
253 (xfs_filblks_t)(end_fsb - offset_fsb), 251 (xfs_filblks_t)(end_fsb - offset_fsb),
254 bmapi_flags, NULL, 0, &imap, 252 bmapi_flags, NULL, 0, &imap,
255 &nimaps, NULL); 253 &nimaps, NULL, NULL);
256 254
257 if (error) 255 if (error)
258 goto out; 256 goto out;
@@ -519,8 +517,8 @@ xfs_iomap_write_direct(
519 */ 517 */
520 XFS_BMAP_INIT(&free_list, &firstfsb); 518 XFS_BMAP_INIT(&free_list, &firstfsb);
521 nimaps = 1; 519 nimaps = 1;
522 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, 520 error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb, bmapi_flag,
523 bmapi_flag, &firstfsb, 0, &imap, &nimaps, &free_list); 521 &firstfsb, 0, &imap, &nimaps, &free_list, NULL);
524 if (error) 522 if (error)
525 goto error0; 523 goto error0;
526 524
@@ -610,8 +608,8 @@ xfs_iomap_eof_want_preallocate(
610 while (count_fsb > 0) { 608 while (count_fsb > 0) {
611 imaps = nimaps; 609 imaps = nimaps;
612 firstblock = NULLFSBLOCK; 610 firstblock = NULLFSBLOCK;
613 error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 611 error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 0,
614 0, &firstblock, 0, imap, &imaps, NULL); 612 &firstblock, 0, imap, &imaps, NULL, NULL);
615 if (error) 613 if (error)
616 return error; 614 return error;
617 for (n = 0; n < imaps; n++) { 615 for (n = 0; n < imaps; n++) {
@@ -695,11 +693,11 @@ retry:
695 693
696 nimaps = XFS_WRITE_IMAPS; 694 nimaps = XFS_WRITE_IMAPS;
697 firstblock = NULLFSBLOCK; 695 firstblock = NULLFSBLOCK;
698 error = xfs_bmapi(NULL, ip, offset_fsb, 696 error = XFS_BMAPI(mp, NULL, io, offset_fsb,
699 (xfs_filblks_t)(last_fsb - offset_fsb), 697 (xfs_filblks_t)(last_fsb - offset_fsb),
700 XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | 698 XFS_BMAPI_DELAY | XFS_BMAPI_WRITE |
701 XFS_BMAPI_ENTIRE, &firstblock, 1, imap, 699 XFS_BMAPI_ENTIRE, &firstblock, 1, imap,
702 &nimaps, NULL); 700 &nimaps, NULL, NULL);
703 if (error && (error != ENOSPC)) 701 if (error && (error != ENOSPC))
704 return XFS_ERROR(error); 702 return XFS_ERROR(error);
705 703
@@ -832,9 +830,9 @@ xfs_iomap_write_allocate(
832 } 830 }
833 831
834 /* Go get the actual blocks */ 832 /* Go get the actual blocks */
835 error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, 833 error = XFS_BMAPI(mp, tp, io, map_start_fsb, count_fsb,
836 XFS_BMAPI_WRITE, &first_block, 1, 834 XFS_BMAPI_WRITE, &first_block, 1,
837 imap, &nimaps, &free_list); 835 imap, &nimaps, &free_list, NULL);
838 if (error) 836 if (error)
839 goto trans_cancel; 837 goto trans_cancel;
840 838
@@ -955,9 +953,9 @@ xfs_iomap_write_unwritten(
955 */ 953 */
956 XFS_BMAP_INIT(&free_list, &firstfsb); 954 XFS_BMAP_INIT(&free_list, &firstfsb);
957 nimaps = 1; 955 nimaps = 1;
958 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, 956 error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb,
959 XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, 957 XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb,
960 1, &imap, &nimaps, &free_list); 958 1, &imap, &nimaps, &free_list, NULL);
961 if (error) 959 if (error)
962 goto error_on_bmapi_transaction; 960 goto error_on_bmapi_transaction;
963 961
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 94068d014f27..46249e4d1fea 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -41,11 +39,6 @@
41#include "xfs_error.h" 39#include "xfs_error.h"
42#include "xfs_btree.h" 40#include "xfs_btree.h"
43 41
44#ifndef HAVE_USERACC
45#define useracc(ubuffer, size, flags, foo) (0)
46#define unuseracc(ubuffer, size, flags)
47#endif
48
49STATIC int 42STATIC int
50xfs_bulkstat_one_iget( 43xfs_bulkstat_one_iget(
51 xfs_mount_t *mp, /* mount point for filesystem */ 44 xfs_mount_t *mp, /* mount point for filesystem */
@@ -56,7 +49,7 @@ xfs_bulkstat_one_iget(
56{ 49{
57 xfs_dinode_core_t *dic; /* dinode core info pointer */ 50 xfs_dinode_core_t *dic; /* dinode core info pointer */
58 xfs_inode_t *ip; /* incore inode pointer */ 51 xfs_inode_t *ip; /* incore inode pointer */
59 vnode_t *vp; 52 bhv_vnode_t *vp;
60 int error; 53 int error;
61 54
62 error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno); 55 error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
@@ -336,15 +329,6 @@ xfs_bulkstat(
336 nimask = ~(nicluster - 1); 329 nimask = ~(nicluster - 1);
337 nbcluster = nicluster >> mp->m_sb.sb_inopblog; 330 nbcluster = nicluster >> mp->m_sb.sb_inopblog;
338 /* 331 /*
339 * Lock down the user's buffer. If a buffer was not sent, as in the case
340 * disk quota code calls here, we skip this.
341 */
342 if (ubuffer &&
343 (error = useracc(ubuffer, ubcount * statstruct_size,
344 (B_READ|B_PHYS), NULL))) {
345 return error;
346 }
347 /*
348 * Allocate a page-sized buffer for inode btree records. 332 * Allocate a page-sized buffer for inode btree records.
349 * We could try allocating something smaller, but for normal 333 * We could try allocating something smaller, but for normal
350 * calls we'll always (potentially) need the whole page. 334 * calls we'll always (potentially) need the whole page.
@@ -650,8 +634,6 @@ xfs_bulkstat(
650 * Done, we're either out of filesystem or space to put the data. 634 * Done, we're either out of filesystem or space to put the data.
651 */ 635 */
652 kmem_free(irbuf, NBPC); 636 kmem_free(irbuf, NBPC);
653 if (ubuffer)
654 unuseracc(ubuffer, ubcount * statstruct_size, (B_READ|B_PHYS));
655 *ubcountp = ubelem; 637 *ubcountp = ubelem;
656 if (agno >= mp->m_sb.sb_agcount) { 638 if (agno >= mp->m_sb.sb_agcount) {
657 /* 639 /*
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
index 11eb4e1b18c4..be5f12e07d22 100644
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -45,7 +45,6 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
45 */ 45 */
46#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */ 46#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */
47#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */ 47#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */
48#define BULKSTAT_FG_VFSLOCKED 0x4 /* Already have vfs lock */
49 48
50/* 49/*
51 * Return stat information in bulk (by-inode) for the filesystem. 50 * Return stat information in bulk (by-inode) for the filesystem.
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 32e841d2f26d..d8f5d4cbe8b7 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -36,7 +35,6 @@
36#include "xfs_ialloc_btree.h" 35#include "xfs_ialloc_btree.h"
37#include "xfs_log_recover.h" 36#include "xfs_log_recover.h"
38#include "xfs_trans_priv.h" 37#include "xfs_trans_priv.h"
39#include "xfs_dir_sf.h"
40#include "xfs_dir2_sf.h" 38#include "xfs_dir2_sf.h"
41#include "xfs_attr_sf.h" 39#include "xfs_attr_sf.h"
42#include "xfs_dinode.h" 40#include "xfs_dinode.h"
@@ -402,7 +400,7 @@ xfs_log_release_iclog(xfs_mount_t *mp,
402 xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl; 400 xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
403 401
404 if (xlog_state_release_iclog(log, iclog)) { 402 if (xlog_state_release_iclog(log, iclog)) {
405 xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); 403 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
406 return EIO; 404 return EIO;
407 } 405 }
408 406
@@ -498,9 +496,8 @@ xfs_log_mount(xfs_mount_t *mp,
498 * just worked. 496 * just worked.
499 */ 497 */
500 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { 498 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
501 int error; 499 bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
502 vfs_t *vfsp = XFS_MTOVFS(mp); 500 int error, readonly = (vfsp->vfs_flag & VFS_RDONLY);
503 int readonly = (vfsp->vfs_flag & VFS_RDONLY);
504 501
505 if (readonly) 502 if (readonly)
506 vfsp->vfs_flag &= ~VFS_RDONLY; 503 vfsp->vfs_flag &= ~VFS_RDONLY;
@@ -726,7 +723,7 @@ xfs_log_write(xfs_mount_t * mp,
726 return XFS_ERROR(EIO); 723 return XFS_ERROR(EIO);
727 724
728 if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) { 725 if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) {
729 xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); 726 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
730 } 727 }
731 return error; 728 return error;
732} /* xfs_log_write */ 729} /* xfs_log_write */
@@ -816,9 +813,9 @@ xfs_log_need_covered(xfs_mount_t *mp)
816 SPLDECL(s); 813 SPLDECL(s);
817 int needed = 0, gen; 814 int needed = 0, gen;
818 xlog_t *log = mp->m_log; 815 xlog_t *log = mp->m_log;
819 vfs_t *vfsp = XFS_MTOVFS(mp); 816 bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
820 817
821 if (fs_frozen(vfsp) || XFS_FORCED_SHUTDOWN(mp) || 818 if (vfs_test_for_freeze(vfsp) || XFS_FORCED_SHUTDOWN(mp) ||
822 (vfsp->vfs_flag & VFS_RDONLY)) 819 (vfsp->vfs_flag & VFS_RDONLY))
823 return 0; 820 return 0;
824 821
@@ -956,7 +953,7 @@ xlog_iodone(xfs_buf_t *bp)
956 XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) { 953 XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) {
957 xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp)); 954 xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp));
958 XFS_BUF_STALE(bp); 955 XFS_BUF_STALE(bp);
959 xfs_force_shutdown(l->l_mp, XFS_LOG_IO_ERROR); 956 xfs_force_shutdown(l->l_mp, SHUTDOWN_LOG_IO_ERROR);
960 /* 957 /*
961 * This flag will be propagated to the trans-committed 958 * This flag will be propagated to the trans-committed
962 * callback routines to let them know that the log-commit 959 * callback routines to let them know that the log-commit
@@ -1261,7 +1258,7 @@ xlog_commit_record(xfs_mount_t *mp,
1261 ASSERT_ALWAYS(iclog); 1258 ASSERT_ALWAYS(iclog);
1262 if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp, 1259 if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp,
1263 iclog, XLOG_COMMIT_TRANS))) { 1260 iclog, XLOG_COMMIT_TRANS))) {
1264 xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); 1261 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
1265 } 1262 }
1266 return error; 1263 return error;
1267} /* xlog_commit_record */ 1264} /* xlog_commit_record */
@@ -1790,7 +1787,7 @@ xlog_write(xfs_mount_t * mp,
1790 xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp, 1787 xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp,
1791 "xfs_log_write: reservation ran out. Need to up reservation"); 1788 "xfs_log_write: reservation ran out. Need to up reservation");
1792 /* If we did not panic, shutdown the filesystem */ 1789 /* If we did not panic, shutdown the filesystem */
1793 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 1790 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
1794#endif 1791#endif
1795 } else 1792 } else
1796 ticket->t_curr_res -= len; 1793 ticket->t_curr_res -= len;
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 1f0016b0b4ec..55b4237c2153 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -193,14 +191,14 @@ xlog_header_check_dump(
193{ 191{
194 int b; 192 int b;
195 193
196 printk("%s: SB : uuid = ", __FUNCTION__); 194 cmn_err(CE_DEBUG, "%s: SB : uuid = ", __FUNCTION__);
197 for (b = 0; b < 16; b++) 195 for (b = 0; b < 16; b++)
198 printk("%02x",((unsigned char *)&mp->m_sb.sb_uuid)[b]); 196 cmn_err(CE_DEBUG, "%02x", ((uchar_t *)&mp->m_sb.sb_uuid)[b]);
199 printk(", fmt = %d\n", XLOG_FMT); 197 cmn_err(CE_DEBUG, ", fmt = %d\n", XLOG_FMT);
200 printk(" log : uuid = "); 198 cmn_err(CE_DEBUG, " log : uuid = ");
201 for (b = 0; b < 16; b++) 199 for (b = 0; b < 16; b++)
202 printk("%02x",((unsigned char *)&head->h_fs_uuid)[b]); 200 cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]);
203 printk(", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT)); 201 cmn_err(CE_DEBUG, ", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT));
204} 202}
205#else 203#else
206#define xlog_header_check_dump(mp, head) 204#define xlog_header_check_dump(mp, head)
@@ -282,7 +280,7 @@ xlog_recover_iodone(
282 mp = XFS_BUF_FSPRIVATE(bp, xfs_mount_t *); 280 mp = XFS_BUF_FSPRIVATE(bp, xfs_mount_t *);
283 xfs_ioerror_alert("xlog_recover_iodone", 281 xfs_ioerror_alert("xlog_recover_iodone",
284 mp, bp, XFS_BUF_ADDR(bp)); 282 mp, bp, XFS_BUF_ADDR(bp));
285 xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); 283 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
286 } 284 }
287 XFS_BUF_SET_FSPRIVATE(bp, NULL); 285 XFS_BUF_SET_FSPRIVATE(bp, NULL);
288 XFS_BUF_CLR_IODONE_FUNC(bp); 286 XFS_BUF_CLR_IODONE_FUNC(bp);
@@ -1889,7 +1887,7 @@ xlog_recover_do_inode_buffer(
1889 1887
1890 buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp, 1888 buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp,
1891 next_unlinked_offset); 1889 next_unlinked_offset);
1892 INT_SET(*buffer_nextp, ARCH_CONVERT, *logged_nextp); 1890 *buffer_nextp = *logged_nextp;
1893 } 1891 }
1894 1892
1895 return 0; 1893 return 0;
@@ -2292,12 +2290,22 @@ xlog_recover_do_inode_trans(
2292 int attr_index; 2290 int attr_index;
2293 uint fields; 2291 uint fields;
2294 xfs_dinode_core_t *dicp; 2292 xfs_dinode_core_t *dicp;
2293 int need_free = 0;
2295 2294
2296 if (pass == XLOG_RECOVER_PASS1) { 2295 if (pass == XLOG_RECOVER_PASS1) {
2297 return 0; 2296 return 0;
2298 } 2297 }
2299 2298
2300 in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr; 2299 if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) {
2300 in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr;
2301 } else {
2302 in_f = (xfs_inode_log_format_t *)kmem_alloc(
2303 sizeof(xfs_inode_log_format_t), KM_SLEEP);
2304 need_free = 1;
2305 error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f);
2306 if (error)
2307 goto error;
2308 }
2301 ino = in_f->ilf_ino; 2309 ino = in_f->ilf_ino;
2302 mp = log->l_mp; 2310 mp = log->l_mp;
2303 if (ITEM_TYPE(item) == XFS_LI_INODE) { 2311 if (ITEM_TYPE(item) == XFS_LI_INODE) {
@@ -2323,8 +2331,10 @@ xlog_recover_do_inode_trans(
2323 * Inode buffers can be freed, look out for it, 2331 * Inode buffers can be freed, look out for it,
2324 * and do not replay the inode. 2332 * and do not replay the inode.
2325 */ 2333 */
2326 if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0)) 2334 if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0)) {
2327 return 0; 2335 error = 0;
2336 goto error;
2337 }
2328 2338
2329 bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len, 2339 bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len,
2330 XFS_BUF_LOCK); 2340 XFS_BUF_LOCK);
@@ -2333,7 +2343,7 @@ xlog_recover_do_inode_trans(
2333 bp, imap.im_blkno); 2343 bp, imap.im_blkno);
2334 error = XFS_BUF_GETERROR(bp); 2344 error = XFS_BUF_GETERROR(bp);
2335 xfs_buf_relse(bp); 2345 xfs_buf_relse(bp);
2336 return error; 2346 goto error;
2337 } 2347 }
2338 error = 0; 2348 error = 0;
2339 ASSERT(in_f->ilf_fields & XFS_ILOG_CORE); 2349 ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
@@ -2350,7 +2360,8 @@ xlog_recover_do_inode_trans(
2350 dip, bp, ino); 2360 dip, bp, ino);
2351 XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)", 2361 XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)",
2352 XFS_ERRLEVEL_LOW, mp); 2362 XFS_ERRLEVEL_LOW, mp);
2353 return XFS_ERROR(EFSCORRUPTED); 2363 error = EFSCORRUPTED;
2364 goto error;
2354 } 2365 }
2355 dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr); 2366 dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr);
2356 if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) { 2367 if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
@@ -2360,7 +2371,8 @@ xlog_recover_do_inode_trans(
2360 item, ino); 2371 item, ino);
2361 XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)", 2372 XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)",
2362 XFS_ERRLEVEL_LOW, mp); 2373 XFS_ERRLEVEL_LOW, mp);
2363 return XFS_ERROR(EFSCORRUPTED); 2374 error = EFSCORRUPTED;
2375 goto error;
2364 } 2376 }
2365 2377
2366 /* Skip replay when the on disk inode is newer than the log one */ 2378 /* Skip replay when the on disk inode is newer than the log one */
@@ -2376,7 +2388,8 @@ xlog_recover_do_inode_trans(
2376 /* do nothing */ 2388 /* do nothing */
2377 } else { 2389 } else {
2378 xfs_buf_relse(bp); 2390 xfs_buf_relse(bp);
2379 return 0; 2391 error = 0;
2392 goto error;
2380 } 2393 }
2381 } 2394 }
2382 /* Take the opportunity to reset the flush iteration count */ 2395 /* Take the opportunity to reset the flush iteration count */
@@ -2391,7 +2404,8 @@ xlog_recover_do_inode_trans(
2391 xfs_fs_cmn_err(CE_ALERT, mp, 2404 xfs_fs_cmn_err(CE_ALERT, mp,
2392 "xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", 2405 "xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
2393 item, dip, bp, ino); 2406 item, dip, bp, ino);
2394 return XFS_ERROR(EFSCORRUPTED); 2407 error = EFSCORRUPTED;
2408 goto error;
2395 } 2409 }
2396 } else if (unlikely((dicp->di_mode & S_IFMT) == S_IFDIR)) { 2410 } else if (unlikely((dicp->di_mode & S_IFMT) == S_IFDIR)) {
2397 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && 2411 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
@@ -2403,7 +2417,8 @@ xlog_recover_do_inode_trans(
2403 xfs_fs_cmn_err(CE_ALERT, mp, 2417 xfs_fs_cmn_err(CE_ALERT, mp,
2404 "xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", 2418 "xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
2405 item, dip, bp, ino); 2419 item, dip, bp, ino);
2406 return XFS_ERROR(EFSCORRUPTED); 2420 error = EFSCORRUPTED;
2421 goto error;
2407 } 2422 }
2408 } 2423 }
2409 if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){ 2424 if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){
@@ -2415,7 +2430,8 @@ xlog_recover_do_inode_trans(
2415 item, dip, bp, ino, 2430 item, dip, bp, ino,
2416 dicp->di_nextents + dicp->di_anextents, 2431 dicp->di_nextents + dicp->di_anextents,
2417 dicp->di_nblocks); 2432 dicp->di_nblocks);
2418 return XFS_ERROR(EFSCORRUPTED); 2433 error = EFSCORRUPTED;
2434 goto error;
2419 } 2435 }
2420 if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) { 2436 if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) {
2421 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)", 2437 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)",
@@ -2424,7 +2440,8 @@ xlog_recover_do_inode_trans(
2424 xfs_fs_cmn_err(CE_ALERT, mp, 2440 xfs_fs_cmn_err(CE_ALERT, mp,
2425 "xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x", 2441 "xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x",
2426 item, dip, bp, ino, dicp->di_forkoff); 2442 item, dip, bp, ino, dicp->di_forkoff);
2427 return XFS_ERROR(EFSCORRUPTED); 2443 error = EFSCORRUPTED;
2444 goto error;
2428 } 2445 }
2429 if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) { 2446 if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) {
2430 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)", 2447 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)",
@@ -2433,7 +2450,8 @@ xlog_recover_do_inode_trans(
2433 xfs_fs_cmn_err(CE_ALERT, mp, 2450 xfs_fs_cmn_err(CE_ALERT, mp,
2434 "xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p", 2451 "xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p",
2435 item->ri_buf[1].i_len, item); 2452 item->ri_buf[1].i_len, item);
2436 return XFS_ERROR(EFSCORRUPTED); 2453 error = EFSCORRUPTED;
2454 goto error;
2437 } 2455 }
2438 2456
2439 /* The core is in in-core format */ 2457 /* The core is in in-core format */
@@ -2521,7 +2539,8 @@ xlog_recover_do_inode_trans(
2521 xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag"); 2539 xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag");
2522 ASSERT(0); 2540 ASSERT(0);
2523 xfs_buf_relse(bp); 2541 xfs_buf_relse(bp);
2524 return XFS_ERROR(EIO); 2542 error = EIO;
2543 goto error;
2525 } 2544 }
2526 } 2545 }
2527 2546
@@ -2537,7 +2556,10 @@ write_inode_buffer:
2537 error = xfs_bwrite(mp, bp); 2556 error = xfs_bwrite(mp, bp);
2538 } 2557 }
2539 2558
2540 return (error); 2559error:
2560 if (need_free)
2561 kmem_free(in_f, sizeof(*in_f));
2562 return XFS_ERROR(error);
2541} 2563}
2542 2564
2543/* 2565/*
@@ -2674,32 +2696,32 @@ xlog_recover_do_dquot_trans(
2674 * structure into it, and adds the efi to the AIL with the given 2696 * structure into it, and adds the efi to the AIL with the given
2675 * LSN. 2697 * LSN.
2676 */ 2698 */
2677STATIC void 2699STATIC int
2678xlog_recover_do_efi_trans( 2700xlog_recover_do_efi_trans(
2679 xlog_t *log, 2701 xlog_t *log,
2680 xlog_recover_item_t *item, 2702 xlog_recover_item_t *item,
2681 xfs_lsn_t lsn, 2703 xfs_lsn_t lsn,
2682 int pass) 2704 int pass)
2683{ 2705{
2706 int error;
2684 xfs_mount_t *mp; 2707 xfs_mount_t *mp;
2685 xfs_efi_log_item_t *efip; 2708 xfs_efi_log_item_t *efip;
2686 xfs_efi_log_format_t *efi_formatp; 2709 xfs_efi_log_format_t *efi_formatp;
2687 SPLDECL(s); 2710 SPLDECL(s);
2688 2711
2689 if (pass == XLOG_RECOVER_PASS1) { 2712 if (pass == XLOG_RECOVER_PASS1) {
2690 return; 2713 return 0;
2691 } 2714 }
2692 2715
2693 efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr; 2716 efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr;
2694 ASSERT(item->ri_buf[0].i_len ==
2695 (sizeof(xfs_efi_log_format_t) +
2696 ((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t))));
2697 2717
2698 mp = log->l_mp; 2718 mp = log->l_mp;
2699 efip = xfs_efi_init(mp, efi_formatp->efi_nextents); 2719 efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
2700 memcpy((char *)&(efip->efi_format), (char *)efi_formatp, 2720 if ((error = xfs_efi_copy_format(&(item->ri_buf[0]),
2701 sizeof(xfs_efi_log_format_t) + 2721 &(efip->efi_format)))) {
2702 ((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t))); 2722 xfs_efi_item_free(efip);
2723 return error;
2724 }
2703 efip->efi_next_extent = efi_formatp->efi_nextents; 2725 efip->efi_next_extent = efi_formatp->efi_nextents;
2704 efip->efi_flags |= XFS_EFI_COMMITTED; 2726 efip->efi_flags |= XFS_EFI_COMMITTED;
2705 2727
@@ -2708,6 +2730,7 @@ xlog_recover_do_efi_trans(
2708 * xfs_trans_update_ail() drops the AIL lock. 2730 * xfs_trans_update_ail() drops the AIL lock.
2709 */ 2731 */
2710 xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn, s); 2732 xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn, s);
2733 return 0;
2711} 2734}
2712 2735
2713 2736
@@ -2738,9 +2761,10 @@ xlog_recover_do_efd_trans(
2738 } 2761 }
2739 2762
2740 efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr; 2763 efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr;
2741 ASSERT(item->ri_buf[0].i_len == 2764 ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
2742 (sizeof(xfs_efd_log_format_t) + 2765 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
2743 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_t)))); 2766 (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
2767 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t)))));
2744 efi_id = efd_formatp->efd_efi_id; 2768 efi_id = efd_formatp->efd_efi_id;
2745 2769
2746 /* 2770 /*
@@ -2810,15 +2834,14 @@ xlog_recover_do_trans(
2810 if ((error = xlog_recover_do_buffer_trans(log, item, 2834 if ((error = xlog_recover_do_buffer_trans(log, item,
2811 pass))) 2835 pass)))
2812 break; 2836 break;
2813 } else if ((ITEM_TYPE(item) == XFS_LI_INODE) || 2837 } else if ((ITEM_TYPE(item) == XFS_LI_INODE)) {
2814 (ITEM_TYPE(item) == XFS_LI_6_1_INODE) ||
2815 (ITEM_TYPE(item) == XFS_LI_5_3_INODE)) {
2816 if ((error = xlog_recover_do_inode_trans(log, item, 2838 if ((error = xlog_recover_do_inode_trans(log, item,
2817 pass))) 2839 pass)))
2818 break; 2840 break;
2819 } else if (ITEM_TYPE(item) == XFS_LI_EFI) { 2841 } else if (ITEM_TYPE(item) == XFS_LI_EFI) {
2820 xlog_recover_do_efi_trans(log, item, trans->r_lsn, 2842 if ((error = xlog_recover_do_efi_trans(log, item, trans->r_lsn,
2821 pass); 2843 pass)))
2844 break;
2822 } else if (ITEM_TYPE(item) == XFS_LI_EFD) { 2845 } else if (ITEM_TYPE(item) == XFS_LI_EFD) {
2823 xlog_recover_do_efd_trans(log, item, pass); 2846 xlog_recover_do_efd_trans(log, item, pass);
2824 } else if (ITEM_TYPE(item) == XFS_LI_DQUOT) { 2847 } else if (ITEM_TYPE(item) == XFS_LI_DQUOT) {
@@ -3419,13 +3442,13 @@ xlog_unpack_data_checksum(
3419 if (rhead->h_chksum || 3442 if (rhead->h_chksum ||
3420 ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) { 3443 ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) {
3421 cmn_err(CE_DEBUG, 3444 cmn_err(CE_DEBUG,
3422 "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)", 3445 "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)\n",
3423 INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum); 3446 INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum);
3424 cmn_err(CE_DEBUG, 3447 cmn_err(CE_DEBUG,
3425"XFS: Disregard message if filesystem was created with non-DEBUG kernel"); 3448"XFS: Disregard message if filesystem was created with non-DEBUG kernel");
3426 if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { 3449 if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
3427 cmn_err(CE_DEBUG, 3450 cmn_err(CE_DEBUG,
3428 "XFS: LogR this is a LogV2 filesystem"); 3451 "XFS: LogR this is a LogV2 filesystem\n");
3429 } 3452 }
3430 log->l_flags |= XLOG_CHKSUM_MISMATCH; 3453 log->l_flags |= XLOG_CHKSUM_MISMATCH;
3431 } 3454 }
@@ -3798,7 +3821,7 @@ xlog_do_log_recovery(
3798 error = xlog_do_recovery_pass(log, head_blk, tail_blk, 3821 error = xlog_do_recovery_pass(log, head_blk, tail_blk,
3799 XLOG_RECOVER_PASS2); 3822 XLOG_RECOVER_PASS2);
3800#ifdef DEBUG 3823#ifdef DEBUG
3801 { 3824 if (!error) {
3802 int i; 3825 int i;
3803 3826
3804 for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) 3827 for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
@@ -3974,7 +3997,7 @@ xlog_recover_finish(
3974 log->l_flags &= ~XLOG_RECOVERY_NEEDED; 3997 log->l_flags &= ~XLOG_RECOVERY_NEEDED;
3975 } else { 3998 } else {
3976 cmn_err(CE_DEBUG, 3999 cmn_err(CE_DEBUG,
3977 "!Ending clean XFS mount for filesystem: %s", 4000 "!Ending clean XFS mount for filesystem: %s\n",
3978 log->l_mp->m_fsname); 4001 log->l_mp->m_fsname);
3979 } 4002 }
3980 return 0; 4003 return 0;
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index c0b1c2906880..10dbf203c62f 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -196,7 +194,7 @@ xfs_mount_free(
196 kmem_free(mp->m_logname, strlen(mp->m_logname) + 1); 194 kmem_free(mp->m_logname, strlen(mp->m_logname) + 1);
197 195
198 if (remove_bhv) { 196 if (remove_bhv) {
199 struct vfs *vfsp = XFS_MTOVFS(mp); 197 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
200 198
201 bhv_remove_all_vfsops(vfsp, 0); 199 bhv_remove_all_vfsops(vfsp, 0);
202 VFS_REMOVEBHV(vfsp, &mp->m_bhv); 200 VFS_REMOVEBHV(vfsp, &mp->m_bhv);
@@ -337,7 +335,7 @@ xfs_mount_validate_sb(
337 335
338xfs_agnumber_t 336xfs_agnumber_t
339xfs_initialize_perag( 337xfs_initialize_perag(
340 struct vfs *vfs, 338 bhv_vfs_t *vfs,
341 xfs_mount_t *mp, 339 xfs_mount_t *mp,
342 xfs_agnumber_t agcount) 340 xfs_agnumber_t agcount)
343{ 341{
@@ -651,14 +649,14 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
651 */ 649 */
652int 650int
653xfs_mountfs( 651xfs_mountfs(
654 vfs_t *vfsp, 652 bhv_vfs_t *vfsp,
655 xfs_mount_t *mp, 653 xfs_mount_t *mp,
656 int mfsi_flags) 654 int mfsi_flags)
657{ 655{
658 xfs_buf_t *bp; 656 xfs_buf_t *bp;
659 xfs_sb_t *sbp = &(mp->m_sb); 657 xfs_sb_t *sbp = &(mp->m_sb);
660 xfs_inode_t *rip; 658 xfs_inode_t *rip;
661 vnode_t *rvp = NULL; 659 bhv_vnode_t *rvp = NULL;
662 int readio_log, writeio_log; 660 int readio_log, writeio_log;
663 xfs_daddr_t d; 661 xfs_daddr_t d;
664 __uint64_t ret64; 662 __uint64_t ret64;
@@ -934,18 +932,7 @@ xfs_mountfs(
934 vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid; 932 vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid;
935 mp->m_dmevmask = 0; /* not persistent; set after each mount */ 933 mp->m_dmevmask = 0; /* not persistent; set after each mount */
936 934
937 /* 935 xfs_dir_mount(mp);
938 * Select the right directory manager.
939 */
940 mp->m_dirops =
941 XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ?
942 xfsv2_dirops :
943 xfsv1_dirops;
944
945 /*
946 * Initialize directory manager's entries.
947 */
948 XFS_DIR_MOUNT(mp);
949 936
950 /* 937 /*
951 * Initialize the attribute manager's entries. 938 * Initialize the attribute manager's entries.
@@ -1006,8 +993,9 @@ xfs_mountfs(
1006 993
1007 if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) { 994 if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) {
1008 cmn_err(CE_WARN, "XFS: corrupted root inode"); 995 cmn_err(CE_WARN, "XFS: corrupted root inode");
1009 prdev("Root inode %llu is not a directory", 996 cmn_err(CE_WARN, "Device %s - root %llu is not a directory",
1010 mp->m_ddev_targp, (unsigned long long)rip->i_ino); 997 XFS_BUFTARG_NAME(mp->m_ddev_targp),
998 (unsigned long long)rip->i_ino);
1011 xfs_iunlock(rip, XFS_ILOCK_EXCL); 999 xfs_iunlock(rip, XFS_ILOCK_EXCL);
1012 XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW, 1000 XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
1013 mp); 1001 mp);
@@ -1094,7 +1082,7 @@ xfs_mountfs(
1094int 1082int
1095xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) 1083xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
1096{ 1084{
1097 struct vfs *vfsp = XFS_MTOVFS(mp); 1085 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
1098#if defined(DEBUG) || defined(INDUCE_IO_ERROR) 1086#if defined(DEBUG) || defined(INDUCE_IO_ERROR)
1099 int64_t fsid; 1087 int64_t fsid;
1100#endif 1088#endif
@@ -1254,6 +1242,26 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
1254 1242
1255 xfs_trans_log_buf(tp, bp, first, last); 1243 xfs_trans_log_buf(tp, bp, first, last);
1256} 1244}
1245
1246/*
1247 * In order to avoid ENOSPC-related deadlock caused by
1248 * out-of-order locking of AGF buffer (PV 947395), we place
1249 * constraints on the relationship among actual allocations for
1250 * data blocks, freelist blocks, and potential file data bmap
1251 * btree blocks. However, these restrictions may result in no
1252 * actual space allocated for a delayed extent, for example, a data
1253 * block in a certain AG is allocated but there is no additional
1254 * block for the additional bmap btree block due to a split of the
1255 * bmap btree of the file. The result of this may lead to an
1256 * infinite loop in xfssyncd when the file gets flushed to disk and
1257 * all delayed extents need to be actually allocated. To get around
1258 * this, we explicitly set aside a few blocks which will not be
1259 * reserved in delayed allocation. Considering the minimum number of
1260 * needed freelist blocks is 4 fsbs, a potential split of file's bmap
1261 * btree requires 1 fsb, so we set the number of set-aside blocks to 8.
1262*/
1263#define SET_ASIDE_BLOCKS 8
1264
1257/* 1265/*
1258 * xfs_mod_incore_sb_unlocked() is a utility routine common used to apply 1266 * xfs_mod_incore_sb_unlocked() is a utility routine common used to apply
1259 * a delta to a specified field in the in-core superblock. Simply 1267 * a delta to a specified field in the in-core superblock. Simply
@@ -1298,7 +1306,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
1298 return 0; 1306 return 0;
1299 case XFS_SBS_FDBLOCKS: 1307 case XFS_SBS_FDBLOCKS:
1300 1308
1301 lcounter = (long long)mp->m_sb.sb_fdblocks; 1309 lcounter = (long long)mp->m_sb.sb_fdblocks - SET_ASIDE_BLOCKS;
1302 res_used = (long long)(mp->m_resblks - mp->m_resblks_avail); 1310 res_used = (long long)(mp->m_resblks - mp->m_resblks_avail);
1303 1311
1304 if (delta > 0) { /* Putting blocks back */ 1312 if (delta > 0) { /* Putting blocks back */
@@ -1332,7 +1340,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
1332 } 1340 }
1333 } 1341 }
1334 1342
1335 mp->m_sb.sb_fdblocks = lcounter; 1343 mp->m_sb.sb_fdblocks = lcounter + SET_ASIDE_BLOCKS;
1336 return 0; 1344 return 0;
1337 case XFS_SBS_FREXTENTS: 1345 case XFS_SBS_FREXTENTS:
1338 lcounter = (long long)mp->m_sb.sb_frextents; 1346 lcounter = (long long)mp->m_sb.sb_frextents;
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 668ad23fd37c..b2bd4be4200a 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -53,8 +53,8 @@ typedef struct xfs_trans_reservations {
53#else 53#else
54struct cred; 54struct cred;
55struct log; 55struct log;
56struct vfs; 56struct bhv_vfs;
57struct vnode; 57struct bhv_vnode;
58struct xfs_mount_args; 58struct xfs_mount_args;
59struct xfs_ihash; 59struct xfs_ihash;
60struct xfs_chash; 60struct xfs_chash;
@@ -63,9 +63,11 @@ struct xfs_perag;
63struct xfs_iocore; 63struct xfs_iocore;
64struct xfs_bmbt_irec; 64struct xfs_bmbt_irec;
65struct xfs_bmap_free; 65struct xfs_bmap_free;
66struct xfs_extdelta;
67struct xfs_swapext;
66 68
67extern struct vfsops xfs_vfsops; 69extern struct bhv_vfsops xfs_vfsops;
68extern struct vnodeops xfs_vnodeops; 70extern struct bhv_vnodeops xfs_vnodeops;
69 71
70#define AIL_LOCK_T lock_t 72#define AIL_LOCK_T lock_t
71#define AIL_LOCKINIT(x,y) spinlock_init(x,y) 73#define AIL_LOCKINIT(x,y) spinlock_init(x,y)
@@ -78,15 +80,15 @@ extern struct vnodeops xfs_vnodeops;
78 * Prototypes and functions for the Data Migration subsystem. 80 * Prototypes and functions for the Data Migration subsystem.
79 */ 81 */
80 82
81typedef int (*xfs_send_data_t)(int, struct vnode *, 83typedef int (*xfs_send_data_t)(int, struct bhv_vnode *,
82 xfs_off_t, size_t, int, vrwlock_t *); 84 xfs_off_t, size_t, int, bhv_vrwlock_t *);
83typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); 85typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint);
84typedef int (*xfs_send_destroy_t)(struct vnode *, dm_right_t); 86typedef int (*xfs_send_destroy_t)(struct bhv_vnode *, dm_right_t);
85typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct vfs *, 87typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct bhv_vfs *,
86 struct vnode *, 88 struct bhv_vnode *,
87 dm_right_t, struct vnode *, dm_right_t, 89 dm_right_t, struct bhv_vnode *, dm_right_t,
88 char *, char *, mode_t, int, int); 90 char *, char *, mode_t, int, int);
89typedef void (*xfs_send_unmount_t)(struct vfs *, struct vnode *, 91typedef void (*xfs_send_unmount_t)(struct bhv_vfs *, struct bhv_vnode *,
90 dm_right_t, mode_t, int, int); 92 dm_right_t, mode_t, int, int);
91 93
92typedef struct xfs_dmops { 94typedef struct xfs_dmops {
@@ -188,13 +190,18 @@ typedef struct xfs_qmops {
188 * Prototypes and functions for I/O core modularization. 190 * Prototypes and functions for I/O core modularization.
189 */ 191 */
190 192
191typedef int (*xfs_ioinit_t)(struct vfs *, 193typedef int (*xfs_ioinit_t)(struct bhv_vfs *,
192 struct xfs_mount_args *, int); 194 struct xfs_mount_args *, int);
193typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, 195typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *,
194 xfs_fileoff_t, xfs_filblks_t, int, 196 xfs_fileoff_t, xfs_filblks_t, int,
195 xfs_fsblock_t *, xfs_extlen_t, 197 xfs_fsblock_t *, xfs_extlen_t,
196 struct xfs_bmbt_irec *, int *, 198 struct xfs_bmbt_irec *, int *,
197 struct xfs_bmap_free *); 199 struct xfs_bmap_free *, struct xfs_extdelta *);
200typedef int (*xfs_bunmapi_t)(struct xfs_trans *,
201 void *, xfs_fileoff_t,
202 xfs_filblks_t, int, xfs_extnum_t,
203 xfs_fsblock_t *, struct xfs_bmap_free *,
204 struct xfs_extdelta *, int *);
198typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); 205typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);
199typedef int (*xfs_iomap_write_direct_t)( 206typedef int (*xfs_iomap_write_direct_t)(
200 void *, xfs_off_t, size_t, int, 207 void *, xfs_off_t, size_t, int,
@@ -213,11 +220,14 @@ typedef void (*xfs_lock_demote_t)(void *, uint);
213typedef int (*xfs_lock_nowait_t)(void *, uint); 220typedef int (*xfs_lock_nowait_t)(void *, uint);
214typedef void (*xfs_unlk_t)(void *, unsigned int); 221typedef void (*xfs_unlk_t)(void *, unsigned int);
215typedef xfs_fsize_t (*xfs_size_t)(void *); 222typedef xfs_fsize_t (*xfs_size_t)(void *);
216typedef xfs_fsize_t (*xfs_iodone_t)(struct vfs *); 223typedef xfs_fsize_t (*xfs_iodone_t)(struct bhv_vfs *);
224typedef int (*xfs_swap_extents_t)(void *, void *,
225 struct xfs_swapext*);
217 226
218typedef struct xfs_ioops { 227typedef struct xfs_ioops {
219 xfs_ioinit_t xfs_ioinit; 228 xfs_ioinit_t xfs_ioinit;
220 xfs_bmapi_t xfs_bmapi_func; 229 xfs_bmapi_t xfs_bmapi_func;
230 xfs_bunmapi_t xfs_bunmapi_func;
221 xfs_bmap_eof_t xfs_bmap_eof_func; 231 xfs_bmap_eof_t xfs_bmap_eof_func;
222 xfs_iomap_write_direct_t xfs_iomap_write_direct; 232 xfs_iomap_write_direct_t xfs_iomap_write_direct;
223 xfs_iomap_write_delay_t xfs_iomap_write_delay; 233 xfs_iomap_write_delay_t xfs_iomap_write_delay;
@@ -230,13 +240,17 @@ typedef struct xfs_ioops {
230 xfs_unlk_t xfs_unlock; 240 xfs_unlk_t xfs_unlock;
231 xfs_size_t xfs_size_func; 241 xfs_size_t xfs_size_func;
232 xfs_iodone_t xfs_iodone; 242 xfs_iodone_t xfs_iodone;
243 xfs_swap_extents_t xfs_swap_extents_func;
233} xfs_ioops_t; 244} xfs_ioops_t;
234 245
235#define XFS_IOINIT(vfsp, args, flags) \ 246#define XFS_IOINIT(vfsp, args, flags) \
236 (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags) 247 (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags)
237#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist) \ 248#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \
238 (*(mp)->m_io_ops.xfs_bmapi_func) \ 249 (*(mp)->m_io_ops.xfs_bmapi_func) \
239 (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist) 250 (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta)
251#define XFS_BUNMAPI(mp, trans,io,bno,len,f,nexts,first,flist,delta,done) \
252 (*(mp)->m_io_ops.xfs_bunmapi_func) \
253 (trans,(io)->io_obj,bno,len,f,nexts,first,flist,delta,done)
240#define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \ 254#define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \
241 (*(mp)->m_io_ops.xfs_bmap_eof_func) \ 255 (*(mp)->m_io_ops.xfs_bmap_eof_func) \
242 ((io)->io_obj, endoff, whichfork, eof) 256 ((io)->io_obj, endoff, whichfork, eof)
@@ -266,6 +280,9 @@ typedef struct xfs_ioops {
266 (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj) 280 (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj)
267#define XFS_IODONE(vfsp) \ 281#define XFS_IODONE(vfsp) \
268 (*(mp)->m_io_ops.xfs_iodone)(vfsp) 282 (*(mp)->m_io_ops.xfs_iodone)(vfsp)
283#define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \
284 (*(mp)->m_io_ops.xfs_swap_extents_func) \
285 ((io)->io_obj, (tio)->io_obj, sxp)
269 286
270#ifdef HAVE_PERCPU_SB 287#ifdef HAVE_PERCPU_SB
271 288
@@ -386,8 +403,6 @@ typedef struct xfs_mount {
386 __uint8_t m_inode_quiesce;/* call quiesce on new inodes. 403 __uint8_t m_inode_quiesce;/* call quiesce on new inodes.
387 field governed by m_ilock */ 404 field governed by m_ilock */
388 __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ 405 __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */
389 __uint8_t m_dirversion; /* 1 or 2 */
390 xfs_dirops_t m_dirops; /* table of dir funcs */
391 int m_dirblksize; /* directory block sz--bytes */ 406 int m_dirblksize; /* directory block sz--bytes */
392 int m_dirblkfsbs; /* directory block sz--fsbs */ 407 int m_dirblkfsbs; /* directory block sz--fsbs */
393 xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ 408 xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */
@@ -494,16 +509,7 @@ xfs_preferred_iosize(xfs_mount_t *mp)
494 509
495#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) 510#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
496#define xfs_force_shutdown(m,f) \ 511#define xfs_force_shutdown(m,f) \
497 VFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__) 512 bhv_vfs_force_shutdown((XFS_MTOVFS(m)), f, __FILE__, __LINE__)
498
499/*
500 * Flags sent to xfs_force_shutdown.
501 */
502#define XFS_METADATA_IO_ERROR 0x1
503#define XFS_LOG_IO_ERROR 0x2
504#define XFS_FORCE_UMOUNT 0x4
505#define XFS_CORRUPT_INCORE 0x8 /* Corrupt in-memory data structures */
506#define XFS_SHUTDOWN_REMOTE_REQ 0x10 /* Shutdown came from remote cell */
507 513
508/* 514/*
509 * Flags for xfs_mountfs 515 * Flags for xfs_mountfs
@@ -521,7 +527,7 @@ xfs_preferred_iosize(xfs_mount_t *mp)
521 * Macros for getting from mount to vfs and back. 527 * Macros for getting from mount to vfs and back.
522 */ 528 */
523#define XFS_MTOVFS(mp) xfs_mtovfs(mp) 529#define XFS_MTOVFS(mp) xfs_mtovfs(mp)
524static inline struct vfs *xfs_mtovfs(xfs_mount_t *mp) 530static inline struct bhv_vfs *xfs_mtovfs(xfs_mount_t *mp)
525{ 531{
526 return bhvtovfs(&mp->m_bhv); 532 return bhvtovfs(&mp->m_bhv);
527} 533}
@@ -533,7 +539,7 @@ static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp)
533} 539}
534 540
535#define XFS_VFSTOM(vfs) xfs_vfstom(vfs) 541#define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
536static inline xfs_mount_t *xfs_vfstom(vfs_t *vfs) 542static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs)
537{ 543{
538 return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops)); 544 return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops));
539} 545}
@@ -571,7 +577,7 @@ typedef struct xfs_mod_sb {
571extern xfs_mount_t *xfs_mount_init(void); 577extern xfs_mount_t *xfs_mount_init(void);
572extern void xfs_mod_sb(xfs_trans_t *, __int64_t); 578extern void xfs_mod_sb(xfs_trans_t *, __int64_t);
573extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); 579extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
574extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int); 580extern int xfs_mountfs(struct bhv_vfs *, xfs_mount_t *mp, int);
575extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); 581extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);
576 582
577extern int xfs_unmountfs(xfs_mount_t *, struct cred *); 583extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
@@ -589,7 +595,7 @@ extern void xfs_freesb(xfs_mount_t *);
589extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); 595extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
590extern int xfs_syncsub(xfs_mount_t *, int, int, int *); 596extern int xfs_syncsub(xfs_mount_t *, int, int, int *);
591extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *); 597extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *);
592extern xfs_agnumber_t xfs_initialize_perag(struct vfs *, xfs_mount_t *, 598extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *,
593 xfs_agnumber_t); 599 xfs_agnumber_t);
594extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t); 600extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t);
595 601
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index 1408a32eef88..320d63ff9ca2 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
29#include "xfs_mount.h" 28#include "xfs_mount.h"
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 7fbef974bce6..acb853b33ebb 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -365,7 +365,7 @@ typedef struct xfs_dqtrxops {
365extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); 365extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
366extern int xfs_mount_reset_sbqflags(struct xfs_mount *); 366extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
367 367
368extern struct bhv_vfsops xfs_qmops; 368extern struct bhv_module_vfsops xfs_qmops;
369 369
370#endif /* __KERNEL__ */ 370#endif /* __KERNEL__ */
371 371
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 1f148762eb28..d98171deaa1c 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -22,13 +22,11 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
@@ -40,7 +38,6 @@
40#include "xfs_refcache.h" 38#include "xfs_refcache.h"
41#include "xfs_utils.h" 39#include "xfs_utils.h"
42#include "xfs_trans_space.h" 40#include "xfs_trans_space.h"
43#include "xfs_dir_leaf.h"
44 41
45 42
46/* 43/*
@@ -87,8 +84,8 @@ STATIC int
87xfs_lock_for_rename( 84xfs_lock_for_rename(
88 xfs_inode_t *dp1, /* old (source) directory inode */ 85 xfs_inode_t *dp1, /* old (source) directory inode */
89 xfs_inode_t *dp2, /* new (target) directory inode */ 86 xfs_inode_t *dp2, /* new (target) directory inode */
90 vname_t *vname1,/* old entry name */ 87 bhv_vname_t *vname1,/* old entry name */
91 vname_t *vname2,/* new entry name */ 88 bhv_vname_t *vname2,/* new entry name */
92 xfs_inode_t **ipp1, /* inode of old entry */ 89 xfs_inode_t **ipp1, /* inode of old entry */
93 xfs_inode_t **ipp2, /* inode of new entry, if it 90 xfs_inode_t **ipp2, /* inode of new entry, if it
94 already exists, NULL otherwise. */ 91 already exists, NULL otherwise. */
@@ -225,9 +222,9 @@ xfs_lock_for_rename(
225int 222int
226xfs_rename( 223xfs_rename(
227 bhv_desc_t *src_dir_bdp, 224 bhv_desc_t *src_dir_bdp,
228 vname_t *src_vname, 225 bhv_vname_t *src_vname,
229 vnode_t *target_dir_vp, 226 bhv_vnode_t *target_dir_vp,
230 vname_t *target_vname, 227 bhv_vname_t *target_vname,
231 cred_t *credp) 228 cred_t *credp)
232{ 229{
233 xfs_trans_t *tp; 230 xfs_trans_t *tp;
@@ -242,7 +239,7 @@ xfs_rename(
242 int committed; 239 int committed;
243 xfs_inode_t *inodes[4]; 240 xfs_inode_t *inodes[4];
244 int target_ip_dropped = 0; /* dropped target_ip link? */ 241 int target_ip_dropped = 0; /* dropped target_ip link? */
245 vnode_t *src_dir_vp; 242 bhv_vnode_t *src_dir_vp;
246 int spaceres; 243 int spaceres;
247 int target_link_zero = 0; 244 int target_link_zero = 0;
248 int num_inodes; 245 int num_inodes;
@@ -398,34 +395,29 @@ xfs_rename(
398 * fit before actually inserting it. 395 * fit before actually inserting it.
399 */ 396 */
400 if (spaceres == 0 && 397 if (spaceres == 0 &&
401 (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name, 398 (error = xfs_dir_canenter(tp, target_dp, target_name,
402 target_namelen))) { 399 target_namelen)))
403 goto error_return; 400 goto error_return;
404 }
405 /* 401 /*
406 * If target does not exist and the rename crosses 402 * If target does not exist and the rename crosses
407 * directories, adjust the target directory link count 403 * directories, adjust the target directory link count
408 * to account for the ".." reference from the new entry. 404 * to account for the ".." reference from the new entry.
409 */ 405 */
410 error = XFS_DIR_CREATENAME(mp, tp, target_dp, target_name, 406 error = xfs_dir_createname(tp, target_dp, target_name,
411 target_namelen, src_ip->i_ino, 407 target_namelen, src_ip->i_ino,
412 &first_block, &free_list, spaceres); 408 &first_block, &free_list, spaceres);
413 if (error == ENOSPC) { 409 if (error == ENOSPC)
414 goto error_return; 410 goto error_return;
415 } 411 if (error)
416 if (error) {
417 goto abort_return; 412 goto abort_return;
418 }
419 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 413 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
420 414
421 if (new_parent && src_is_directory) { 415 if (new_parent && src_is_directory) {
422 error = xfs_bumplink(tp, target_dp); 416 error = xfs_bumplink(tp, target_dp);
423 if (error) { 417 if (error)
424 goto abort_return; 418 goto abort_return;
425 }
426 } 419 }
427 } else { /* target_ip != NULL */ 420 } else { /* target_ip != NULL */
428
429 /* 421 /*
430 * If target exists and it's a directory, check that both 422 * If target exists and it's a directory, check that both
431 * target and source are directories and that target can be 423 * target and source are directories and that target can be
@@ -435,7 +427,7 @@ xfs_rename(
435 /* 427 /*
436 * Make sure target dir is empty. 428 * Make sure target dir is empty.
437 */ 429 */
438 if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) || 430 if (!(xfs_dir_isempty(target_ip)) ||
439 (target_ip->i_d.di_nlink > 2)) { 431 (target_ip->i_d.di_nlink > 2)) {
440 error = XFS_ERROR(EEXIST); 432 error = XFS_ERROR(EEXIST);
441 goto error_return; 433 goto error_return;
@@ -451,12 +443,11 @@ xfs_rename(
451 * In case there is already an entry with the same 443 * In case there is already an entry with the same
452 * name at the destination directory, remove it first. 444 * name at the destination directory, remove it first.
453 */ 445 */
454 error = XFS_DIR_REPLACE(mp, tp, target_dp, target_name, 446 error = xfs_dir_replace(tp, target_dp, target_name,
455 target_namelen, src_ip->i_ino, &first_block, 447 target_namelen, src_ip->i_ino,
456 &free_list, spaceres); 448 &first_block, &free_list, spaceres);
457 if (error) { 449 if (error)
458 goto abort_return; 450 goto abort_return;
459 }
460 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 451 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
461 452
462 /* 453 /*
@@ -464,9 +455,8 @@ xfs_rename(
464 * dir no longer points to it. 455 * dir no longer points to it.
465 */ 456 */
466 error = xfs_droplink(tp, target_ip); 457 error = xfs_droplink(tp, target_ip);
467 if (error) { 458 if (error)
468 goto abort_return; 459 goto abort_return;
469 }
470 target_ip_dropped = 1; 460 target_ip_dropped = 1;
471 461
472 if (src_is_directory) { 462 if (src_is_directory) {
@@ -474,9 +464,8 @@ xfs_rename(
474 * Drop the link from the old "." entry. 464 * Drop the link from the old "." entry.
475 */ 465 */
476 error = xfs_droplink(tp, target_ip); 466 error = xfs_droplink(tp, target_ip);
477 if (error) { 467 if (error)
478 goto abort_return; 468 goto abort_return;
479 }
480 } 469 }
481 470
482 /* Do this test while we still hold the locks */ 471 /* Do this test while we still hold the locks */
@@ -488,18 +477,15 @@ xfs_rename(
488 * Remove the source. 477 * Remove the source.
489 */ 478 */
490 if (new_parent && src_is_directory) { 479 if (new_parent && src_is_directory) {
491
492 /* 480 /*
493 * Rewrite the ".." entry to point to the new 481 * Rewrite the ".." entry to point to the new
494 * directory. 482 * directory.
495 */ 483 */
496 error = XFS_DIR_REPLACE(mp, tp, src_ip, "..", 2, 484 error = xfs_dir_replace(tp, src_ip, "..", 2, target_dp->i_ino,
497 target_dp->i_ino, &first_block, 485 &first_block, &free_list, spaceres);
498 &free_list, spaceres);
499 ASSERT(error != EEXIST); 486 ASSERT(error != EEXIST);
500 if (error) { 487 if (error)
501 goto abort_return; 488 goto abort_return;
502 }
503 xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 489 xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
504 490
505 } else { 491 } else {
@@ -527,16 +513,14 @@ xfs_rename(
527 * entry that's moved no longer points to it. 513 * entry that's moved no longer points to it.
528 */ 514 */
529 error = xfs_droplink(tp, src_dp); 515 error = xfs_droplink(tp, src_dp);
530 if (error) { 516 if (error)
531 goto abort_return; 517 goto abort_return;
532 }
533 } 518 }
534 519
535 error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen, 520 error = xfs_dir_removename(tp, src_dp, src_name, src_namelen,
536 src_ip->i_ino, &first_block, &free_list, spaceres); 521 src_ip->i_ino, &first_block, &free_list, spaceres);
537 if (error) { 522 if (error)
538 goto abort_return; 523 goto abort_return;
539 }
540 xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 524 xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
541 525
542 /* 526 /*
@@ -609,7 +593,7 @@ xfs_rename(
609 * Let interposed file systems know about removed links. 593 * Let interposed file systems know about removed links.
610 */ 594 */
611 if (target_ip_dropped) { 595 if (target_ip_dropped) {
612 VOP_LINK_REMOVED(XFS_ITOV(target_ip), target_dir_vp, 596 bhv_vop_link_removed(XFS_ITOV(target_ip), target_dir_vp,
613 target_link_zero); 597 target_link_zero);
614 IRELE(target_ip); 598 IRELE(target_ip);
615 } 599 }
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 5b413946b1c5..0c1e42b037ef 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -141,7 +139,7 @@ xfs_growfs_rt_alloc(
141 cancelflags |= XFS_TRANS_ABORT; 139 cancelflags |= XFS_TRANS_ABORT;
142 error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks, 140 error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks,
143 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock, 141 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock,
144 resblks, &map, &nmap, &flist); 142 resblks, &map, &nmap, &flist, NULL);
145 if (!error && nmap < 1) 143 if (!error && nmap < 1)
146 error = XFS_ERROR(ENOSPC); 144 error = XFS_ERROR(ENOSPC);
147 if (error) 145 if (error)
@@ -2404,10 +2402,10 @@ xfs_rtprint_range(
2404{ 2402{
2405 xfs_extlen_t i; /* block number in the extent */ 2403 xfs_extlen_t i; /* block number in the extent */
2406 2404
2407 printk("%Ld: ", (long long)start); 2405 cmn_err(CE_DEBUG, "%Ld: ", (long long)start);
2408 for (i = 0; i < len; i++) 2406 for (i = 0; i < len; i++)
2409 printk("%d", xfs_rtcheck_bit(mp, tp, start + i, 1)); 2407 cmn_err(CE_DEBUG, "%d", xfs_rtcheck_bit(mp, tp, start + i, 1));
2410 printk("\n"); 2408 cmn_err(CE_DEBUG, "\n");
2411} 2409}
2412 2410
2413/* 2411/*
@@ -2431,17 +2429,17 @@ xfs_rtprint_summary(
2431 (void)xfs_rtget_summary(mp, tp, l, i, &sumbp, &sb, &c); 2429 (void)xfs_rtget_summary(mp, tp, l, i, &sumbp, &sb, &c);
2432 if (c) { 2430 if (c) {
2433 if (!p) { 2431 if (!p) {
2434 printk("%Ld-%Ld:", 1LL << l, 2432 cmn_err(CE_DEBUG, "%Ld-%Ld:", 1LL << l,
2435 XFS_RTMIN((1LL << l) + 2433 XFS_RTMIN((1LL << l) +
2436 ((1LL << l) - 1LL), 2434 ((1LL << l) - 1LL),
2437 mp->m_sb.sb_rextents)); 2435 mp->m_sb.sb_rextents));
2438 p = 1; 2436 p = 1;
2439 } 2437 }
2440 printk(" %Ld:%d", (long long)i, c); 2438 cmn_err(CE_DEBUG, " %Ld:%d", (long long)i, c);
2441 } 2439 }
2442 } 2440 }
2443 if (p) 2441 if (p)
2444 printk("\n"); 2442 cmn_err(CE_DEBUG, "\n");
2445 } 2443 }
2446 if (sumbp) 2444 if (sumbp)
2447 xfs_trans_brelse(tp, sumbp); 2445 xfs_trans_brelse(tp, sumbp);
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index a59c102cf214..defb2febaaf5 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -92,6 +90,90 @@ xfs_write_clear_setuid(
92} 90}
93 91
94/* 92/*
93 * Handle logging requirements of various synchronous types of write.
94 */
95int
96xfs_write_sync_logforce(
97 xfs_mount_t *mp,
98 xfs_inode_t *ip)
99{
100 int error = 0;
101
102 /*
103 * If we're treating this as O_DSYNC and we have not updated the
104 * size, force the log.
105 */
106 if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
107 !(ip->i_update_size)) {
108 xfs_inode_log_item_t *iip = ip->i_itemp;
109
110 /*
111 * If an allocation transaction occurred
112 * without extending the size, then we have to force
113 * the log up the proper point to ensure that the
114 * allocation is permanent. We can't count on
115 * the fact that buffered writes lock out direct I/O
116 * writes - the direct I/O write could have extended
117 * the size nontransactionally, then finished before
118 * we started. xfs_write_file will think that the file
119 * didn't grow but the update isn't safe unless the
120 * size change is logged.
121 *
122 * Force the log if we've committed a transaction
123 * against the inode or if someone else has and
124 * the commit record hasn't gone to disk (e.g.
125 * the inode is pinned). This guarantees that
126 * all changes affecting the inode are permanent
127 * when we return.
128 */
129 if (iip && iip->ili_last_lsn) {
130 xfs_log_force(mp, iip->ili_last_lsn,
131 XFS_LOG_FORCE | XFS_LOG_SYNC);
132 } else if (xfs_ipincount(ip) > 0) {
133 xfs_log_force(mp, (xfs_lsn_t)0,
134 XFS_LOG_FORCE | XFS_LOG_SYNC);
135 }
136
137 } else {
138 xfs_trans_t *tp;
139
140 /*
141 * O_SYNC or O_DSYNC _with_ a size update are handled
142 * the same way.
143 *
144 * If the write was synchronous then we need to make
145 * sure that the inode modification time is permanent.
146 * We'll have updated the timestamp above, so here
147 * we use a synchronous transaction to log the inode.
148 * It's not fast, but it's necessary.
149 *
150 * If this a dsync write and the size got changed
151 * non-transactionally, then we need to ensure that
152 * the size change gets logged in a synchronous
153 * transaction.
154 */
155 tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
156 if ((error = xfs_trans_reserve(tp, 0,
157 XFS_SWRITE_LOG_RES(mp),
158 0, 0, 0))) {
159 /* Transaction reserve failed */
160 xfs_trans_cancel(tp, 0);
161 } else {
162 /* Transaction reserve successful */
163 xfs_ilock(ip, XFS_ILOCK_EXCL);
164 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
165 xfs_trans_ihold(tp, ip);
166 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
167 xfs_trans_set_sync(tp);
168 error = xfs_trans_commit(tp, 0, NULL);
169 xfs_iunlock(ip, XFS_ILOCK_EXCL);
170 }
171 }
172
173 return error;
174}
175
176/*
95 * Force a shutdown of the filesystem instantly while keeping 177 * Force a shutdown of the filesystem instantly while keeping
96 * the filesystem consistent. We don't do an unmount here; just shutdown 178 * the filesystem consistent. We don't do an unmount here; just shutdown
97 * the shop, make sure that absolutely nothing persistent happens to 179 * the shop, make sure that absolutely nothing persistent happens to
@@ -109,12 +191,12 @@ xfs_do_force_shutdown(
109 xfs_mount_t *mp; 191 xfs_mount_t *mp;
110 192
111 mp = XFS_BHVTOM(bdp); 193 mp = XFS_BHVTOM(bdp);
112 logerror = flags & XFS_LOG_IO_ERROR; 194 logerror = flags & SHUTDOWN_LOG_IO_ERROR;
113 195
114 if (!(flags & XFS_FORCE_UMOUNT)) { 196 if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
115 cmn_err(CE_NOTE, 197 cmn_err(CE_NOTE, "xfs_force_shutdown(%s,0x%x) called from "
116 "xfs_force_shutdown(%s,0x%x) called from line %d of file %s. Return address = 0x%p", 198 "line %d of file %s. Return address = 0x%p",
117 mp->m_fsname,flags,lnnum,fname,__return_address); 199 mp->m_fsname, flags, lnnum, fname, __return_address);
118 } 200 }
119 /* 201 /*
120 * No need to duplicate efforts. 202 * No need to duplicate efforts.
@@ -125,33 +207,37 @@ xfs_do_force_shutdown(
125 /* 207 /*
126 * This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't 208 * This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't
127 * queue up anybody new on the log reservations, and wakes up 209 * queue up anybody new on the log reservations, and wakes up
128 * everybody who's sleeping on log reservations and tells 210 * everybody who's sleeping on log reservations to tell them
129 * them the bad news. 211 * the bad news.
130 */ 212 */
131 if (xfs_log_force_umount(mp, logerror)) 213 if (xfs_log_force_umount(mp, logerror))
132 return; 214 return;
133 215
134 if (flags & XFS_CORRUPT_INCORE) { 216 if (flags & SHUTDOWN_CORRUPT_INCORE) {
135 xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp, 217 xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp,
136 "Corruption of in-memory data detected. Shutting down filesystem: %s", 218 "Corruption of in-memory data detected. Shutting down filesystem: %s",
137 mp->m_fsname); 219 mp->m_fsname);
138 if (XFS_ERRLEVEL_HIGH <= xfs_error_level) { 220 if (XFS_ERRLEVEL_HIGH <= xfs_error_level) {
139 xfs_stack_trace(); 221 xfs_stack_trace();
140 } 222 }
141 } else if (!(flags & XFS_FORCE_UMOUNT)) { 223 } else if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
142 if (logerror) { 224 if (logerror) {
143 xfs_cmn_err(XFS_PTAG_SHUTDOWN_LOGERROR, CE_ALERT, mp, 225 xfs_cmn_err(XFS_PTAG_SHUTDOWN_LOGERROR, CE_ALERT, mp,
144 "Log I/O Error Detected. Shutting down filesystem: %s", 226 "Log I/O Error Detected. Shutting down filesystem: %s",
227 mp->m_fsname);
228 } else if (flags & SHUTDOWN_DEVICE_REQ) {
229 xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp,
230 "All device paths lost. Shutting down filesystem: %s",
145 mp->m_fsname); 231 mp->m_fsname);
146 } else if (!(flags & XFS_SHUTDOWN_REMOTE_REQ)) { 232 } else if (!(flags & SHUTDOWN_REMOTE_REQ)) {
147 xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp, 233 xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp,
148 "I/O Error Detected. Shutting down filesystem: %s", 234 "I/O Error Detected. Shutting down filesystem: %s",
149 mp->m_fsname); 235 mp->m_fsname);
150 } 236 }
151 } 237 }
152 if (!(flags & XFS_FORCE_UMOUNT)) { 238 if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
153 cmn_err(CE_ALERT, 239 cmn_err(CE_ALERT, "Please umount the filesystem, "
154 "Please umount the filesystem, and rectify the problem(s)"); 240 "and rectify the problem(s)");
155 } 241 }
156} 242}
157 243
@@ -335,7 +421,7 @@ xfs_bwrite(
335 * from bwrite and we could be tracing a buffer that has 421 * from bwrite and we could be tracing a buffer that has
336 * been reused. 422 * been reused.
337 */ 423 */
338 xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); 424 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
339 } 425 }
340 return (error); 426 return (error);
341} 427}
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h
index e63795644478..188b296ff50c 100644
--- a/fs/xfs/xfs_rw.h
+++ b/fs/xfs/xfs_rw.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -75,6 +75,7 @@ xfs_fsb_to_db_io(struct xfs_iocore *io, xfs_fsblock_t fsb)
75 * Prototypes for functions in xfs_rw.c. 75 * Prototypes for functions in xfs_rw.c.
76 */ 76 */
77extern int xfs_write_clear_setuid(struct xfs_inode *ip); 77extern int xfs_write_clear_setuid(struct xfs_inode *ip);
78extern int xfs_write_sync_logforce(struct xfs_mount *mp, struct xfs_inode *ip);
78extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp); 79extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp);
79extern int xfs_bioerror(struct xfs_buf *bp); 80extern int xfs_bioerror(struct xfs_buf *bp);
80extern int xfs_bioerror_relse(struct xfs_buf *bp); 81extern int xfs_bioerror_relse(struct xfs_buf *bp);
@@ -87,9 +88,10 @@ extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,
87/* 88/*
88 * Prototypes for functions in xfs_vnodeops.c. 89 * Prototypes for functions in xfs_vnodeops.c.
89 */ 90 */
90extern int xfs_rwlock(bhv_desc_t *bdp, vrwlock_t write_lock); 91extern int xfs_rwlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
91extern void xfs_rwunlock(bhv_desc_t *bdp, vrwlock_t write_lock); 92extern void xfs_rwunlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
92extern int xfs_setattr(bhv_desc_t *bdp, vattr_t *vap, int flags, cred_t *credp); 93extern int xfs_setattr(bhv_desc_t *, bhv_vattr_t *vap, int flags,
94 cred_t *credp);
93extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf, 95extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf,
94 xfs_off_t offset, cred_t *credp, int flags); 96 xfs_off_t offset, cred_t *credp, int flags);
95extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state, 97extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state,
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 8d056cef5d1f..ee2721e0de4d 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -33,7 +32,6 @@
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -236,11 +234,8 @@ xfs_trans_alloc(
236 xfs_mount_t *mp, 234 xfs_mount_t *mp,
237 uint type) 235 uint type)
238{ 236{
239 fs_check_frozen(XFS_MTOVFS(mp), SB_FREEZE_TRANS); 237 vfs_wait_for_freeze(XFS_MTOVFS(mp), SB_FREEZE_TRANS);
240 atomic_inc(&mp->m_active_trans); 238 return _xfs_trans_alloc(mp, type);
241
242 return (_xfs_trans_alloc(mp, type));
243
244} 239}
245 240
246xfs_trans_t * 241xfs_trans_t *
@@ -250,12 +245,9 @@ _xfs_trans_alloc(
250{ 245{
251 xfs_trans_t *tp; 246 xfs_trans_t *tp;
252 247
253 ASSERT(xfs_trans_zone != NULL); 248 atomic_inc(&mp->m_active_trans);
254 tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
255 249
256 /* 250 tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
257 * Initialize the transaction structure.
258 */
259 tp->t_magic = XFS_TRANS_MAGIC; 251 tp->t_magic = XFS_TRANS_MAGIC;
260 tp->t_type = type; 252 tp->t_type = type;
261 tp->t_mountp = mp; 253 tp->t_mountp = mp;
@@ -263,8 +255,7 @@ _xfs_trans_alloc(
263 tp->t_busy_free = XFS_LBC_NUM_SLOTS; 255 tp->t_busy_free = XFS_LBC_NUM_SLOTS;
264 XFS_LIC_INIT(&(tp->t_items)); 256 XFS_LIC_INIT(&(tp->t_items));
265 XFS_LBC_INIT(&(tp->t_busy)); 257 XFS_LBC_INIT(&(tp->t_busy));
266 258 return tp;
267 return (tp);
268} 259}
269 260
270/* 261/*
@@ -303,7 +294,7 @@ xfs_trans_dup(
303 tp->t_blk_res = tp->t_blk_res_used; 294 tp->t_blk_res = tp->t_blk_res_used;
304 ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used; 295 ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used;
305 tp->t_rtx_res = tp->t_rtx_res_used; 296 tp->t_rtx_res = tp->t_rtx_res_used;
306 PFLAGS_DUP(&tp->t_pflags, &ntp->t_pflags); 297 ntp->t_pflags = tp->t_pflags;
307 298
308 XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp); 299 XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp);
309 300
@@ -335,14 +326,11 @@ xfs_trans_reserve(
335 uint logcount) 326 uint logcount)
336{ 327{
337 int log_flags; 328 int log_flags;
338 int error; 329 int error = 0;
339 int rsvd; 330 int rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
340
341 error = 0;
342 rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
343 331
344 /* Mark this thread as being in a transaction */ 332 /* Mark this thread as being in a transaction */
345 PFLAGS_SET_FSTRANS(&tp->t_pflags); 333 current_set_flags_nested(&tp->t_pflags, PF_FSTRANS);
346 334
347 /* 335 /*
348 * Attempt to reserve the needed disk blocks by decrementing 336 * Attempt to reserve the needed disk blocks by decrementing
@@ -353,7 +341,7 @@ xfs_trans_reserve(
353 error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS, 341 error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS,
354 -blocks, rsvd); 342 -blocks, rsvd);
355 if (error != 0) { 343 if (error != 0) {
356 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 344 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
357 return (XFS_ERROR(ENOSPC)); 345 return (XFS_ERROR(ENOSPC));
358 } 346 }
359 tp->t_blk_res += blocks; 347 tp->t_blk_res += blocks;
@@ -426,9 +414,9 @@ undo_blocks:
426 tp->t_blk_res = 0; 414 tp->t_blk_res = 0;
427 } 415 }
428 416
429 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 417 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
430 418
431 return (error); 419 return error;
432} 420}
433 421
434 422
@@ -819,7 +807,7 @@ shut_us_down:
819 if (commit_lsn == -1 && !shutdown) 807 if (commit_lsn == -1 && !shutdown)
820 shutdown = XFS_ERROR(EIO); 808 shutdown = XFS_ERROR(EIO);
821 } 809 }
822 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 810 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
823 xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0); 811 xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0);
824 xfs_trans_free_busy(tp); 812 xfs_trans_free_busy(tp);
825 xfs_trans_free(tp); 813 xfs_trans_free(tp);
@@ -846,7 +834,7 @@ shut_us_down:
846 */ 834 */
847 nvec = xfs_trans_count_vecs(tp); 835 nvec = xfs_trans_count_vecs(tp);
848 if (nvec == 0) { 836 if (nvec == 0) {
849 xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); 837 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
850 goto shut_us_down; 838 goto shut_us_down;
851 } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) { 839 } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) {
852 log_vector = log_vector_fast; 840 log_vector = log_vector_fast;
@@ -884,7 +872,7 @@ shut_us_down:
884 * had pinned, clean up, free trans structure, and return error. 872 * had pinned, clean up, free trans structure, and return error.
885 */ 873 */
886 if (error || commit_lsn == -1) { 874 if (error || commit_lsn == -1) {
887 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 875 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
888 xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT); 876 xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT);
889 return XFS_ERROR(EIO); 877 return XFS_ERROR(EIO);
890 } 878 }
@@ -926,7 +914,7 @@ shut_us_down:
926 /* 914 /*
927 * Mark this thread as no longer being in a transaction 915 * Mark this thread as no longer being in a transaction
928 */ 916 */
929 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 917 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
930 918
931 /* 919 /*
932 * Once all the items of the transaction have been copied 920 * Once all the items of the transaction have been copied
@@ -1148,7 +1136,7 @@ xfs_trans_cancel(
1148 */ 1136 */
1149 if ((tp->t_flags & XFS_TRANS_DIRTY) && !XFS_FORCED_SHUTDOWN(mp)) { 1137 if ((tp->t_flags & XFS_TRANS_DIRTY) && !XFS_FORCED_SHUTDOWN(mp)) {
1150 XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp); 1138 XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp);
1151 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 1139 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
1152 } 1140 }
1153#ifdef DEBUG 1141#ifdef DEBUG
1154 if (!(flags & XFS_TRANS_ABORT)) { 1142 if (!(flags & XFS_TRANS_ABORT)) {
@@ -1182,7 +1170,7 @@ xfs_trans_cancel(
1182 } 1170 }
1183 1171
1184 /* mark this thread as no longer being in a transaction */ 1172 /* mark this thread as no longer being in a transaction */
1185 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 1173 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
1186 1174
1187 xfs_trans_free_items(tp, flags); 1175 xfs_trans_free_items(tp, flags);
1188 xfs_trans_free_busy(tp); 1176 xfs_trans_free_busy(tp);
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 100d9a4b38ee..cb65c3a603f5 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -805,12 +805,9 @@ typedef struct xfs_trans {
805 ((mp)->m_sb.sb_inodesize + \ 805 ((mp)->m_sb.sb_inodesize + \
806 (mp)->m_sb.sb_sectsize * 2 + \ 806 (mp)->m_sb.sb_sectsize * 2 + \
807 (mp)->m_dirblksize + \ 807 (mp)->m_dirblksize + \
808 (XFS_DIR_IS_V1(mp) ? 0 : \ 808 XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \
809 XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1))) + \
810 XFS_ALLOCFREE_LOG_RES(mp, 1) + \ 809 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
811 (128 * (4 + \ 810 (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \
812 (XFS_DIR_IS_V1(mp) ? 0 : \
813 XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \
814 XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) 811 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
815 812
816#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) 813#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork)
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 19ab24af1c1c..558c87ff0c41 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -22,7 +22,6 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dmapi.h" 25#include "xfs_dmapi.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_trans_priv.h" 27#include "xfs_trans_priv.h"
@@ -363,9 +362,10 @@ xfs_trans_delete_ail(
363 AIL_UNLOCK(mp, s); 362 AIL_UNLOCK(mp, s);
364 else { 363 else {
365 xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp, 364 xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp,
366 "xfs_trans_delete_ail: attempting to delete a log item that is not in the AIL"); 365 "%s: attempting to delete a log item that is not in the AIL",
366 __FUNCTION__);
367 AIL_UNLOCK(mp, s); 367 AIL_UNLOCK(mp, s);
368 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 368 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
369 } 369 }
370 } 370 }
371} 371}
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index c74c31ebc81c..60b6b898022b 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -320,7 +318,7 @@ xfs_trans_read_buf(
320 if (xfs_error_target == target) { 318 if (xfs_error_target == target) {
321 if (((xfs_req_num++) % xfs_error_mod) == 0) { 319 if (((xfs_req_num++) % xfs_error_mod) == 0) {
322 xfs_buf_relse(bp); 320 xfs_buf_relse(bp);
323 printk("Returning error!\n"); 321 cmn_err(CE_DEBUG, "Returning error!\n");
324 return XFS_ERROR(EIO); 322 return XFS_ERROR(EIO);
325 } 323 }
326 } 324 }
@@ -369,7 +367,7 @@ xfs_trans_read_buf(
369 */ 367 */
370 if (tp->t_flags & XFS_TRANS_DIRTY) 368 if (tp->t_flags & XFS_TRANS_DIRTY)
371 xfs_force_shutdown(tp->t_mountp, 369 xfs_force_shutdown(tp->t_mountp,
372 XFS_METADATA_IO_ERROR); 370 SHUTDOWN_META_IO_ERROR);
373 return error; 371 return error;
374 } 372 }
375 } 373 }
@@ -414,7 +412,7 @@ xfs_trans_read_buf(
414 xfs_ioerror_alert("xfs_trans_read_buf", mp, 412 xfs_ioerror_alert("xfs_trans_read_buf", mp,
415 bp, blkno); 413 bp, blkno);
416 if (tp->t_flags & XFS_TRANS_DIRTY) 414 if (tp->t_flags & XFS_TRANS_DIRTY)
417 xfs_force_shutdown(tp->t_mountp, XFS_METADATA_IO_ERROR); 415 xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR);
418 xfs_buf_relse(bp); 416 xfs_buf_relse(bp);
419 return error; 417 return error;
420 } 418 }
@@ -423,9 +421,9 @@ xfs_trans_read_buf(
423 if (xfs_error_target == target) { 421 if (xfs_error_target == target) {
424 if (((xfs_req_num++) % xfs_error_mod) == 0) { 422 if (((xfs_req_num++) % xfs_error_mod) == 0) {
425 xfs_force_shutdown(tp->t_mountp, 423 xfs_force_shutdown(tp->t_mountp,
426 XFS_METADATA_IO_ERROR); 424 SHUTDOWN_META_IO_ERROR);
427 xfs_buf_relse(bp); 425 xfs_buf_relse(bp);
428 printk("Returning error in trans!\n"); 426 cmn_err(CE_DEBUG, "Returning trans error!\n");
429 return XFS_ERROR(EIO); 427 return XFS_ERROR(EIO);
430 } 428 }
431 } 429 }
diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c
index 7d7d627f25df..b290270dd4a6 100644
--- a/fs/xfs/xfs_trans_extfree.c
+++ b/fs/xfs/xfs_trans_extfree.c
@@ -22,7 +22,6 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dmapi.h" 25#include "xfs_dmapi.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_trans_priv.h" 27#include "xfs_trans_priv.h"
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
index 7c5894d59f81..b8db1d5cde5a 100644
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_trans_item.c b/fs/xfs/xfs_trans_item.c
index 1117d600d741..2912aac07c7b 100644
--- a/fs/xfs/xfs_trans_item.c
+++ b/fs/xfs/xfs_trans_item.c
@@ -493,7 +493,7 @@ xfs_trans_add_busy(xfs_trans_t *tp, xfs_agnumber_t ag, xfs_extlen_t idx)
493 break; 493 break;
494 } else { 494 } else {
495 /* out-of-order vacancy */ 495 /* out-of-order vacancy */
496 printk("OOO vacancy lbcp 0x%p\n", lbcp); 496 cmn_err(CE_DEBUG, "OOO vacancy lbcp 0x%p\n", lbcp);
497 ASSERT(0); 497 ASSERT(0);
498 } 498 }
499 } 499 }
diff --git a/fs/xfs/xfs_trans_space.h b/fs/xfs/xfs_trans_space.h
index 7fe3792b18df..4ea2e5074bdd 100644
--- a/fs/xfs/xfs_trans_space.h
+++ b/fs/xfs/xfs_trans_space.h
@@ -30,8 +30,7 @@
30 XFS_EXTENTADD_SPACE_RES(mp,w)) 30 XFS_EXTENTADD_SPACE_RES(mp,w))
31#define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1) 31#define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1)
32#define XFS_DAENTER_DBS(mp,w) \ 32#define XFS_DAENTER_DBS(mp,w) \
33 (XFS_DA_NODE_MAXDEPTH + \ 33 (XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0))
34 ((XFS_DIR_IS_V2(mp) && (w) == XFS_DATA_FORK) ? 2 : 0))
35#define XFS_DAENTER_BLOCKS(mp,w) \ 34#define XFS_DAENTER_BLOCKS(mp,w) \
36 (XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w)) 35 (XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w))
37#define XFS_DAENTER_BMAP1B(mp,w) \ 36#define XFS_DAENTER_BMAP1B(mp,w) \
@@ -41,10 +40,7 @@
41#define XFS_DAENTER_SPACE_RES(mp,w) \ 40#define XFS_DAENTER_SPACE_RES(mp,w) \
42 (XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w)) 41 (XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w))
43#define XFS_DAREMOVE_SPACE_RES(mp,w) XFS_DAENTER_BMAPS(mp,w) 42#define XFS_DAREMOVE_SPACE_RES(mp,w) XFS_DAENTER_BMAPS(mp,w)
44#define XFS_DIRENTER_MAX_SPLIT(mp,nl) \ 43#define XFS_DIRENTER_MAX_SPLIT(mp,nl) 1
45 (((mp)->m_sb.sb_blocksize == 512 && \
46 XFS_DIR_IS_V1(mp) && \
47 (nl) >= XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN) ? 2 : 1)
48#define XFS_DIRENTER_SPACE_RES(mp,nl) \ 44#define XFS_DIRENTER_SPACE_RES(mp,nl) \
49 (XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \ 45 (XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \
50 XFS_DIRENTER_MAX_SPLIT(mp,nl)) 46 XFS_DIRENTER_MAX_SPLIT(mp,nl))
@@ -57,8 +53,7 @@
57 * Space reservation values for various transactions. 53 * Space reservation values for various transactions.
58 */ 54 */
59#define XFS_ADDAFORK_SPACE_RES(mp) \ 55#define XFS_ADDAFORK_SPACE_RES(mp) \
60 ((mp)->m_dirblkfsbs + \ 56 ((mp)->m_dirblkfsbs + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))
61 (XFS_DIR_IS_V1(mp) ? 0 : XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK)))
62#define XFS_ATTRRM_SPACE_RES(mp) \ 57#define XFS_ATTRRM_SPACE_RES(mp) \
63 XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK) 58 XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK)
64/* This macro is not used - see inline code in xfs_attr_set */ 59/* This macro is not used - see inline code in xfs_attr_set */
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 34654ec6ae10..9014d7e44488 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -24,12 +24,10 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_dir_sf.h"
33#include "xfs_dir2_sf.h" 31#include "xfs_dir2_sf.h"
34#include "xfs_attr_sf.h" 32#include "xfs_attr_sf.h"
35#include "xfs_dinode.h" 33#include "xfs_dinode.h"
@@ -51,10 +49,10 @@
51 */ 49 */
52int 50int
53xfs_get_dir_entry( 51xfs_get_dir_entry(
54 vname_t *dentry, 52 bhv_vname_t *dentry,
55 xfs_inode_t **ipp) 53 xfs_inode_t **ipp)
56{ 54{
57 vnode_t *vp; 55 bhv_vnode_t *vp;
58 56
59 vp = VNAME_TO_VNODE(dentry); 57 vp = VNAME_TO_VNODE(dentry);
60 58
@@ -69,11 +67,11 @@ int
69xfs_dir_lookup_int( 67xfs_dir_lookup_int(
70 bhv_desc_t *dir_bdp, 68 bhv_desc_t *dir_bdp,
71 uint lock_mode, 69 uint lock_mode,
72 vname_t *dentry, 70 bhv_vname_t *dentry,
73 xfs_ino_t *inum, 71 xfs_ino_t *inum,
74 xfs_inode_t **ipp) 72 xfs_inode_t **ipp)
75{ 73{
76 vnode_t *dir_vp; 74 bhv_vnode_t *dir_vp;
77 xfs_inode_t *dp; 75 xfs_inode_t *dp;
78 int error; 76 int error;
79 77
@@ -82,8 +80,7 @@ xfs_dir_lookup_int(
82 80
83 dp = XFS_BHVTOI(dir_bdp); 81 dp = XFS_BHVTOI(dir_bdp);
84 82
85 error = XFS_DIR_LOOKUP(dp->i_mount, NULL, dp, 83 error = xfs_dir_lookup(NULL, dp, VNAME(dentry), VNAMELEN(dentry), inum);
86 VNAME(dentry), VNAMELEN(dentry), inum);
87 if (!error) { 84 if (!error) {
88 /* 85 /*
89 * Unlock the directory. We do this because we can't 86 * Unlock the directory. We do this because we can't
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
index 472661a3b6d8..fe953e98afa7 100644
--- a/fs/xfs/xfs_utils.h
+++ b/fs/xfs/xfs_utils.h
@@ -23,9 +23,10 @@
23#define ITRACE(ip) vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \ 23#define ITRACE(ip) vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \
24 (inst_t *)__return_address) 24 (inst_t *)__return_address)
25 25
26extern int xfs_rename (bhv_desc_t *, vname_t *, vnode_t *, vname_t *, cred_t *); 26extern int xfs_rename (bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
27extern int xfs_get_dir_entry (vname_t *, xfs_inode_t **); 27 bhv_vname_t *, cred_t *);
28extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *, 28extern int xfs_get_dir_entry (bhv_vname_t *, xfs_inode_t **);
29extern int xfs_dir_lookup_int (bhv_desc_t *, uint, bhv_vname_t *, xfs_ino_t *,
29 xfs_inode_t **); 30 xfs_inode_t **);
30extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); 31extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *);
31extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, 32extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t,
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 36ea1b2094f2..6c96391f3f1a 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -131,9 +129,6 @@ xfs_init(void)
131#ifdef XFS_BMBT_TRACE 129#ifdef XFS_BMBT_TRACE
132 xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_SLEEP); 130 xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_SLEEP);
133#endif 131#endif
134#ifdef XFS_DIR_TRACE
135 xfs_dir_trace_buf = ktrace_alloc(XFS_DIR_TRACE_SIZE, KM_SLEEP);
136#endif
137#ifdef XFS_ATTR_TRACE 132#ifdef XFS_ATTR_TRACE
138 xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_SLEEP); 133 xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_SLEEP);
139#endif 134#endif
@@ -177,9 +172,6 @@ xfs_cleanup(void)
177#ifdef XFS_ATTR_TRACE 172#ifdef XFS_ATTR_TRACE
178 ktrace_free(xfs_attr_trace_buf); 173 ktrace_free(xfs_attr_trace_buf);
179#endif 174#endif
180#ifdef XFS_DIR_TRACE
181 ktrace_free(xfs_dir_trace_buf);
182#endif
183#ifdef XFS_BMBT_TRACE 175#ifdef XFS_BMBT_TRACE
184 ktrace_free(xfs_bmbt_trace_buf); 176 ktrace_free(xfs_bmbt_trace_buf);
185#endif 177#endif
@@ -212,7 +204,7 @@ xfs_cleanup(void)
212 */ 204 */
213STATIC int 205STATIC int
214xfs_start_flags( 206xfs_start_flags(
215 struct vfs *vfs, 207 struct bhv_vfs *vfs,
216 struct xfs_mount_args *ap, 208 struct xfs_mount_args *ap,
217 struct xfs_mount *mp) 209 struct xfs_mount *mp)
218{ 210{
@@ -337,7 +329,7 @@ xfs_start_flags(
337 */ 329 */
338STATIC int 330STATIC int
339xfs_finish_flags( 331xfs_finish_flags(
340 struct vfs *vfs, 332 struct bhv_vfs *vfs,
341 struct xfs_mount_args *ap, 333 struct xfs_mount_args *ap,
342 struct xfs_mount *mp) 334 struct xfs_mount *mp)
343{ 335{
@@ -423,7 +415,7 @@ xfs_mount(
423 struct xfs_mount_args *args, 415 struct xfs_mount_args *args,
424 cred_t *credp) 416 cred_t *credp)
425{ 417{
426 struct vfs *vfsp = bhvtovfs(bhvp); 418 struct bhv_vfs *vfsp = bhvtovfs(bhvp);
427 struct bhv_desc *p; 419 struct bhv_desc *p;
428 struct xfs_mount *mp = XFS_BHVTOM(bhvp); 420 struct xfs_mount *mp = XFS_BHVTOM(bhvp);
429 struct block_device *ddev, *logdev, *rtdev; 421 struct block_device *ddev, *logdev, *rtdev;
@@ -552,10 +544,10 @@ xfs_unmount(
552 int flags, 544 int flags,
553 cred_t *credp) 545 cred_t *credp)
554{ 546{
555 struct vfs *vfsp = bhvtovfs(bdp); 547 bhv_vfs_t *vfsp = bhvtovfs(bdp);
556 xfs_mount_t *mp = XFS_BHVTOM(bdp); 548 xfs_mount_t *mp = XFS_BHVTOM(bdp);
557 xfs_inode_t *rip; 549 xfs_inode_t *rip;
558 vnode_t *rvp; 550 bhv_vnode_t *rvp;
559 int unmount_event_wanted = 0; 551 int unmount_event_wanted = 0;
560 int unmount_event_flags = 0; 552 int unmount_event_flags = 0;
561 int xfs_unmountfs_needed = 0; 553 int xfs_unmountfs_needed = 0;
@@ -665,9 +657,8 @@ xfs_mntupdate(
665 int *flags, 657 int *flags,
666 struct xfs_mount_args *args) 658 struct xfs_mount_args *args)
667{ 659{
668 struct vfs *vfsp = bhvtovfs(bdp); 660 bhv_vfs_t *vfsp = bhvtovfs(bdp);
669 xfs_mount_t *mp = XFS_BHVTOM(bdp); 661 xfs_mount_t *mp = XFS_BHVTOM(bdp);
670 int error;
671 662
672 if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */ 663 if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */
673 if (vfsp->vfs_flag & VFS_RDONLY) 664 if (vfsp->vfs_flag & VFS_RDONLY)
@@ -679,7 +670,7 @@ xfs_mntupdate(
679 mp->m_flags &= ~XFS_MOUNT_BARRIER; 670 mp->m_flags &= ~XFS_MOUNT_BARRIER;
680 } 671 }
681 } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ 672 } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */
682 VFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL, error); 673 bhv_vfs_sync(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL);
683 xfs_quiesce_fs(mp); 674 xfs_quiesce_fs(mp);
684 xfs_log_unmount_write(mp); 675 xfs_log_unmount_write(mp);
685 xfs_unmountfs_writesb(mp); 676 xfs_unmountfs_writesb(mp);
@@ -702,7 +693,7 @@ xfs_unmount_flush(
702 xfs_inode_t *rip = mp->m_rootip; 693 xfs_inode_t *rip = mp->m_rootip;
703 xfs_inode_t *rbmip; 694 xfs_inode_t *rbmip;
704 xfs_inode_t *rsumip = NULL; 695 xfs_inode_t *rsumip = NULL;
705 vnode_t *rvp = XFS_ITOV(rip); 696 bhv_vnode_t *rvp = XFS_ITOV(rip);
706 int error; 697 int error;
707 698
708 xfs_ilock(rip, XFS_ILOCK_EXCL); 699 xfs_ilock(rip, XFS_ILOCK_EXCL);
@@ -781,9 +772,9 @@ fscorrupt_out2:
781STATIC int 772STATIC int
782xfs_root( 773xfs_root(
783 bhv_desc_t *bdp, 774 bhv_desc_t *bdp,
784 vnode_t **vpp) 775 bhv_vnode_t **vpp)
785{ 776{
786 vnode_t *vp; 777 bhv_vnode_t *vp;
787 778
788 vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip); 779 vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip);
789 VN_HOLD(vp); 780 VN_HOLD(vp);
@@ -801,8 +792,8 @@ xfs_root(
801STATIC int 792STATIC int
802xfs_statvfs( 793xfs_statvfs(
803 bhv_desc_t *bdp, 794 bhv_desc_t *bdp,
804 xfs_statfs_t *statp, 795 bhv_statvfs_t *statp,
805 vnode_t *vp) 796 bhv_vnode_t *vp)
806{ 797{
807 __uint64_t fakeinos; 798 __uint64_t fakeinos;
808 xfs_extlen_t lsize; 799 xfs_extlen_t lsize;
@@ -900,7 +891,7 @@ xfs_sync(
900/* 891/*
901 * xfs sync routine for internal use 892 * xfs sync routine for internal use
902 * 893 *
903 * This routine supports all of the flags defined for the generic VFS_SYNC 894 * This routine supports all of the flags defined for the generic vfs_sync
904 * interface as explained above under xfs_sync. In the interests of not 895 * interface as explained above under xfs_sync. In the interests of not
905 * changing interfaces within the 6.5 family, additional internally- 896 * changing interfaces within the 6.5 family, additional internally-
906 * required functions are specified within a separate xflags parameter, 897 * required functions are specified within a separate xflags parameter,
@@ -917,7 +908,7 @@ xfs_sync_inodes(
917 xfs_inode_t *ip = NULL; 908 xfs_inode_t *ip = NULL;
918 xfs_inode_t *ip_next; 909 xfs_inode_t *ip_next;
919 xfs_buf_t *bp; 910 xfs_buf_t *bp;
920 vnode_t *vp = NULL; 911 bhv_vnode_t *vp = NULL;
921 int error; 912 int error;
922 int last_error; 913 int last_error;
923 uint64_t fflag; 914 uint64_t fflag;
@@ -1156,9 +1147,9 @@ xfs_sync_inodes(
1156 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1147 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1157 1148
1158 if (XFS_FORCED_SHUTDOWN(mp)) { 1149 if (XFS_FORCED_SHUTDOWN(mp)) {
1159 VOP_TOSS_PAGES(vp, 0, -1, FI_REMAPF); 1150 bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
1160 } else { 1151 } else {
1161 VOP_FLUSHINVAL_PAGES(vp, 0, -1, FI_REMAPF); 1152 bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF);
1162 } 1153 }
1163 1154
1164 xfs_ilock(ip, XFS_ILOCK_SHARED); 1155 xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -1178,8 +1169,8 @@ xfs_sync_inodes(
1178 * across calls to the buffer cache. 1169 * across calls to the buffer cache.
1179 */ 1170 */
1180 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1171 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1181 VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 1172 error = bhv_vop_flush_pages(vp, (xfs_off_t)0,
1182 fflag, FI_NONE, error); 1173 -1, fflag, FI_NONE);
1183 xfs_ilock(ip, XFS_ILOCK_SHARED); 1174 xfs_ilock(ip, XFS_ILOCK_SHARED);
1184 } 1175 }
1185 1176
@@ -1231,9 +1222,7 @@ xfs_sync_inodes(
1231 * marker and free it. 1222 * marker and free it.
1232 */ 1223 */
1233 XFS_MOUNT_ILOCK(mp); 1224 XFS_MOUNT_ILOCK(mp);
1234
1235 IPOINTER_REMOVE(ip, mp); 1225 IPOINTER_REMOVE(ip, mp);
1236
1237 XFS_MOUNT_IUNLOCK(mp); 1226 XFS_MOUNT_IUNLOCK(mp);
1238 1227
1239 ASSERT(!(lock_flags & 1228 ASSERT(!(lock_flags &
@@ -1421,7 +1410,7 @@ xfs_sync_inodes(
1421/* 1410/*
1422 * xfs sync routine for internal use 1411 * xfs sync routine for internal use
1423 * 1412 *
1424 * This routine supports all of the flags defined for the generic VFS_SYNC 1413 * This routine supports all of the flags defined for the generic vfs_sync
1425 * interface as explained above under xfs_sync. In the interests of not 1414 * interface as explained above under xfs_sync. In the interests of not
1426 * changing interfaces within the 6.5 family, additional internally- 1415 * changing interfaces within the 6.5 family, additional internally-
1427 * required functions are specified within a separate xflags parameter, 1416 * required functions are specified within a separate xflags parameter,
@@ -1574,7 +1563,7 @@ xfs_syncsub(
1574STATIC int 1563STATIC int
1575xfs_vget( 1564xfs_vget(
1576 bhv_desc_t *bdp, 1565 bhv_desc_t *bdp,
1577 vnode_t **vpp, 1566 bhv_vnode_t **vpp,
1578 fid_t *fidp) 1567 fid_t *fidp)
1579{ 1568{
1580 xfs_mount_t *mp = XFS_BHVTOM(bdp); 1569 xfs_mount_t *mp = XFS_BHVTOM(bdp);
@@ -1657,10 +1646,10 @@ xfs_vget(
1657#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ 1646#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
1658 1647
1659STATIC unsigned long 1648STATIC unsigned long
1660suffix_strtoul(const char *cp, char **endp, unsigned int base) 1649suffix_strtoul(char *s, char **endp, unsigned int base)
1661{ 1650{
1662 int last, shift_left_factor = 0; 1651 int last, shift_left_factor = 0;
1663 char *value = (char *)cp; 1652 char *value = s;
1664 1653
1665 last = strlen(value) - 1; 1654 last = strlen(value) - 1;
1666 if (value[last] == 'K' || value[last] == 'k') { 1655 if (value[last] == 'K' || value[last] == 'k') {
@@ -1676,7 +1665,7 @@ suffix_strtoul(const char *cp, char **endp, unsigned int base)
1676 value[last] = '\0'; 1665 value[last] = '\0';
1677 } 1666 }
1678 1667
1679 return simple_strtoul(cp, endp, base) << shift_left_factor; 1668 return simple_strtoul((const char *)s, endp, base) << shift_left_factor;
1680} 1669}
1681 1670
1682STATIC int 1671STATIC int
@@ -1686,7 +1675,7 @@ xfs_parseargs(
1686 struct xfs_mount_args *args, 1675 struct xfs_mount_args *args,
1687 int update) 1676 int update)
1688{ 1677{
1689 struct vfs *vfsp = bhvtovfs(bhv); 1678 bhv_vfs_t *vfsp = bhvtovfs(bhv);
1690 char *this_char, *value, *eov; 1679 char *this_char, *value, *eov;
1691 int dsunit, dswidth, vol_dsunit, vol_dswidth; 1680 int dsunit, dswidth, vol_dsunit, vol_dswidth;
1692 int iosize; 1681 int iosize;
@@ -1708,42 +1697,48 @@ xfs_parseargs(
1708 1697
1709 if (!strcmp(this_char, MNTOPT_LOGBUFS)) { 1698 if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
1710 if (!value || !*value) { 1699 if (!value || !*value) {
1711 printk("XFS: %s option requires an argument\n", 1700 cmn_err(CE_WARN,
1701 "XFS: %s option requires an argument",
1712 this_char); 1702 this_char);
1713 return EINVAL; 1703 return EINVAL;
1714 } 1704 }
1715 args->logbufs = simple_strtoul(value, &eov, 10); 1705 args->logbufs = simple_strtoul(value, &eov, 10);
1716 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { 1706 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
1717 if (!value || !*value) { 1707 if (!value || !*value) {
1718 printk("XFS: %s option requires an argument\n", 1708 cmn_err(CE_WARN,
1709 "XFS: %s option requires an argument",
1719 this_char); 1710 this_char);
1720 return EINVAL; 1711 return EINVAL;
1721 } 1712 }
1722 args->logbufsize = suffix_strtoul(value, &eov, 10); 1713 args->logbufsize = suffix_strtoul(value, &eov, 10);
1723 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { 1714 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
1724 if (!value || !*value) { 1715 if (!value || !*value) {
1725 printk("XFS: %s option requires an argument\n", 1716 cmn_err(CE_WARN,
1717 "XFS: %s option requires an argument",
1726 this_char); 1718 this_char);
1727 return EINVAL; 1719 return EINVAL;
1728 } 1720 }
1729 strncpy(args->logname, value, MAXNAMELEN); 1721 strncpy(args->logname, value, MAXNAMELEN);
1730 } else if (!strcmp(this_char, MNTOPT_MTPT)) { 1722 } else if (!strcmp(this_char, MNTOPT_MTPT)) {
1731 if (!value || !*value) { 1723 if (!value || !*value) {
1732 printk("XFS: %s option requires an argument\n", 1724 cmn_err(CE_WARN,
1725 "XFS: %s option requires an argument",
1733 this_char); 1726 this_char);
1734 return EINVAL; 1727 return EINVAL;
1735 } 1728 }
1736 strncpy(args->mtpt, value, MAXNAMELEN); 1729 strncpy(args->mtpt, value, MAXNAMELEN);
1737 } else if (!strcmp(this_char, MNTOPT_RTDEV)) { 1730 } else if (!strcmp(this_char, MNTOPT_RTDEV)) {
1738 if (!value || !*value) { 1731 if (!value || !*value) {
1739 printk("XFS: %s option requires an argument\n", 1732 cmn_err(CE_WARN,
1733 "XFS: %s option requires an argument",
1740 this_char); 1734 this_char);
1741 return EINVAL; 1735 return EINVAL;
1742 } 1736 }
1743 strncpy(args->rtname, value, MAXNAMELEN); 1737 strncpy(args->rtname, value, MAXNAMELEN);
1744 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { 1738 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
1745 if (!value || !*value) { 1739 if (!value || !*value) {
1746 printk("XFS: %s option requires an argument\n", 1740 cmn_err(CE_WARN,
1741 "XFS: %s option requires an argument",
1747 this_char); 1742 this_char);
1748 return EINVAL; 1743 return EINVAL;
1749 } 1744 }
@@ -1752,7 +1747,8 @@ xfs_parseargs(
1752 args->iosizelog = (uint8_t) iosize; 1747 args->iosizelog = (uint8_t) iosize;
1753 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { 1748 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
1754 if (!value || !*value) { 1749 if (!value || !*value) {
1755 printk("XFS: %s option requires an argument\n", 1750 cmn_err(CE_WARN,
1751 "XFS: %s option requires an argument",
1756 this_char); 1752 this_char);
1757 return EINVAL; 1753 return EINVAL;
1758 } 1754 }
@@ -1761,7 +1757,8 @@ xfs_parseargs(
1761 args->iosizelog = ffs(iosize) - 1; 1757 args->iosizelog = ffs(iosize) - 1;
1762 } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) { 1758 } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) {
1763 if (!value || !*value) { 1759 if (!value || !*value) {
1764 printk("XFS: %s option requires an argument\n", 1760 cmn_err(CE_WARN,
1761 "XFS: %s option requires an argument",
1765 this_char); 1762 this_char);
1766 return EINVAL; 1763 return EINVAL;
1767 } 1764 }
@@ -1782,7 +1779,8 @@ xfs_parseargs(
1782 } else if (!strcmp(this_char, MNTOPT_INO64)) { 1779 } else if (!strcmp(this_char, MNTOPT_INO64)) {
1783 args->flags |= XFSMNT_INO64; 1780 args->flags |= XFSMNT_INO64;
1784#if !XFS_BIG_INUMS 1781#if !XFS_BIG_INUMS
1785 printk("XFS: %s option not allowed on this system\n", 1782 cmn_err(CE_WARN,
1783 "XFS: %s option not allowed on this system",
1786 this_char); 1784 this_char);
1787 return EINVAL; 1785 return EINVAL;
1788#endif 1786#endif
@@ -1792,14 +1790,16 @@ xfs_parseargs(
1792 args->flags |= XFSMNT_SWALLOC; 1790 args->flags |= XFSMNT_SWALLOC;
1793 } else if (!strcmp(this_char, MNTOPT_SUNIT)) { 1791 } else if (!strcmp(this_char, MNTOPT_SUNIT)) {
1794 if (!value || !*value) { 1792 if (!value || !*value) {
1795 printk("XFS: %s option requires an argument\n", 1793 cmn_err(CE_WARN,
1794 "XFS: %s option requires an argument",
1796 this_char); 1795 this_char);
1797 return EINVAL; 1796 return EINVAL;
1798 } 1797 }
1799 dsunit = simple_strtoul(value, &eov, 10); 1798 dsunit = simple_strtoul(value, &eov, 10);
1800 } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { 1799 } else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
1801 if (!value || !*value) { 1800 if (!value || !*value) {
1802 printk("XFS: %s option requires an argument\n", 1801 cmn_err(CE_WARN,
1802 "XFS: %s option requires an argument",
1803 this_char); 1803 this_char);
1804 return EINVAL; 1804 return EINVAL;
1805 } 1805 }
@@ -1807,7 +1807,8 @@ xfs_parseargs(
1807 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { 1807 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
1808 args->flags &= ~XFSMNT_32BITINODES; 1808 args->flags &= ~XFSMNT_32BITINODES;
1809#if !XFS_BIG_INUMS 1809#if !XFS_BIG_INUMS
1810 printk("XFS: %s option not allowed on this system\n", 1810 cmn_err(CE_WARN,
1811 "XFS: %s option not allowed on this system",
1811 this_char); 1812 this_char);
1812 return EINVAL; 1813 return EINVAL;
1813#endif 1814#endif
@@ -1831,36 +1832,41 @@ xfs_parseargs(
1831 args->flags &= ~XFSMNT_ATTR2; 1832 args->flags &= ~XFSMNT_ATTR2;
1832 } else if (!strcmp(this_char, "osyncisdsync")) { 1833 } else if (!strcmp(this_char, "osyncisdsync")) {
1833 /* no-op, this is now the default */ 1834 /* no-op, this is now the default */
1834printk("XFS: osyncisdsync is now the default, option is deprecated.\n"); 1835 cmn_err(CE_WARN,
1836 "XFS: osyncisdsync is now the default, option is deprecated.");
1835 } else if (!strcmp(this_char, "irixsgid")) { 1837 } else if (!strcmp(this_char, "irixsgid")) {
1836printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n"); 1838 cmn_err(CE_WARN,
1839 "XFS: irixsgid is now a sysctl(2) variable, option is deprecated.");
1837 } else { 1840 } else {
1838 printk("XFS: unknown mount option [%s].\n", this_char); 1841 cmn_err(CE_WARN,
1842 "XFS: unknown mount option [%s].", this_char);
1839 return EINVAL; 1843 return EINVAL;
1840 } 1844 }
1841 } 1845 }
1842 1846
1843 if (args->flags & XFSMNT_NORECOVERY) { 1847 if (args->flags & XFSMNT_NORECOVERY) {
1844 if ((vfsp->vfs_flag & VFS_RDONLY) == 0) { 1848 if ((vfsp->vfs_flag & VFS_RDONLY) == 0) {
1845 printk("XFS: no-recovery mounts must be read-only.\n"); 1849 cmn_err(CE_WARN,
1850 "XFS: no-recovery mounts must be read-only.");
1846 return EINVAL; 1851 return EINVAL;
1847 } 1852 }
1848 } 1853 }
1849 1854
1850 if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) { 1855 if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) {
1851 printk( 1856 cmn_err(CE_WARN,
1852 "XFS: sunit and swidth options incompatible with the noalign option\n"); 1857 "XFS: sunit and swidth options incompatible with the noalign option");
1853 return EINVAL; 1858 return EINVAL;
1854 } 1859 }
1855 1860
1856 if ((dsunit && !dswidth) || (!dsunit && dswidth)) { 1861 if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
1857 printk("XFS: sunit and swidth must be specified together\n"); 1862 cmn_err(CE_WARN,
1863 "XFS: sunit and swidth must be specified together");
1858 return EINVAL; 1864 return EINVAL;
1859 } 1865 }
1860 1866
1861 if (dsunit && (dswidth % dsunit != 0)) { 1867 if (dsunit && (dswidth % dsunit != 0)) {
1862 printk( 1868 cmn_err(CE_WARN,
1863 "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)\n", 1869 "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)",
1864 dswidth, dsunit); 1870 dswidth, dsunit);
1865 return EINVAL; 1871 return EINVAL;
1866 } 1872 }
@@ -1907,7 +1913,7 @@ xfs_showargs(
1907 }; 1913 };
1908 struct proc_xfs_info *xfs_infop; 1914 struct proc_xfs_info *xfs_infop;
1909 struct xfs_mount *mp = XFS_BHVTOM(bhv); 1915 struct xfs_mount *mp = XFS_BHVTOM(bhv);
1910 struct vfs *vfsp = XFS_MTOVFS(mp); 1916 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
1911 1917
1912 for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) { 1918 for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
1913 if (mp->m_flags & xfs_infop->flag) 1919 if (mp->m_flags & xfs_infop->flag)
@@ -1967,7 +1973,7 @@ xfs_freeze(
1967} 1973}
1968 1974
1969 1975
1970vfsops_t xfs_vfsops = { 1976bhv_vfsops_t xfs_vfsops = {
1971 BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS), 1977 BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS),
1972 .vfs_parseargs = xfs_parseargs, 1978 .vfs_parseargs = xfs_parseargs,
1973 .vfs_showargs = xfs_showargs, 1979 .vfs_showargs = xfs_showargs,
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 7027ae68ee38..00a6b7dc24a0 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -16,8 +16,6 @@
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 18
19#include <linux/capability.h>
20
21#include "xfs.h" 19#include "xfs.h"
22#include "xfs_fs.h" 20#include "xfs_fs.h"
23#include "xfs_types.h" 21#include "xfs_types.h"
@@ -27,7 +25,6 @@
27#include "xfs_trans.h" 25#include "xfs_trans.h"
28#include "xfs_sb.h" 26#include "xfs_sb.h"
29#include "xfs_ag.h" 27#include "xfs_ag.h"
30#include "xfs_dir.h"
31#include "xfs_dir2.h" 28#include "xfs_dir2.h"
32#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
33#include "xfs_mount.h" 30#include "xfs_mount.h"
@@ -35,13 +32,11 @@
35#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
36#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
37#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
38#include "xfs_dir_sf.h"
39#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
40#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
41#include "xfs_dinode.h" 37#include "xfs_dinode.h"
42#include "xfs_inode.h" 38#include "xfs_inode.h"
43#include "xfs_inode_item.h" 39#include "xfs_inode_item.h"
44#include "xfs_dir_leaf.h"
45#include "xfs_itable.h" 40#include "xfs_itable.h"
46#include "xfs_btree.h" 41#include "xfs_btree.h"
47#include "xfs_ialloc.h" 42#include "xfs_ialloc.h"
@@ -58,32 +53,14 @@
58#include "xfs_log_priv.h" 53#include "xfs_log_priv.h"
59#include "xfs_mac.h" 54#include "xfs_mac.h"
60 55
61
62/*
63 * The maximum pathlen is 1024 bytes. Since the minimum file system
64 * blocksize is 512 bytes, we can get a max of 2 extents back from
65 * bmapi.
66 */
67#define SYMLINK_MAPS 2
68
69/*
70 * For xfs, we check that the file isn't too big to be opened by this kernel.
71 * No other open action is required for regular files. Devices are handled
72 * through the specfs file system, pipes through fifofs. Device and
73 * fifo vnodes are "wrapped" by specfs and fifofs vnodes, respectively,
74 * when a new vnode is first looked up or created.
75 */
76STATIC int 56STATIC int
77xfs_open( 57xfs_open(
78 bhv_desc_t *bdp, 58 bhv_desc_t *bdp,
79 cred_t *credp) 59 cred_t *credp)
80{ 60{
81 int mode; 61 int mode;
82 vnode_t *vp; 62 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
83 xfs_inode_t *ip; 63 xfs_inode_t *ip = XFS_BHVTOI(bdp);
84
85 vp = BHV_TO_VNODE(bdp);
86 ip = XFS_BHVTOI(bdp);
87 64
88 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) 65 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
89 return XFS_ERROR(EIO); 66 return XFS_ERROR(EIO);
@@ -101,6 +78,35 @@ xfs_open(
101 return 0; 78 return 0;
102} 79}
103 80
81STATIC int
82xfs_close(
83 bhv_desc_t *bdp,
84 int flags,
85 lastclose_t lastclose,
86 cred_t *credp)
87{
88 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
89 xfs_inode_t *ip = XFS_BHVTOI(bdp);
90
91 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
92 return XFS_ERROR(EIO);
93
94 if (lastclose != L_TRUE || !VN_ISREG(vp))
95 return 0;
96
97 /*
98 * If we previously truncated this file and removed old data in
99 * the process, we want to initiate "early" writeout on the last
100 * close. This is an attempt to combat the notorious NULL files
101 * problem which is particularly noticable from a truncate down,
102 * buffered (re-)write (delalloc), followed by a crash. What we
103 * are effectively doing here is significantly reducing the time
104 * window where we'd otherwise be exposed to that problem.
105 */
106 if (VUNTRUNCATE(vp) && VN_DIRTY(vp) && ip->i_delayed_blks > 0)
107 return bhv_vop_flush_pages(vp, 0, -1, XFS_B_ASYNC, FI_NONE);
108 return 0;
109}
104 110
105/* 111/*
106 * xfs_getattr 112 * xfs_getattr
@@ -108,13 +114,13 @@ xfs_open(
108STATIC int 114STATIC int
109xfs_getattr( 115xfs_getattr(
110 bhv_desc_t *bdp, 116 bhv_desc_t *bdp,
111 vattr_t *vap, 117 bhv_vattr_t *vap,
112 int flags, 118 int flags,
113 cred_t *credp) 119 cred_t *credp)
114{ 120{
115 xfs_inode_t *ip; 121 xfs_inode_t *ip;
116 xfs_mount_t *mp; 122 xfs_mount_t *mp;
117 vnode_t *vp; 123 bhv_vnode_t *vp;
118 124
119 vp = BHV_TO_VNODE(bdp); 125 vp = BHV_TO_VNODE(bdp);
120 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 126 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
@@ -241,7 +247,7 @@ xfs_getattr(
241int 247int
242xfs_setattr( 248xfs_setattr(
243 bhv_desc_t *bdp, 249 bhv_desc_t *bdp,
244 vattr_t *vap, 250 bhv_vattr_t *vap,
245 int flags, 251 int flags,
246 cred_t *credp) 252 cred_t *credp)
247{ 253{
@@ -255,7 +261,7 @@ xfs_setattr(
255 uid_t uid=0, iuid=0; 261 uid_t uid=0, iuid=0;
256 gid_t gid=0, igid=0; 262 gid_t gid=0, igid=0;
257 int timeflags = 0; 263 int timeflags = 0;
258 vnode_t *vp; 264 bhv_vnode_t *vp;
259 xfs_prid_t projid=0, iprojid=0; 265 xfs_prid_t projid=0, iprojid=0;
260 int mandlock_before, mandlock_after; 266 int mandlock_before, mandlock_after;
261 struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; 267 struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
@@ -347,7 +353,6 @@ xfs_setattr(
347 */ 353 */
348 tp = NULL; 354 tp = NULL;
349 lock_flags = XFS_ILOCK_EXCL; 355 lock_flags = XFS_ILOCK_EXCL;
350 ASSERT(flags & ATTR_NOLOCK ? flags & ATTR_DMI : 1);
351 if (flags & ATTR_NOLOCK) 356 if (flags & ATTR_NOLOCK)
352 need_iolock = 0; 357 need_iolock = 0;
353 if (!(mask & XFS_AT_SIZE)) { 358 if (!(mask & XFS_AT_SIZE)) {
@@ -666,9 +671,17 @@ xfs_setattr(
666 ((ip->i_d.di_nlink != 0 || 671 ((ip->i_d.di_nlink != 0 ||
667 !(mp->m_flags & XFS_MOUNT_WSYNC)) 672 !(mp->m_flags & XFS_MOUNT_WSYNC))
668 ? 1 : 0)); 673 ? 1 : 0));
669 if (code) { 674 if (code)
670 goto abort_return; 675 goto abort_return;
671 } 676 /*
677 * Truncated "down", so we're removing references
678 * to old data here - if we now delay flushing for
679 * a long time, we expose ourselves unduly to the
680 * notorious NULL files problem. So, we mark this
681 * vnode and flush it when the file is closed, and
682 * do not wait the usual (long) time for writeout.
683 */
684 VTRUNCATE(vp);
672 } 685 }
673 /* 686 /*
674 * Have to do this even if the file's size doesn't change. 687 * Have to do this even if the file's size doesn't change.
@@ -800,6 +813,8 @@ xfs_setattr(
800 di_flags |= XFS_DIFLAG_NODUMP; 813 di_flags |= XFS_DIFLAG_NODUMP;
801 if (vap->va_xflags & XFS_XFLAG_PROJINHERIT) 814 if (vap->va_xflags & XFS_XFLAG_PROJINHERIT)
802 di_flags |= XFS_DIFLAG_PROJINHERIT; 815 di_flags |= XFS_DIFLAG_PROJINHERIT;
816 if (vap->va_xflags & XFS_XFLAG_NODEFRAG)
817 di_flags |= XFS_DIFLAG_NODEFRAG;
803 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { 818 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
804 if (vap->va_xflags & XFS_XFLAG_RTINHERIT) 819 if (vap->va_xflags & XFS_XFLAG_RTINHERIT)
805 di_flags |= XFS_DIFLAG_RTINHERIT; 820 di_flags |= XFS_DIFLAG_RTINHERIT;
@@ -869,7 +884,7 @@ xfs_setattr(
869 */ 884 */
870 mandlock_after = MANDLOCK(vp, ip->i_d.di_mode); 885 mandlock_after = MANDLOCK(vp, ip->i_d.di_mode);
871 if (mandlock_before != mandlock_after) { 886 if (mandlock_before != mandlock_after) {
872 VOP_VNODE_CHANGE(vp, VCHANGE_FLAGS_ENF_LOCKING, 887 bhv_vop_vnode_change(vp, VCHANGE_FLAGS_ENF_LOCKING,
873 mandlock_after); 888 mandlock_after);
874 } 889 }
875 890
@@ -936,6 +951,13 @@ xfs_access(
936 951
937 952
938/* 953/*
954 * The maximum pathlen is 1024 bytes. Since the minimum file system
955 * blocksize is 512 bytes, we can get a max of 2 extents back from
956 * bmapi.
957 */
958#define SYMLINK_MAPS 2
959
960/*
939 * xfs_readlink 961 * xfs_readlink
940 * 962 *
941 */ 963 */
@@ -950,7 +972,7 @@ xfs_readlink(
950 int count; 972 int count;
951 xfs_off_t offset; 973 xfs_off_t offset;
952 int pathlen; 974 int pathlen;
953 vnode_t *vp; 975 bhv_vnode_t *vp;
954 int error = 0; 976 int error = 0;
955 xfs_mount_t *mp; 977 xfs_mount_t *mp;
956 int nmaps; 978 int nmaps;
@@ -1000,7 +1022,7 @@ xfs_readlink(
1000 nmaps = SYMLINK_MAPS; 1022 nmaps = SYMLINK_MAPS;
1001 1023
1002 error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), 1024 error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen),
1003 0, NULL, 0, mval, &nmaps, NULL); 1025 0, NULL, 0, mval, &nmaps, NULL, NULL);
1004 1026
1005 if (error) { 1027 if (error) {
1006 goto error_return; 1028 goto error_return;
@@ -1208,8 +1230,8 @@ xfs_inactive_free_eofblocks(
1208 1230
1209 nimaps = 1; 1231 nimaps = 1;
1210 xfs_ilock(ip, XFS_ILOCK_SHARED); 1232 xfs_ilock(ip, XFS_ILOCK_SHARED);
1211 error = xfs_bmapi(NULL, ip, end_fsb, map_len, 0, 1233 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, end_fsb, map_len, 0,
1212 NULL, 0, &imap, &nimaps, NULL); 1234 NULL, 0, &imap, &nimaps, NULL, NULL);
1213 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1235 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1214 1236
1215 if (!error && (nimaps != 0) && 1237 if (!error && (nimaps != 0) &&
@@ -1338,7 +1360,7 @@ xfs_inactive_symlink_rmt(
1338 nmaps = ARRAY_SIZE(mval); 1360 nmaps = ARRAY_SIZE(mval);
1339 if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size), 1361 if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size),
1340 XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps, 1362 XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps,
1341 &free_list))) 1363 &free_list, NULL)))
1342 goto error0; 1364 goto error0;
1343 /* 1365 /*
1344 * Invalidate the block(s). 1366 * Invalidate the block(s).
@@ -1353,7 +1375,7 @@ xfs_inactive_symlink_rmt(
1353 * Unmap the dead block(s) to the free_list. 1375 * Unmap the dead block(s) to the free_list.
1354 */ 1376 */
1355 if ((error = xfs_bunmapi(tp, ip, 0, size, XFS_BMAPI_METADATA, nmaps, 1377 if ((error = xfs_bunmapi(tp, ip, 0, size, XFS_BMAPI_METADATA, nmaps,
1356 &first_block, &free_list, &done))) 1378 &first_block, &free_list, NULL, &done)))
1357 goto error1; 1379 goto error1;
1358 ASSERT(done); 1380 ASSERT(done);
1359 /* 1381 /*
@@ -1469,9 +1491,6 @@ xfs_inactive_symlink_local(
1469 return 0; 1491 return 0;
1470} 1492}
1471 1493
1472/*
1473 *
1474 */
1475STATIC int 1494STATIC int
1476xfs_inactive_attrs( 1495xfs_inactive_attrs(
1477 xfs_inode_t *ip, 1496 xfs_inode_t *ip,
@@ -1524,16 +1543,16 @@ xfs_release(
1524 bhv_desc_t *bdp) 1543 bhv_desc_t *bdp)
1525{ 1544{
1526 xfs_inode_t *ip; 1545 xfs_inode_t *ip;
1527 vnode_t *vp; 1546 bhv_vnode_t *vp;
1528 xfs_mount_t *mp; 1547 xfs_mount_t *mp;
1529 int error; 1548 int error;
1530 1549
1531 vp = BHV_TO_VNODE(bdp); 1550 vp = BHV_TO_VNODE(bdp);
1532 ip = XFS_BHVTOI(bdp); 1551 ip = XFS_BHVTOI(bdp);
1552 mp = ip->i_mount;
1533 1553
1534 if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) { 1554 if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0))
1535 return 0; 1555 return 0;
1536 }
1537 1556
1538 /* If this is a read-only mount, don't do this (would generate I/O) */ 1557 /* If this is a read-only mount, don't do this (would generate I/O) */
1539 if (vp->v_vfsp->vfs_flag & VFS_RDONLY) 1558 if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
@@ -1545,8 +1564,6 @@ xfs_release(
1545 return 0; 1564 return 0;
1546#endif 1565#endif
1547 1566
1548 mp = ip->i_mount;
1549
1550 if (ip->i_d.di_nlink != 0) { 1567 if (ip->i_d.di_nlink != 0) {
1551 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 1568 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
1552 ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 || 1569 ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 ||
@@ -1579,8 +1596,8 @@ xfs_inactive(
1579 cred_t *credp) 1596 cred_t *credp)
1580{ 1597{
1581 xfs_inode_t *ip; 1598 xfs_inode_t *ip;
1582 vnode_t *vp; 1599 bhv_vnode_t *vp;
1583 xfs_bmap_free_t free_list; 1600 xfs_bmap_free_t free_list;
1584 xfs_fsblock_t first_block; 1601 xfs_fsblock_t first_block;
1585 int committed; 1602 int committed;
1586 xfs_trans_t *tp; 1603 xfs_trans_t *tp;
@@ -1760,7 +1777,7 @@ xfs_inactive(
1760 cmn_err(CE_NOTE, 1777 cmn_err(CE_NOTE,
1761 "xfs_inactive: xfs_ifree() returned an error = %d on %s", 1778 "xfs_inactive: xfs_ifree() returned an error = %d on %s",
1762 error, mp->m_fsname); 1779 error, mp->m_fsname);
1763 xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); 1780 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
1764 } 1781 }
1765 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); 1782 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
1766 } else { 1783 } else {
@@ -1795,17 +1812,17 @@ xfs_inactive(
1795STATIC int 1812STATIC int
1796xfs_lookup( 1813xfs_lookup(
1797 bhv_desc_t *dir_bdp, 1814 bhv_desc_t *dir_bdp,
1798 vname_t *dentry, 1815 bhv_vname_t *dentry,
1799 vnode_t **vpp, 1816 bhv_vnode_t **vpp,
1800 int flags, 1817 int flags,
1801 vnode_t *rdir, 1818 bhv_vnode_t *rdir,
1802 cred_t *credp) 1819 cred_t *credp)
1803{ 1820{
1804 xfs_inode_t *dp, *ip; 1821 xfs_inode_t *dp, *ip;
1805 xfs_ino_t e_inum; 1822 xfs_ino_t e_inum;
1806 int error; 1823 int error;
1807 uint lock_mode; 1824 uint lock_mode;
1808 vnode_t *dir_vp; 1825 bhv_vnode_t *dir_vp;
1809 1826
1810 dir_vp = BHV_TO_VNODE(dir_bdp); 1827 dir_vp = BHV_TO_VNODE(dir_bdp);
1811 vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); 1828 vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
@@ -1832,15 +1849,15 @@ xfs_lookup(
1832STATIC int 1849STATIC int
1833xfs_create( 1850xfs_create(
1834 bhv_desc_t *dir_bdp, 1851 bhv_desc_t *dir_bdp,
1835 vname_t *dentry, 1852 bhv_vname_t *dentry,
1836 vattr_t *vap, 1853 bhv_vattr_t *vap,
1837 vnode_t **vpp, 1854 bhv_vnode_t **vpp,
1838 cred_t *credp) 1855 cred_t *credp)
1839{ 1856{
1840 char *name = VNAME(dentry); 1857 char *name = VNAME(dentry);
1841 vnode_t *dir_vp; 1858 bhv_vnode_t *dir_vp;
1842 xfs_inode_t *dp, *ip; 1859 xfs_inode_t *dp, *ip;
1843 vnode_t *vp=NULL; 1860 bhv_vnode_t *vp = NULL;
1844 xfs_trans_t *tp; 1861 xfs_trans_t *tp;
1845 xfs_mount_t *mp; 1862 xfs_mount_t *mp;
1846 xfs_dev_t rdev; 1863 xfs_dev_t rdev;
@@ -1938,8 +1955,7 @@ xfs_create(
1938 if (error) 1955 if (error)
1939 goto error_return; 1956 goto error_return;
1940 1957
1941 if (resblks == 0 && 1958 if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen)))
1942 (error = XFS_DIR_CANENTER(mp, tp, dp, name, namelen)))
1943 goto error_return; 1959 goto error_return;
1944 rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; 1960 rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0;
1945 error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1, 1961 error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1,
@@ -1970,9 +1986,9 @@ xfs_create(
1970 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); 1986 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
1971 dp_joined_to_trans = B_TRUE; 1987 dp_joined_to_trans = B_TRUE;
1972 1988
1973 error = XFS_DIR_CREATENAME(mp, tp, dp, name, namelen, ip->i_ino, 1989 error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino,
1974 &first_block, &free_list, 1990 &first_block, &free_list, resblks ?
1975 resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); 1991 resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
1976 if (error) { 1992 if (error) {
1977 ASSERT(error != ENOSPC); 1993 ASSERT(error != ENOSPC);
1978 goto abort_return; 1994 goto abort_return;
@@ -2026,7 +2042,7 @@ xfs_create(
2026 * Propagate the fact that the vnode changed after the 2042 * Propagate the fact that the vnode changed after the
2027 * xfs_inode locks have been released. 2043 * xfs_inode locks have been released.
2028 */ 2044 */
2029 VOP_VNODE_CHANGE(vp, VCHANGE_FLAGS_TRUNCATED, 3); 2045 bhv_vop_vnode_change(vp, VCHANGE_FLAGS_TRUNCATED, 3);
2030 2046
2031 *vpp = vp; 2047 *vpp = vp;
2032 2048
@@ -2107,7 +2123,7 @@ int xfs_rm_attempts;
2107STATIC int 2123STATIC int
2108xfs_lock_dir_and_entry( 2124xfs_lock_dir_and_entry(
2109 xfs_inode_t *dp, 2125 xfs_inode_t *dp,
2110 vname_t *dentry, 2126 bhv_vname_t *dentry,
2111 xfs_inode_t *ip) /* inode of entry 'name' */ 2127 xfs_inode_t *ip) /* inode of entry 'name' */
2112{ 2128{
2113 int attempts; 2129 int attempts;
@@ -2321,10 +2337,10 @@ int remove_which_error_return = 0;
2321STATIC int 2337STATIC int
2322xfs_remove( 2338xfs_remove(
2323 bhv_desc_t *dir_bdp, 2339 bhv_desc_t *dir_bdp,
2324 vname_t *dentry, 2340 bhv_vname_t *dentry,
2325 cred_t *credp) 2341 cred_t *credp)
2326{ 2342{
2327 vnode_t *dir_vp; 2343 bhv_vnode_t *dir_vp;
2328 char *name = VNAME(dentry); 2344 char *name = VNAME(dentry);
2329 xfs_inode_t *dp, *ip; 2345 xfs_inode_t *dp, *ip;
2330 xfs_trans_t *tp = NULL; 2346 xfs_trans_t *tp = NULL;
@@ -2448,8 +2464,8 @@ xfs_remove(
2448 * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. 2464 * Entry must exist since we did a lookup in xfs_lock_dir_and_entry.
2449 */ 2465 */
2450 XFS_BMAP_INIT(&free_list, &first_block); 2466 XFS_BMAP_INIT(&free_list, &first_block);
2451 error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, ip->i_ino, 2467 error = xfs_dir_removename(tp, dp, name, namelen, ip->i_ino,
2452 &first_block, &free_list, 0); 2468 &first_block, &free_list, 0);
2453 if (error) { 2469 if (error) {
2454 ASSERT(error != ENOENT); 2470 ASSERT(error != ENOENT);
2455 REMOVE_DEBUG_TRACE(__LINE__); 2471 REMOVE_DEBUG_TRACE(__LINE__);
@@ -2511,7 +2527,7 @@ xfs_remove(
2511 /* 2527 /*
2512 * Let interposed file systems know about removed links. 2528 * Let interposed file systems know about removed links.
2513 */ 2529 */
2514 VOP_LINK_REMOVED(XFS_ITOV(ip), dir_vp, link_zero); 2530 bhv_vop_link_removed(XFS_ITOV(ip), dir_vp, link_zero);
2515 2531
2516 IRELE(ip); 2532 IRELE(ip);
2517 2533
@@ -2564,8 +2580,8 @@ xfs_remove(
2564STATIC int 2580STATIC int
2565xfs_link( 2581xfs_link(
2566 bhv_desc_t *target_dir_bdp, 2582 bhv_desc_t *target_dir_bdp,
2567 vnode_t *src_vp, 2583 bhv_vnode_t *src_vp,
2568 vname_t *dentry, 2584 bhv_vname_t *dentry,
2569 cred_t *credp) 2585 cred_t *credp)
2570{ 2586{
2571 xfs_inode_t *tdp, *sip; 2587 xfs_inode_t *tdp, *sip;
@@ -2577,7 +2593,7 @@ xfs_link(
2577 xfs_fsblock_t first_block; 2593 xfs_fsblock_t first_block;
2578 int cancel_flags; 2594 int cancel_flags;
2579 int committed; 2595 int committed;
2580 vnode_t *target_dir_vp; 2596 bhv_vnode_t *target_dir_vp;
2581 int resblks; 2597 int resblks;
2582 char *target_name = VNAME(dentry); 2598 char *target_name = VNAME(dentry);
2583 int target_namelen; 2599 int target_namelen;
@@ -2668,13 +2684,12 @@ xfs_link(
2668 } 2684 }
2669 2685
2670 if (resblks == 0 && 2686 if (resblks == 0 &&
2671 (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name, 2687 (error = xfs_dir_canenter(tp, tdp, target_name, target_namelen)))
2672 target_namelen)))
2673 goto error_return; 2688 goto error_return;
2674 2689
2675 XFS_BMAP_INIT(&free_list, &first_block); 2690 XFS_BMAP_INIT(&free_list, &first_block);
2676 2691
2677 error = XFS_DIR_CREATENAME(mp, tp, tdp, target_name, target_namelen, 2692 error = xfs_dir_createname(tp, tdp, target_name, target_namelen,
2678 sip->i_ino, &first_block, &free_list, 2693 sip->i_ino, &first_block, &free_list,
2679 resblks); 2694 resblks);
2680 if (error) 2695 if (error)
@@ -2734,15 +2749,15 @@ std_return:
2734STATIC int 2749STATIC int
2735xfs_mkdir( 2750xfs_mkdir(
2736 bhv_desc_t *dir_bdp, 2751 bhv_desc_t *dir_bdp,
2737 vname_t *dentry, 2752 bhv_vname_t *dentry,
2738 vattr_t *vap, 2753 bhv_vattr_t *vap,
2739 vnode_t **vpp, 2754 bhv_vnode_t **vpp,
2740 cred_t *credp) 2755 cred_t *credp)
2741{ 2756{
2742 char *dir_name = VNAME(dentry); 2757 char *dir_name = VNAME(dentry);
2743 xfs_inode_t *dp; 2758 xfs_inode_t *dp;
2744 xfs_inode_t *cdp; /* inode of created dir */ 2759 xfs_inode_t *cdp; /* inode of created dir */
2745 vnode_t *cvp; /* vnode of created dir */ 2760 bhv_vnode_t *cvp; /* vnode of created dir */
2746 xfs_trans_t *tp; 2761 xfs_trans_t *tp;
2747 xfs_mount_t *mp; 2762 xfs_mount_t *mp;
2748 int cancel_flags; 2763 int cancel_flags;
@@ -2750,7 +2765,7 @@ xfs_mkdir(
2750 int committed; 2765 int committed;
2751 xfs_bmap_free_t free_list; 2766 xfs_bmap_free_t free_list;
2752 xfs_fsblock_t first_block; 2767 xfs_fsblock_t first_block;
2753 vnode_t *dir_vp; 2768 bhv_vnode_t *dir_vp;
2754 boolean_t dp_joined_to_trans; 2769 boolean_t dp_joined_to_trans;
2755 boolean_t created = B_FALSE; 2770 boolean_t created = B_FALSE;
2756 int dm_event_sent = 0; 2771 int dm_event_sent = 0;
@@ -2840,7 +2855,7 @@ xfs_mkdir(
2840 goto error_return; 2855 goto error_return;
2841 2856
2842 if (resblks == 0 && 2857 if (resblks == 0 &&
2843 (error = XFS_DIR_CANENTER(mp, tp, dp, dir_name, dir_namelen))) 2858 (error = xfs_dir_canenter(tp, dp, dir_name, dir_namelen)))
2844 goto error_return; 2859 goto error_return;
2845 /* 2860 /*
2846 * create the directory inode. 2861 * create the directory inode.
@@ -2867,9 +2882,9 @@ xfs_mkdir(
2867 2882
2868 XFS_BMAP_INIT(&free_list, &first_block); 2883 XFS_BMAP_INIT(&free_list, &first_block);
2869 2884
2870 error = XFS_DIR_CREATENAME(mp, tp, dp, dir_name, dir_namelen, 2885 error = xfs_dir_createname(tp, dp, dir_name, dir_namelen, cdp->i_ino,
2871 cdp->i_ino, &first_block, &free_list, 2886 &first_block, &free_list, resblks ?
2872 resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); 2887 resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
2873 if (error) { 2888 if (error) {
2874 ASSERT(error != ENOSPC); 2889 ASSERT(error != ENOSPC);
2875 goto error1; 2890 goto error1;
@@ -2883,16 +2898,14 @@ xfs_mkdir(
2883 */ 2898 */
2884 dp->i_gen++; 2899 dp->i_gen++;
2885 2900
2886 error = XFS_DIR_INIT(mp, tp, cdp, dp); 2901 error = xfs_dir_init(tp, cdp, dp);
2887 if (error) { 2902 if (error)
2888 goto error2; 2903 goto error2;
2889 }
2890 2904
2891 cdp->i_gen = 1; 2905 cdp->i_gen = 1;
2892 error = xfs_bumplink(tp, dp); 2906 error = xfs_bumplink(tp, dp);
2893 if (error) { 2907 if (error)
2894 goto error2; 2908 goto error2;
2895 }
2896 2909
2897 cvp = XFS_ITOV(cdp); 2910 cvp = XFS_ITOV(cdp);
2898 2911
@@ -2969,7 +2982,7 @@ std_return:
2969STATIC int 2982STATIC int
2970xfs_rmdir( 2983xfs_rmdir(
2971 bhv_desc_t *dir_bdp, 2984 bhv_desc_t *dir_bdp,
2972 vname_t *dentry, 2985 bhv_vname_t *dentry,
2973 cred_t *credp) 2986 cred_t *credp)
2974{ 2987{
2975 char *name = VNAME(dentry); 2988 char *name = VNAME(dentry);
@@ -2982,7 +2995,7 @@ xfs_rmdir(
2982 xfs_fsblock_t first_block; 2995 xfs_fsblock_t first_block;
2983 int cancel_flags; 2996 int cancel_flags;
2984 int committed; 2997 int committed;
2985 vnode_t *dir_vp; 2998 bhv_vnode_t *dir_vp;
2986 int dm_di_mode = 0; 2999 int dm_di_mode = 0;
2987 int last_cdp_link; 3000 int last_cdp_link;
2988 int namelen; 3001 int namelen;
@@ -3101,16 +3114,15 @@ xfs_rmdir(
3101 error = XFS_ERROR(ENOTEMPTY); 3114 error = XFS_ERROR(ENOTEMPTY);
3102 goto error_return; 3115 goto error_return;
3103 } 3116 }
3104 if (!XFS_DIR_ISEMPTY(mp, cdp)) { 3117 if (!xfs_dir_isempty(cdp)) {
3105 error = XFS_ERROR(ENOTEMPTY); 3118 error = XFS_ERROR(ENOTEMPTY);
3106 goto error_return; 3119 goto error_return;
3107 } 3120 }
3108 3121
3109 error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, cdp->i_ino, 3122 error = xfs_dir_removename(tp, dp, name, namelen, cdp->i_ino,
3110 &first_block, &free_list, resblks); 3123 &first_block, &free_list, resblks);
3111 if (error) { 3124 if (error)
3112 goto error1; 3125 goto error1;
3113 }
3114 3126
3115 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 3127 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
3116 3128
@@ -3181,7 +3193,7 @@ xfs_rmdir(
3181 /* 3193 /*
3182 * Let interposed file systems know about removed links. 3194 * Let interposed file systems know about removed links.
3183 */ 3195 */
3184 VOP_LINK_REMOVED(XFS_ITOV(cdp), dir_vp, last_cdp_link); 3196 bhv_vop_link_removed(XFS_ITOV(cdp), dir_vp, last_cdp_link);
3185 3197
3186 IRELE(cdp); 3198 IRELE(cdp);
3187 3199
@@ -3209,8 +3221,6 @@ xfs_rmdir(
3209 3221
3210 3222
3211/* 3223/*
3212 * xfs_readdir
3213 *
3214 * Read dp's entries starting at uiop->uio_offset and translate them into 3224 * Read dp's entries starting at uiop->uio_offset and translate them into
3215 * bufsize bytes worth of struct dirents starting at bufbase. 3225 * bufsize bytes worth of struct dirents starting at bufbase.
3216 */ 3226 */
@@ -3230,28 +3240,23 @@ xfs_readdir(
3230 (inst_t *)__return_address); 3240 (inst_t *)__return_address);
3231 dp = XFS_BHVTOI(dir_bdp); 3241 dp = XFS_BHVTOI(dir_bdp);
3232 3242
3233 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) { 3243 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
3234 return XFS_ERROR(EIO); 3244 return XFS_ERROR(EIO);
3235 }
3236 3245
3237 lock_mode = xfs_ilock_map_shared(dp); 3246 lock_mode = xfs_ilock_map_shared(dp);
3238 error = XFS_DIR_GETDENTS(dp->i_mount, tp, dp, uiop, eofp); 3247 error = xfs_dir_getdents(tp, dp, uiop, eofp);
3239 xfs_iunlock_map_shared(dp, lock_mode); 3248 xfs_iunlock_map_shared(dp, lock_mode);
3240 return error; 3249 return error;
3241} 3250}
3242 3251
3243 3252
3244/*
3245 * xfs_symlink
3246 *
3247 */
3248STATIC int 3253STATIC int
3249xfs_symlink( 3254xfs_symlink(
3250 bhv_desc_t *dir_bdp, 3255 bhv_desc_t *dir_bdp,
3251 vname_t *dentry, 3256 bhv_vname_t *dentry,
3252 vattr_t *vap, 3257 bhv_vattr_t *vap,
3253 char *target_path, 3258 char *target_path,
3254 vnode_t **vpp, 3259 bhv_vnode_t **vpp,
3255 cred_t *credp) 3260 cred_t *credp)
3256{ 3261{
3257 xfs_trans_t *tp; 3262 xfs_trans_t *tp;
@@ -3263,7 +3268,7 @@ xfs_symlink(
3263 xfs_bmap_free_t free_list; 3268 xfs_bmap_free_t free_list;
3264 xfs_fsblock_t first_block; 3269 xfs_fsblock_t first_block;
3265 boolean_t dp_joined_to_trans; 3270 boolean_t dp_joined_to_trans;
3266 vnode_t *dir_vp; 3271 bhv_vnode_t *dir_vp;
3267 uint cancel_flags; 3272 uint cancel_flags;
3268 int committed; 3273 int committed;
3269 xfs_fileoff_t first_fsb; 3274 xfs_fileoff_t first_fsb;
@@ -3308,7 +3313,7 @@ xfs_symlink(
3308 int len, total; 3313 int len, total;
3309 char *path; 3314 char *path;
3310 3315
3311 for(total = 0, path = target_path; total < pathlen;) { 3316 for (total = 0, path = target_path; total < pathlen;) {
3312 /* 3317 /*
3313 * Skip any slashes. 3318 * Skip any slashes.
3314 */ 3319 */
@@ -3402,7 +3407,7 @@ xfs_symlink(
3402 * Check for ability to enter directory entry, if no space reserved. 3407 * Check for ability to enter directory entry, if no space reserved.
3403 */ 3408 */
3404 if (resblks == 0 && 3409 if (resblks == 0 &&
3405 (error = XFS_DIR_CANENTER(mp, tp, dp, link_name, link_namelen))) 3410 (error = xfs_dir_canenter(tp, dp, link_name, link_namelen)))
3406 goto error_return; 3411 goto error_return;
3407 /* 3412 /*
3408 * Initialize the bmap freelist prior to calling either 3413 * Initialize the bmap freelist prior to calling either
@@ -3457,7 +3462,7 @@ xfs_symlink(
3457 error = xfs_bmapi(tp, ip, first_fsb, fs_blocks, 3462 error = xfs_bmapi(tp, ip, first_fsb, fs_blocks,
3458 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, 3463 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA,
3459 &first_block, resblks, mval, &nmaps, 3464 &first_block, resblks, mval, &nmaps,
3460 &free_list); 3465 &free_list, NULL);
3461 if (error) { 3466 if (error) {
3462 goto error1; 3467 goto error1;
3463 } 3468 }
@@ -3489,11 +3494,10 @@ xfs_symlink(
3489 /* 3494 /*
3490 * Create the directory entry for the symlink. 3495 * Create the directory entry for the symlink.
3491 */ 3496 */
3492 error = XFS_DIR_CREATENAME(mp, tp, dp, link_name, link_namelen, 3497 error = xfs_dir_createname(tp, dp, link_name, link_namelen, ip->i_ino,
3493 ip->i_ino, &first_block, &free_list, resblks); 3498 &first_block, &free_list, resblks);
3494 if (error) { 3499 if (error)
3495 goto error1; 3500 goto error1;
3496 }
3497 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 3501 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
3498 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); 3502 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
3499 3503
@@ -3541,7 +3545,7 @@ std_return:
3541 } 3545 }
3542 3546
3543 if (!error) { 3547 if (!error) {
3544 vnode_t *vp; 3548 bhv_vnode_t *vp;
3545 3549
3546 ASSERT(ip); 3550 ASSERT(ip);
3547 vp = XFS_ITOV(ip); 3551 vp = XFS_ITOV(ip);
@@ -3606,10 +3610,10 @@ xfs_fid2(
3606int 3610int
3607xfs_rwlock( 3611xfs_rwlock(
3608 bhv_desc_t *bdp, 3612 bhv_desc_t *bdp,
3609 vrwlock_t locktype) 3613 bhv_vrwlock_t locktype)
3610{ 3614{
3611 xfs_inode_t *ip; 3615 xfs_inode_t *ip;
3612 vnode_t *vp; 3616 bhv_vnode_t *vp;
3613 3617
3614 vp = BHV_TO_VNODE(bdp); 3618 vp = BHV_TO_VNODE(bdp);
3615 if (VN_ISDIR(vp)) 3619 if (VN_ISDIR(vp))
@@ -3637,10 +3641,10 @@ xfs_rwlock(
3637void 3641void
3638xfs_rwunlock( 3642xfs_rwunlock(
3639 bhv_desc_t *bdp, 3643 bhv_desc_t *bdp,
3640 vrwlock_t locktype) 3644 bhv_vrwlock_t locktype)
3641{ 3645{
3642 xfs_inode_t *ip; 3646 xfs_inode_t *ip;
3643 vnode_t *vp; 3647 bhv_vnode_t *vp;
3644 3648
3645 vp = BHV_TO_VNODE(bdp); 3649 vp = BHV_TO_VNODE(bdp);
3646 if (VN_ISDIR(vp)) 3650 if (VN_ISDIR(vp))
@@ -3744,7 +3748,6 @@ xfs_inode_flush(
3744 return error; 3748 return error;
3745} 3749}
3746 3750
3747
3748int 3751int
3749xfs_set_dmattrs ( 3752xfs_set_dmattrs (
3750 bhv_desc_t *bdp, 3753 bhv_desc_t *bdp,
@@ -3785,16 +3788,12 @@ xfs_set_dmattrs (
3785 return error; 3788 return error;
3786} 3789}
3787 3790
3788
3789/*
3790 * xfs_reclaim
3791 */
3792STATIC int 3791STATIC int
3793xfs_reclaim( 3792xfs_reclaim(
3794 bhv_desc_t *bdp) 3793 bhv_desc_t *bdp)
3795{ 3794{
3796 xfs_inode_t *ip; 3795 xfs_inode_t *ip;
3797 vnode_t *vp; 3796 bhv_vnode_t *vp;
3798 3797
3799 vp = BHV_TO_VNODE(bdp); 3798 vp = BHV_TO_VNODE(bdp);
3800 ip = XFS_BHVTOI(bdp); 3799 ip = XFS_BHVTOI(bdp);
@@ -3849,7 +3848,7 @@ xfs_finish_reclaim(
3849 int sync_mode) 3848 int sync_mode)
3850{ 3849{
3851 xfs_ihash_t *ih = ip->i_hash; 3850 xfs_ihash_t *ih = ip->i_hash;
3852 vnode_t *vp = XFS_ITOV_NULL(ip); 3851 bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
3853 int error; 3852 int error;
3854 3853
3855 if (vp && VN_BAD(vp)) 3854 if (vp && VN_BAD(vp))
@@ -4116,10 +4115,10 @@ retry:
4116 * Issue the xfs_bmapi() call to allocate the blocks 4115 * Issue the xfs_bmapi() call to allocate the blocks
4117 */ 4116 */
4118 XFS_BMAP_INIT(&free_list, &firstfsb); 4117 XFS_BMAP_INIT(&free_list, &firstfsb);
4119 error = xfs_bmapi(tp, ip, startoffset_fsb, 4118 error = XFS_BMAPI(mp, tp, &ip->i_iocore, startoffset_fsb,
4120 allocatesize_fsb, bmapi_flag, 4119 allocatesize_fsb, bmapi_flag,
4121 &firstfsb, 0, imapp, &nimaps, 4120 &firstfsb, 0, imapp, &nimaps,
4122 &free_list); 4121 &free_list, NULL);
4123 if (error) { 4122 if (error) {
4124 goto error0; 4123 goto error0;
4125 } 4124 }
@@ -4199,8 +4198,8 @@ xfs_zero_remaining_bytes(
4199 for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { 4198 for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {
4200 offset_fsb = XFS_B_TO_FSBT(mp, offset); 4199 offset_fsb = XFS_B_TO_FSBT(mp, offset);
4201 nimap = 1; 4200 nimap = 1;
4202 error = xfs_bmapi(NULL, ip, offset_fsb, 1, 0, NULL, 0, &imap, 4201 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, offset_fsb, 1, 0,
4203 &nimap, NULL); 4202 NULL, 0, &imap, &nimap, NULL, NULL);
4204 if (error || nimap < 1) 4203 if (error || nimap < 1)
4205 break; 4204 break;
4206 ASSERT(imap.br_blockcount >= 1); 4205 ASSERT(imap.br_blockcount >= 1);
@@ -4259,7 +4258,7 @@ xfs_free_file_space(
4259 xfs_off_t len, 4258 xfs_off_t len,
4260 int attr_flags) 4259 int attr_flags)
4261{ 4260{
4262 vnode_t *vp; 4261 bhv_vnode_t *vp;
4263 int committed; 4262 int committed;
4264 int done; 4263 int done;
4265 xfs_off_t end_dmi_offset; 4264 xfs_off_t end_dmi_offset;
@@ -4308,7 +4307,6 @@ xfs_free_file_space(
4308 return error; 4307 return error;
4309 } 4308 }
4310 4309
4311 ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1);
4312 if (attr_flags & ATTR_NOLOCK) 4310 if (attr_flags & ATTR_NOLOCK)
4313 need_iolock = 0; 4311 need_iolock = 0;
4314 if (need_iolock) { 4312 if (need_iolock) {
@@ -4326,7 +4324,7 @@ xfs_free_file_space(
4326 if (VN_CACHED(vp) != 0) { 4324 if (VN_CACHED(vp) != 0) {
4327 xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, 4325 xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
4328 ctooff(offtoct(ioffset)), -1); 4326 ctooff(offtoct(ioffset)), -1);
4329 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(ioffset)), 4327 bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)),
4330 -1, FI_REMAPF_LOCKED); 4328 -1, FI_REMAPF_LOCKED);
4331 } 4329 }
4332 4330
@@ -4338,8 +4336,8 @@ xfs_free_file_space(
4338 */ 4336 */
4339 if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { 4337 if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {
4340 nimap = 1; 4338 nimap = 1;
4341 error = xfs_bmapi(NULL, ip, startoffset_fsb, 1, 0, NULL, 0, 4339 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, startoffset_fsb,
4342 &imap, &nimap, NULL); 4340 1, 0, NULL, 0, &imap, &nimap, NULL, NULL);
4343 if (error) 4341 if (error)
4344 goto out_unlock_iolock; 4342 goto out_unlock_iolock;
4345 ASSERT(nimap == 0 || nimap == 1); 4343 ASSERT(nimap == 0 || nimap == 1);
@@ -4353,8 +4351,8 @@ xfs_free_file_space(
4353 startoffset_fsb += mp->m_sb.sb_rextsize - mod; 4351 startoffset_fsb += mp->m_sb.sb_rextsize - mod;
4354 } 4352 }
4355 nimap = 1; 4353 nimap = 1;
4356 error = xfs_bmapi(NULL, ip, endoffset_fsb - 1, 1, 0, NULL, 0, 4354 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, endoffset_fsb - 1,
4357 &imap, &nimap, NULL); 4355 1, 0, NULL, 0, &imap, &nimap, NULL, NULL);
4358 if (error) 4356 if (error)
4359 goto out_unlock_iolock; 4357 goto out_unlock_iolock;
4360 ASSERT(nimap == 0 || nimap == 1); 4358 ASSERT(nimap == 0 || nimap == 1);
@@ -4426,9 +4424,9 @@ xfs_free_file_space(
4426 * issue the bunmapi() call to free the blocks 4424 * issue the bunmapi() call to free the blocks
4427 */ 4425 */
4428 XFS_BMAP_INIT(&free_list, &firstfsb); 4426 XFS_BMAP_INIT(&free_list, &firstfsb);
4429 error = xfs_bunmapi(tp, ip, startoffset_fsb, 4427 error = XFS_BUNMAPI(mp, tp, &ip->i_iocore, startoffset_fsb,
4430 endoffset_fsb - startoffset_fsb, 4428 endoffset_fsb - startoffset_fsb,
4431 0, 2, &firstfsb, &free_list, &done); 4429 0, 2, &firstfsb, &free_list, NULL, &done);
4432 if (error) { 4430 if (error) {
4433 goto error0; 4431 goto error0;
4434 } 4432 }
@@ -4488,8 +4486,8 @@ xfs_change_file_space(
4488 xfs_off_t startoffset; 4486 xfs_off_t startoffset;
4489 xfs_off_t llen; 4487 xfs_off_t llen;
4490 xfs_trans_t *tp; 4488 xfs_trans_t *tp;
4491 vattr_t va; 4489 bhv_vattr_t va;
4492 vnode_t *vp; 4490 bhv_vnode_t *vp;
4493 4491
4494 vp = BHV_TO_VNODE(bdp); 4492 vp = BHV_TO_VNODE(bdp);
4495 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 4493 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
@@ -4642,9 +4640,10 @@ xfs_change_file_space(
4642 return error; 4640 return error;
4643} 4641}
4644 4642
4645vnodeops_t xfs_vnodeops = { 4643bhv_vnodeops_t xfs_vnodeops = {
4646 BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS), 4644 BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS),
4647 .vop_open = xfs_open, 4645 .vop_open = xfs_open,
4646 .vop_close = xfs_close,
4648 .vop_read = xfs_read, 4647 .vop_read = xfs_read,
4649#ifdef HAVE_SENDFILE 4648#ifdef HAVE_SENDFILE
4650 .vop_sendfile = xfs_sendfile, 4649 .vop_sendfile = xfs_sendfile,
diff --git a/include/asm-alpha/vga.h b/include/asm-alpha/vga.h
index 8ca4f6b2da19..ed06f59b544d 100644
--- a/include/asm-alpha/vga.h
+++ b/include/asm-alpha/vga.h
@@ -46,6 +46,6 @@ extern void scr_memcpyw(u16 *d, const u16 *s, unsigned int count);
46#define vga_readb(a) readb((u8 __iomem *)(a)) 46#define vga_readb(a) readb((u8 __iomem *)(a))
47#define vga_writeb(v,a) writeb(v, (u8 __iomem *)(a)) 47#define vga_writeb(v,a) writeb(v, (u8 __iomem *)(a))
48 48
49#define VGA_MAP_MEM(x) ((unsigned long) ioremap(x, 0)) 49#define VGA_MAP_MEM(x,s) ((unsigned long) ioremap(x, s))
50 50
51#endif 51#endif
diff --git a/include/asm-arm/vga.h b/include/asm-arm/vga.h
index 926e5ee128e9..1e0b913c3d71 100644
--- a/include/asm-arm/vga.h
+++ b/include/asm-arm/vga.h
@@ -4,7 +4,7 @@
4#include <asm/hardware.h> 4#include <asm/hardware.h>
5#include <asm/io.h> 5#include <asm/io.h>
6 6
7#define VGA_MAP_MEM(x) (PCIMEM_BASE + (x)) 7#define VGA_MAP_MEM(x,s) (PCIMEM_BASE + (x))
8 8
9#define vga_readb(x) (*((volatile unsigned char *)x)) 9#define vga_readb(x) (*((volatile unsigned char *)x))
10#define vga_writeb(x,y) (*((volatile unsigned char *)y) = (x)) 10#define vga_writeb(x,y) (*((volatile unsigned char *)y) = (x))
diff --git a/include/asm-i386/vga.h b/include/asm-i386/vga.h
index ef0c0e50cc95..0ecf68ac03aa 100644
--- a/include/asm-i386/vga.h
+++ b/include/asm-i386/vga.h
@@ -12,7 +12,7 @@
12 * access the videoram directly without any black magic. 12 * access the videoram directly without any black magic.
13 */ 13 */
14 14
15#define VGA_MAP_MEM(x) (unsigned long)phys_to_virt(x) 15#define VGA_MAP_MEM(x,s) (unsigned long)phys_to_virt(x)
16 16
17#define vga_readb(x) (*(x)) 17#define vga_readb(x) (*(x))
18#define vga_writeb(x,y) (*(y) = (x)) 18#define vga_writeb(x,y) (*(y) = (x))
diff --git a/include/asm-ia64/vga.h b/include/asm-ia64/vga.h
index 091177cda223..02184ecd8208 100644
--- a/include/asm-ia64/vga.h
+++ b/include/asm-ia64/vga.h
@@ -17,7 +17,7 @@
17extern unsigned long vga_console_iobase; 17extern unsigned long vga_console_iobase;
18extern unsigned long vga_console_membase; 18extern unsigned long vga_console_membase;
19 19
20#define VGA_MAP_MEM(x) ((unsigned long) ioremap_nocache(vga_console_membase + (x), 0)) 20#define VGA_MAP_MEM(x,s) ((unsigned long) ioremap_nocache(vga_console_membase + (x), s))
21 21
22#define vga_readb(x) (*(x)) 22#define vga_readb(x) (*(x))
23#define vga_writeb(x,y) (*(y) = (x)) 23#define vga_writeb(x,y) (*(y) = (x))
diff --git a/include/asm-m32r/vga.h b/include/asm-m32r/vga.h
index d0f4b6eed7a3..533163447cc9 100644
--- a/include/asm-m32r/vga.h
+++ b/include/asm-m32r/vga.h
@@ -14,7 +14,7 @@
14 * access the videoram directly without any black magic. 14 * access the videoram directly without any black magic.
15 */ 15 */
16 16
17#define VGA_MAP_MEM(x) (unsigned long)phys_to_virt(x) 17#define VGA_MAP_MEM(x,s) (unsigned long)phys_to_virt(x)
18 18
19#define vga_readb(x) (*(x)) 19#define vga_readb(x) (*(x))
20#define vga_writeb(x,y) (*(y) = (x)) 20#define vga_writeb(x,y) (*(y) = (x))
diff --git a/include/asm-mips/vga.h b/include/asm-mips/vga.h
index 34755c0a6398..c1dd0b10bc27 100644
--- a/include/asm-mips/vga.h
+++ b/include/asm-mips/vga.h
@@ -13,7 +13,7 @@
13 * access the videoram directly without any black magic. 13 * access the videoram directly without any black magic.
14 */ 14 */
15 15
16#define VGA_MAP_MEM(x) (0xb0000000L + (unsigned long)(x)) 16#define VGA_MAP_MEM(x,s) (0xb0000000L + (unsigned long)(x))
17 17
18#define vga_readb(x) (*(x)) 18#define vga_readb(x) (*(x))
19#define vga_writeb(x,y) (*(y) = (x)) 19#define vga_writeb(x,y) (*(y) = (x))
diff --git a/include/asm-powerpc/vga.h b/include/asm-powerpc/vga.h
index eadaf2f3d032..a2eac409c1ec 100644
--- a/include/asm-powerpc/vga.h
+++ b/include/asm-powerpc/vga.h
@@ -41,9 +41,9 @@ static inline u16 scr_readw(volatile const u16 *addr)
41extern unsigned long vgacon_remap_base; 41extern unsigned long vgacon_remap_base;
42 42
43#ifdef __powerpc64__ 43#ifdef __powerpc64__
44#define VGA_MAP_MEM(x) ((unsigned long) ioremap((x), 0)) 44#define VGA_MAP_MEM(x,s) ((unsigned long) ioremap((x), s))
45#else 45#else
46#define VGA_MAP_MEM(x) (x + vgacon_remap_base) 46#define VGA_MAP_MEM(x,s) (x + vgacon_remap_base)
47#endif 47#endif
48 48
49#define vga_readb(x) (*(x)) 49#define vga_readb(x) (*(x))
diff --git a/include/asm-sparc64/vga.h b/include/asm-sparc64/vga.h
index 9c57eb363b40..c69d5b2ba19a 100644
--- a/include/asm-sparc64/vga.h
+++ b/include/asm-sparc64/vga.h
@@ -28,6 +28,6 @@ static inline u16 scr_readw(const u16 *addr)
28 return *addr; 28 return *addr;
29} 29}
30 30
31#define VGA_MAP_MEM(x) (x) 31#define VGA_MAP_MEM(x,s) (x)
32 32
33#endif 33#endif
diff --git a/include/asm-x86_64/vga.h b/include/asm-x86_64/vga.h
index ef0c0e50cc95..0ecf68ac03aa 100644
--- a/include/asm-x86_64/vga.h
+++ b/include/asm-x86_64/vga.h
@@ -12,7 +12,7 @@
12 * access the videoram directly without any black magic. 12 * access the videoram directly without any black magic.
13 */ 13 */
14 14
15#define VGA_MAP_MEM(x) (unsigned long)phys_to_virt(x) 15#define VGA_MAP_MEM(x,s) (unsigned long)phys_to_virt(x)
16 16
17#define vga_readb(x) (*(x)) 17#define vga_readb(x) (*(x))
18#define vga_writeb(x,y) (*(y) = (x)) 18#define vga_writeb(x,y) (*(y) = (x))
diff --git a/include/asm-xtensa/vga.h b/include/asm-xtensa/vga.h
index 23d82f6acb57..1fd8cab3a297 100644
--- a/include/asm-xtensa/vga.h
+++ b/include/asm-xtensa/vga.h
@@ -11,7 +11,7 @@
11#ifndef _XTENSA_VGA_H 11#ifndef _XTENSA_VGA_H
12#define _XTENSA_VGA_H 12#define _XTENSA_VGA_H
13 13
14#define VGA_MAP_MEM(x) (unsigned long)phys_to_virt(x) 14#define VGA_MAP_MEM(x,s) (unsigned long)phys_to_virt(x)
15 15
16#define vga_readb(x) (*(x)) 16#define vga_readb(x) (*(x))
17#define vga_writeb(x,y) (*(y) = (x)) 17#define vga_writeb(x,y) (*(y) = (x))
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 836325ee0931..46d0e079735d 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -217,7 +217,7 @@ extern struct dentry * d_alloc_anon(struct inode *);
217extern struct dentry * d_splice_alias(struct inode *, struct dentry *); 217extern struct dentry * d_splice_alias(struct inode *, struct dentry *);
218extern void shrink_dcache_sb(struct super_block *); 218extern void shrink_dcache_sb(struct super_block *);
219extern void shrink_dcache_parent(struct dentry *); 219extern void shrink_dcache_parent(struct dentry *);
220extern void shrink_dcache_anon(struct hlist_head *); 220extern void shrink_dcache_anon(struct super_block *);
221extern int d_invalidate(struct dentry *); 221extern int d_invalidate(struct dentry *);
222 222
223/* only used at mount-time */ 223/* only used at mount-time */
diff --git a/include/linux/device.h b/include/linux/device.h
index b2e5da2b637b..1e5f30da98bc 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -60,11 +60,6 @@ extern void bus_unregister(struct bus_type * bus);
60 60
61extern void bus_rescan_devices(struct bus_type * bus); 61extern void bus_rescan_devices(struct bus_type * bus);
62 62
63extern struct bus_type * get_bus(struct bus_type * bus);
64extern void put_bus(struct bus_type * bus);
65
66extern struct bus_type * find_bus(char * name);
67
68/* iterator helpers for buses */ 63/* iterator helpers for buses */
69 64
70int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, 65int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data,
@@ -147,6 +142,7 @@ struct class {
147 142
148 struct subsystem subsys; 143 struct subsystem subsys;
149 struct list_head children; 144 struct list_head children;
145 struct list_head devices;
150 struct list_head interfaces; 146 struct list_head interfaces;
151 struct semaphore sem; /* locks both the children and interfaces lists */ 147 struct semaphore sem; /* locks both the children and interfaces lists */
152 148
@@ -163,9 +159,6 @@ struct class {
163extern int class_register(struct class *); 159extern int class_register(struct class *);
164extern void class_unregister(struct class *); 160extern void class_unregister(struct class *);
165 161
166extern struct class * class_get(struct class *);
167extern void class_put(struct class *);
168
169 162
170struct class_attribute { 163struct class_attribute {
171 struct attribute attr; 164 struct attribute attr;
@@ -313,6 +306,7 @@ struct device {
313 struct kobject kobj; 306 struct kobject kobj;
314 char bus_id[BUS_ID_SIZE]; /* position on parent bus */ 307 char bus_id[BUS_ID_SIZE]; /* position on parent bus */
315 struct device_attribute uevent_attr; 308 struct device_attribute uevent_attr;
309 struct device_attribute *devt_attr;
316 310
317 struct semaphore sem; /* semaphore to synchronize calls to 311 struct semaphore sem; /* semaphore to synchronize calls to
318 * its driver. 312 * its driver.
@@ -340,6 +334,11 @@ struct device {
340 struct dma_coherent_mem *dma_mem; /* internal for coherent mem 334 struct dma_coherent_mem *dma_mem; /* internal for coherent mem
341 override */ 335 override */
342 336
337 /* class_device migration path */
338 struct list_head node;
339 struct class *class; /* optional*/
340 dev_t devt; /* dev_t, creates the sysfs "dev" */
341
343 void (*release)(struct device * dev); 342 void (*release)(struct device * dev);
344}; 343};
345 344
@@ -381,6 +380,13 @@ extern int device_attach(struct device * dev);
381extern void driver_attach(struct device_driver * drv); 380extern void driver_attach(struct device_driver * drv);
382extern void device_reprobe(struct device *dev); 381extern void device_reprobe(struct device *dev);
383 382
383/*
384 * Easy functions for dynamically creating devices on the fly
385 */
386extern struct device *device_create(struct class *cls, struct device *parent,
387 dev_t devt, char *fmt, ...)
388 __attribute__((format(printf,4,5)));
389extern void device_destroy(struct class *cls, dev_t devt);
384 390
385/* 391/*
386 * Platform "fixup" functions - allow the platform to have their say 392 * Platform "fixup" functions - allow the platform to have their say
@@ -410,8 +416,9 @@ extern int firmware_register(struct subsystem *);
410extern void firmware_unregister(struct subsystem *); 416extern void firmware_unregister(struct subsystem *);
411 417
412/* debugging and troubleshooting/diagnostic helpers. */ 418/* debugging and troubleshooting/diagnostic helpers. */
419extern const char *dev_driver_string(struct device *dev);
413#define dev_printk(level, dev, format, arg...) \ 420#define dev_printk(level, dev, format, arg...) \
414 printk(level "%s %s: " format , (dev)->driver ? (dev)->driver->name : "" , (dev)->bus_id , ## arg) 421 printk(level "%s %s: " format , dev_driver_string(dev) , (dev)->bus_id , ## arg)
415 422
416#ifdef DEBUG 423#ifdef DEBUG
417#define dev_dbg(dev, format, arg...) \ 424#define dev_dbg(dev, format, arg...) \
diff --git a/include/linux/fs.h b/include/linux/fs.h
index ecc8c2c3d8ca..73c7d6f04b31 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -782,7 +782,6 @@ extern int setlease(struct file *, long, struct file_lock **);
782extern int lease_modify(struct file_lock **, int); 782extern int lease_modify(struct file_lock **, int);
783extern int lock_may_read(struct inode *, loff_t start, unsigned long count); 783extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
784extern int lock_may_write(struct inode *, loff_t start, unsigned long count); 784extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
785extern void steal_locks(fl_owner_t from);
786 785
787struct fasync_struct { 786struct fasync_struct {
788 int magic; 787 int magic;
diff --git a/include/linux/isa.h b/include/linux/isa.h
new file mode 100644
index 000000000000..1b855335cb11
--- /dev/null
+++ b/include/linux/isa.h
@@ -0,0 +1,28 @@
1/*
2 * ISA bus.
3 */
4
5#ifndef __LINUX_ISA_H
6#define __LINUX_ISA_H
7
8#include <linux/device.h>
9#include <linux/kernel.h>
10
11struct isa_driver {
12 int (*match)(struct device *, unsigned int);
13 int (*probe)(struct device *, unsigned int);
14 int (*remove)(struct device *, unsigned int);
15 void (*shutdown)(struct device *, unsigned int);
16 int (*suspend)(struct device *, unsigned int, pm_message_t);
17 int (*resume)(struct device *, unsigned int);
18
19 struct device_driver driver;
20 struct device *devices;
21};
22
23#define to_isa_driver(x) container_of((x), struct isa_driver, driver)
24
25int isa_register_driver(struct isa_driver *, unsigned int);
26void isa_unregister_driver(struct isa_driver *);
27
28#endif /* __LINUX_ISA_H */
diff --git a/include/linux/key.h b/include/linux/key.h
index cbf464ad9589..e81ebf910d0b 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -205,6 +205,11 @@ struct key_type {
205 /* match a key against a description */ 205 /* match a key against a description */
206 int (*match)(const struct key *key, const void *desc); 206 int (*match)(const struct key *key, const void *desc);
207 207
208 /* clear some of the data from a key on revokation (optional)
209 * - the key's semaphore will be write-locked by the caller
210 */
211 void (*revoke)(struct key *key);
212
208 /* clear the data from a key (optional) */ 213 /* clear the data from a key (optional) */
209 void (*destroy)(struct key *key); 214 void (*destroy)(struct key *key);
210 215
@@ -241,8 +246,9 @@ extern void unregister_key_type(struct key_type *ktype);
241 246
242extern struct key *key_alloc(struct key_type *type, 247extern struct key *key_alloc(struct key_type *type,
243 const char *desc, 248 const char *desc,
244 uid_t uid, gid_t gid, key_perm_t perm, 249 uid_t uid, gid_t gid,
245 int not_in_quota); 250 struct task_struct *ctx,
251 key_perm_t perm, int not_in_quota);
246extern int key_payload_reserve(struct key *key, size_t datalen); 252extern int key_payload_reserve(struct key *key, size_t datalen);
247extern int key_instantiate_and_link(struct key *key, 253extern int key_instantiate_and_link(struct key *key,
248 const void *data, 254 const void *data,
@@ -292,7 +298,9 @@ extern int key_unlink(struct key *keyring,
292 struct key *key); 298 struct key *key);
293 299
294extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 300extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
295 int not_in_quota, struct key *dest); 301 struct task_struct *ctx,
302 int not_in_quota,
303 struct key *dest);
296 304
297extern int keyring_clear(struct key *keyring); 305extern int keyring_clear(struct key *keyring);
298 306
@@ -313,7 +321,8 @@ extern void keyring_replace_payload(struct key *key, void *replacement);
313 * the userspace interface 321 * the userspace interface
314 */ 322 */
315extern struct key root_user_keyring, root_session_keyring; 323extern struct key root_user_keyring, root_session_keyring;
316extern int alloc_uid_keyring(struct user_struct *user); 324extern int alloc_uid_keyring(struct user_struct *user,
325 struct task_struct *ctx);
317extern void switch_uid_keyring(struct user_struct *new_user); 326extern void switch_uid_keyring(struct user_struct *new_user);
318extern int copy_keys(unsigned long clone_flags, struct task_struct *tsk); 327extern int copy_keys(unsigned long clone_flags, struct task_struct *tsk);
319extern int copy_thread_group_keys(struct task_struct *tsk); 328extern int copy_thread_group_keys(struct task_struct *tsk);
@@ -342,7 +351,7 @@ extern void key_init(void);
342#define make_key_ref(k) ({ NULL; }) 351#define make_key_ref(k) ({ NULL; })
343#define key_ref_to_ptr(k) ({ NULL; }) 352#define key_ref_to_ptr(k) ({ NULL; })
344#define is_key_possessed(k) 0 353#define is_key_possessed(k) 0
345#define alloc_uid_keyring(u) 0 354#define alloc_uid_keyring(u,c) 0
346#define switch_uid_keyring(u) do { } while(0) 355#define switch_uid_keyring(u) do { } while(0)
347#define __install_session_keyring(t, k) ({ NULL; }) 356#define __install_session_keyring(t, k) ({ NULL; })
348#define copy_keys(f,t) 0 357#define copy_keys(f,t) 0
@@ -355,6 +364,10 @@ extern void key_init(void);
355#define key_fsgid_changed(t) do { } while(0) 364#define key_fsgid_changed(t) do { } while(0)
356#define key_init() do { } while(0) 365#define key_init() do { } while(0)
357 366
367/* Initial keyrings */
368extern struct key root_user_keyring;
369extern struct key root_session_keyring;
370
358#endif /* CONFIG_KEYS */ 371#endif /* CONFIG_KEYS */
359#endif /* __KERNEL__ */ 372#endif /* __KERNEL__ */
360#endif /* _LINUX_KEY_H */ 373#endif /* _LINUX_KEY_H */
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index c187c53cecd0..2d229327959e 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -190,6 +190,8 @@ struct subsystem _varname##_subsys = { \
190 190
191/* The global /sys/kernel/ subsystem for people to chain off of */ 191/* The global /sys/kernel/ subsystem for people to chain off of */
192extern struct subsystem kernel_subsys; 192extern struct subsystem kernel_subsys;
193/* The global /sys/hypervisor/ subsystem */
194extern struct subsystem hypervisor_subsys;
193 195
194/** 196/**
195 * Helpers for setting the kset of registered objects. 197 * Helpers for setting the kset of registered objects.
diff --git a/include/linux/security.h b/include/linux/security.h
index 4dfb1b84a9b3..47722d355532 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1313,7 +1313,7 @@ struct security_operations {
1313 1313
1314 /* key management security hooks */ 1314 /* key management security hooks */
1315#ifdef CONFIG_KEYS 1315#ifdef CONFIG_KEYS
1316 int (*key_alloc)(struct key *key); 1316 int (*key_alloc)(struct key *key, struct task_struct *tsk);
1317 void (*key_free)(struct key *key); 1317 void (*key_free)(struct key *key);
1318 int (*key_permission)(key_ref_t key_ref, 1318 int (*key_permission)(key_ref_t key_ref,
1319 struct task_struct *context, 1319 struct task_struct *context,
@@ -3008,9 +3008,10 @@ static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid
3008 3008
3009#ifdef CONFIG_KEYS 3009#ifdef CONFIG_KEYS
3010#ifdef CONFIG_SECURITY 3010#ifdef CONFIG_SECURITY
3011static inline int security_key_alloc(struct key *key) 3011static inline int security_key_alloc(struct key *key,
3012 struct task_struct *tsk)
3012{ 3013{
3013 return security_ops->key_alloc(key); 3014 return security_ops->key_alloc(key, tsk);
3014} 3015}
3015 3016
3016static inline void security_key_free(struct key *key) 3017static inline void security_key_free(struct key *key)
@@ -3027,7 +3028,8 @@ static inline int security_key_permission(key_ref_t key_ref,
3027 3028
3028#else 3029#else
3029 3030
3030static inline int security_key_alloc(struct key *key) 3031static inline int security_key_alloc(struct key *key,
3032 struct task_struct *tsk)
3031{ 3033{
3032 return 0; 3034 return 0;
3033} 3035}
diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h
index 2a4b432e1176..166a2e58c287 100644
--- a/include/linux/sysdev.h
+++ b/include/linux/sysdev.h
@@ -37,11 +37,27 @@ struct sysdev_class {
37 struct kset kset; 37 struct kset kset;
38}; 38};
39 39
40struct sysdev_class_attribute {
41 struct attribute attr;
42 ssize_t (*show)(struct sysdev_class *, char *);
43 ssize_t (*store)(struct sysdev_class *, const char *, size_t);
44};
45
46#define SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) \
47struct sysdev_class_attribute attr_##_name = { \
48 .attr = {.name = __stringify(_name), .mode = _mode }, \
49 .show = _show, \
50 .store = _store, \
51};
52
40 53
41extern int sysdev_class_register(struct sysdev_class *); 54extern int sysdev_class_register(struct sysdev_class *);
42extern void sysdev_class_unregister(struct sysdev_class *); 55extern void sysdev_class_unregister(struct sysdev_class *);
43 56
44 57extern int sysdev_class_create_file(struct sysdev_class *,
58 struct sysdev_class_attribute *);
59extern void sysdev_class_remove_file(struct sysdev_class *,
60 struct sysdev_class_attribute *);
45/** 61/**
46 * Auxillary system device drivers. 62 * Auxillary system device drivers.
47 */ 63 */
diff --git a/include/linux/tty.h b/include/linux/tty.h
index e898eeb94166..cb35ca50a0a6 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -290,7 +290,9 @@ extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc);
290extern int tty_unregister_ldisc(int disc); 290extern int tty_unregister_ldisc(int disc);
291extern int tty_register_driver(struct tty_driver *driver); 291extern int tty_register_driver(struct tty_driver *driver);
292extern int tty_unregister_driver(struct tty_driver *driver); 292extern int tty_unregister_driver(struct tty_driver *driver);
293extern void tty_register_device(struct tty_driver *driver, unsigned index, struct device *dev); 293extern struct class_device *tty_register_device(struct tty_driver *driver,
294 unsigned index,
295 struct device *dev);
294extern void tty_unregister_device(struct tty_driver *driver, unsigned index); 296extern void tty_unregister_device(struct tty_driver *driver, unsigned index);
295extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, 297extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp,
296 int buflen); 298 int buflen);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 1f492c0c7047..8dead32e7ebf 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -40,6 +40,8 @@ struct usb_driver;
40 * Devices may also have class-specific or vendor-specific descriptors. 40 * Devices may also have class-specific or vendor-specific descriptors.
41 */ 41 */
42 42
43struct ep_device;
44
43/** 45/**
44 * struct usb_host_endpoint - host-side endpoint descriptor and queue 46 * struct usb_host_endpoint - host-side endpoint descriptor and queue
45 * @desc: descriptor for this endpoint, wMaxPacketSize in native byteorder 47 * @desc: descriptor for this endpoint, wMaxPacketSize in native byteorder
@@ -57,7 +59,7 @@ struct usb_host_endpoint {
57 struct usb_endpoint_descriptor desc; 59 struct usb_endpoint_descriptor desc;
58 struct list_head urb_list; 60 struct list_head urb_list;
59 void *hcpriv; 61 void *hcpriv;
60 struct kobject *kobj; /* For sysfs info */ 62 struct ep_device *ep_dev; /* For sysfs info */
61 63
62 unsigned char *extra; /* Extra descriptors */ 64 unsigned char *extra; /* Extra descriptors */
63 int extralen; 65 int extralen;
@@ -101,7 +103,8 @@ enum usb_interface_condition {
101 * @condition: binding state of the interface: not bound, binding 103 * @condition: binding state of the interface: not bound, binding
102 * (in probe()), bound to a driver, or unbinding (in disconnect()) 104 * (in probe()), bound to a driver, or unbinding (in disconnect())
103 * @dev: driver model's view of this device 105 * @dev: driver model's view of this device
104 * @class_dev: driver model's class view of this device. 106 * @usb_dev: if an interface is bound to the USB major, this will point
107 * to the sysfs representation for that device.
105 * 108 *
106 * USB device drivers attach to interfaces on a physical device. Each 109 * USB device drivers attach to interfaces on a physical device. Each
107 * interface encapsulates a single high level function, such as feeding 110 * interface encapsulates a single high level function, such as feeding
@@ -141,7 +144,7 @@ struct usb_interface {
141 * bound to */ 144 * bound to */
142 enum usb_interface_condition condition; /* state of binding */ 145 enum usb_interface_condition condition; /* state of binding */
143 struct device dev; /* interface specific device info */ 146 struct device dev; /* interface specific device info */
144 struct class_device *class_dev; 147 struct device *usb_dev; /* pointer to the usb class's device, if any */
145}; 148};
146#define to_usb_interface(d) container_of(d, struct usb_interface, dev) 149#define to_usb_interface(d) container_of(d, struct usb_interface, dev)
147#define interface_to_usbdev(intf) \ 150#define interface_to_usbdev(intf) \
@@ -358,7 +361,7 @@ struct usb_device {
358 char *serial; /* iSerialNumber string, if present */ 361 char *serial; /* iSerialNumber string, if present */
359 362
360 struct list_head filelist; 363 struct list_head filelist;
361 struct class_device *class_dev; 364 struct device *usbfs_dev;
362 struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */ 365 struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */
363 366
364 /* 367 /*
@@ -386,6 +389,8 @@ extern int usb_lock_device_for_reset(struct usb_device *udev,
386 389
387/* USB port reset for device reinitialization */ 390/* USB port reset for device reinitialization */
388extern int usb_reset_device(struct usb_device *dev); 391extern int usb_reset_device(struct usb_device *dev);
392extern int usb_reset_composite_device(struct usb_device *dev,
393 struct usb_interface *iface);
389 394
390extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id); 395extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id);
391 396
@@ -554,6 +559,10 @@ struct usb_dynids {
554 * do (or don't) show up otherwise in the filesystem. 559 * do (or don't) show up otherwise in the filesystem.
555 * @suspend: Called when the device is going to be suspended by the system. 560 * @suspend: Called when the device is going to be suspended by the system.
556 * @resume: Called when the device is being resumed by the system. 561 * @resume: Called when the device is being resumed by the system.
562 * @pre_reset: Called by usb_reset_composite_device() when the device
563 * is about to be reset.
564 * @post_reset: Called by usb_reset_composite_device() after the device
565 * has been reset.
557 * @id_table: USB drivers use ID table to support hotplugging. 566 * @id_table: USB drivers use ID table to support hotplugging.
558 * Export this with MODULE_DEVICE_TABLE(usb,...). This must be set 567 * Export this with MODULE_DEVICE_TABLE(usb,...). This must be set
559 * or your driver's probe function will never get called. 568 * or your driver's probe function will never get called.
@@ -592,6 +601,9 @@ struct usb_driver {
592 int (*suspend) (struct usb_interface *intf, pm_message_t message); 601 int (*suspend) (struct usb_interface *intf, pm_message_t message);
593 int (*resume) (struct usb_interface *intf); 602 int (*resume) (struct usb_interface *intf);
594 603
604 void (*pre_reset) (struct usb_interface *intf);
605 void (*post_reset) (struct usb_interface *intf);
606
595 const struct usb_device_id *id_table; 607 const struct usb_device_id *id_table;
596 608
597 struct usb_dynids dynids; 609 struct usb_dynids dynids;
@@ -1008,6 +1020,8 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe,
1008extern int usb_control_msg(struct usb_device *dev, unsigned int pipe, 1020extern int usb_control_msg(struct usb_device *dev, unsigned int pipe,
1009 __u8 request, __u8 requesttype, __u16 value, __u16 index, 1021 __u8 request, __u8 requesttype, __u16 value, __u16 index,
1010 void *data, __u16 size, int timeout); 1022 void *data, __u16 size, int timeout);
1023extern int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,
1024 void *data, int len, int *actual_length, int timeout);
1011extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, 1025extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
1012 void *data, int len, int *actual_length, 1026 void *data, int len, int *actual_length,
1013 int timeout); 1027 int timeout);
diff --git a/include/linux/usb_cdc.h b/include/linux/usb/cdc.h
index ba617c372455..ba617c372455 100644
--- a/include/linux/usb_cdc.h
+++ b/include/linux/usb/cdc.h
diff --git a/include/linux/usb_input.h b/include/linux/usb/input.h
index 716e0cc16043..716e0cc16043 100644
--- a/include/linux/usb_input.h
+++ b/include/linux/usb/input.h
diff --git a/include/linux/usb_isp116x.h b/include/linux/usb/isp116x.h
index 436dd8a2b64a..436dd8a2b64a 100644
--- a/include/linux/usb_isp116x.h
+++ b/include/linux/usb/isp116x.h
diff --git a/include/linux/usb_sl811.h b/include/linux/usb/sl811.h
index 4f2d012d7309..397ee3b3d7f3 100644
--- a/include/linux/usb_sl811.h
+++ b/include/linux/usb/sl811.h
@@ -14,13 +14,13 @@ struct sl811_platform_data {
14 u8 power; 14 u8 power;
15 15
16 /* sl811 relies on an external source of VBUS current */ 16 /* sl811 relies on an external source of VBUS current */
17 void (*port_power)(struct device *dev, int is_on); 17 void (*port_power)(struct device *dev, int is_on);
18 18
19 /* pulse sl811 nRST (probably with a GPIO) */ 19 /* pulse sl811 nRST (probably with a GPIO) */
20 void (*reset)(struct device *dev); 20 void (*reset)(struct device *dev);
21 21
22 // some boards need something like these: 22 // some boards need something like these:
23 // int (*check_overcurrent)(struct device *dev); 23 // int (*check_overcurrent)(struct device *dev);
24 // void (*clock_enable)(struct device *dev, int is_on); 24 // void (*clock_enable)(struct device *dev, int is_on);
25}; 25};
26 26
diff --git a/include/linux/zconf.h b/include/linux/zconf.h
index f1cfd66b9554..0beb75e38caa 100644
--- a/include/linux/zconf.h
+++ b/include/linux/zconf.h
@@ -35,6 +35,18 @@
35# define MAX_WBITS 15 /* 32K LZ77 window */ 35# define MAX_WBITS 15 /* 32K LZ77 window */
36#endif 36#endif
37 37
38/* default windowBits for decompression. MAX_WBITS is for compression only */
39#ifndef DEF_WBITS
40# define DEF_WBITS MAX_WBITS
41#endif
42
43/* default memLevel */
44#if MAX_MEM_LEVEL >= 8
45# define DEF_MEM_LEVEL 8
46#else
47# define DEF_MEM_LEVEL MAX_MEM_LEVEL
48#endif
49
38 /* Type declarations */ 50 /* Type declarations */
39 51
40typedef unsigned char Byte; /* 8 bits */ 52typedef unsigned char Byte; /* 8 bits */
diff --git a/include/linux/zlib.h b/include/linux/zlib.h
index 4fa32f0d4df8..9e3192a7dc6f 100644
--- a/include/linux/zlib.h
+++ b/include/linux/zlib.h
@@ -1,7 +1,6 @@
1/* zlib.h -- interface of the 'zlib' general purpose compression library 1/* zlib.h -- interface of the 'zlib' general purpose compression library
2 version 1.1.3, July 9th, 1998
3 2
4 Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler 3 Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
5 4
6 This software is provided 'as-is', without any express or implied 5 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages 6 warranty. In no event will the authors be held liable for any damages
@@ -24,7 +23,7 @@
24 23
25 24
26 The data format used by the zlib library is described by RFCs (Request for 25 The data format used by the zlib library is described by RFCs (Request for
27 Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt 26 Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
28 (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). 27 (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
29*/ 28*/
30 29
@@ -33,7 +32,22 @@
33 32
34#include <linux/zconf.h> 33#include <linux/zconf.h>
35 34
36#define ZLIB_VERSION "1.1.3" 35/* zlib deflate based on ZLIB_VERSION "1.1.3" */
36/* zlib inflate based on ZLIB_VERSION "1.2.3" */
37
38/*
39 This is a modified version of zlib for use inside the Linux kernel.
40 The main changes are to perform all memory allocation in advance.
41
42 Inflation Changes:
43 * Z_PACKET_FLUSH is added and used by ppp_deflate. Before returning
44 this checks there is no more input data available and the next data
45 is a STORED block. It also resets the mode to be read for the next
46 data, all as per PPP requirements.
47 * Addition of zlib_inflateIncomp which copies incompressible data into
48 the history window and adjusts the accoutning without calling
49 zlib_inflate itself to inflate the data.
50*/
37 51
38/* 52/*
39 The 'zlib' compression library provides in-memory compression and 53 The 'zlib' compression library provides in-memory compression and
@@ -48,9 +62,18 @@
48 application must provide more input and/or consume the output 62 application must provide more input and/or consume the output
49 (providing more output space) before each call. 63 (providing more output space) before each call.
50 64
65 The compressed data format used by default by the in-memory functions is
66 the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
67 around a deflate stream, which is itself documented in RFC 1951.
68
51 The library also supports reading and writing files in gzip (.gz) format 69 The library also supports reading and writing files in gzip (.gz) format
52 with an interface similar to that of stdio. 70 with an interface similar to that of stdio.
53 71
72 The zlib format was designed to be compact and fast for use in memory
73 and on communications channels. The gzip format was designed for single-
74 file compression on file systems, has a larger header than zlib to maintain
75 directory information, and uses a different, slower check method than zlib.
76
54 The library does not install any signal handler. The decoder checks 77 The library does not install any signal handler. The decoder checks
55 the consistency of the compressed data, so the library should never 78 the consistency of the compressed data, so the library should never
56 crash even in case of corrupted input. 79 crash even in case of corrupted input.
@@ -119,7 +142,8 @@ typedef z_stream *z_streamp;
119#define Z_SYNC_FLUSH 3 142#define Z_SYNC_FLUSH 3
120#define Z_FULL_FLUSH 4 143#define Z_FULL_FLUSH 4
121#define Z_FINISH 5 144#define Z_FINISH 5
122/* Allowed flush values; see deflate() below for details */ 145#define Z_BLOCK 6 /* Only for inflate at present */
146/* Allowed flush values; see deflate() and inflate() below for details */
123 147
124#define Z_OK 0 148#define Z_OK 0
125#define Z_STREAM_END 1 149#define Z_STREAM_END 1
@@ -155,13 +179,6 @@ typedef z_stream *z_streamp;
155 179
156 /* basic functions */ 180 /* basic functions */
157 181
158extern const char * zlib_zlibVersion (void);
159/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
160 If the first character differs, the library code actually used is
161 not compatible with the zlib.h header file used by the application.
162 This check is automatically made by deflateInit and inflateInit.
163 */
164
165extern int zlib_deflate_workspacesize (void); 182extern int zlib_deflate_workspacesize (void);
166/* 183/*
167 Returns the number of bytes that needs to be allocated for a per- 184 Returns the number of bytes that needs to be allocated for a per-
@@ -315,9 +332,9 @@ extern int zlib_inflateInit (z_streamp strm);
315extern int zlib_inflate (z_streamp strm, int flush); 332extern int zlib_inflate (z_streamp strm, int flush);
316/* 333/*
317 inflate decompresses as much data as possible, and stops when the input 334 inflate decompresses as much data as possible, and stops when the input
318 buffer becomes empty or the output buffer becomes full. It may some 335 buffer becomes empty or the output buffer becomes full. It may introduce
319 introduce some output latency (reading input without producing any output) 336 some output latency (reading input without producing any output) except when
320 except when forced to flush. 337 forced to flush.
321 338
322 The detailed semantics are as follows. inflate performs one or both of the 339 The detailed semantics are as follows. inflate performs one or both of the
323 following actions: 340 following actions:
@@ -341,11 +358,26 @@ extern int zlib_inflate (z_streamp strm, int flush);
341 must be called again after making room in the output buffer because there 358 must be called again after making room in the output buffer because there
342 might be more output pending. 359 might be more output pending.
343 360
344 If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much 361 The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
345 output as possible to the output buffer. The flushing behavior of inflate is 362 Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
346 not specified for values of the flush parameter other than Z_SYNC_FLUSH 363 output as possible to the output buffer. Z_BLOCK requests that inflate() stop
347 and Z_FINISH, but the current implementation actually flushes as much output 364 if and when it gets to the next deflate block boundary. When decoding the
348 as possible anyway. 365 zlib or gzip format, this will cause inflate() to return immediately after
366 the header and before the first block. When doing a raw inflate, inflate()
367 will go ahead and process the first block, and will return when it gets to
368 the end of that block, or when it runs out of data.
369
370 The Z_BLOCK option assists in appending to or combining deflate streams.
371 Also to assist in this, on return inflate() will set strm->data_type to the
372 number of unused bits in the last byte taken from strm->next_in, plus 64
373 if inflate() is currently decoding the last block in the deflate stream,
374 plus 128 if inflate() returned immediately after decoding an end-of-block
375 code or decoding the complete header up to just before the first byte of the
376 deflate stream. The end-of-block will not be indicated until all of the
377 uncompressed data from that block has been written to strm->next_out. The
378 number of unused bits may in general be greater than seven, except when
379 bit 7 of data_type is set, in which case the number of unused bits will be
380 less than eight.
349 381
350 inflate() should normally be called until it returns Z_STREAM_END or an 382 inflate() should normally be called until it returns Z_STREAM_END or an
351 error. However if all decompression is to be performed in a single step 383 error. However if all decompression is to be performed in a single step
@@ -355,29 +387,44 @@ extern int zlib_inflate (z_streamp strm, int flush);
355 uncompressed data. (The size of the uncompressed data may have been saved 387 uncompressed data. (The size of the uncompressed data may have been saved
356 by the compressor for this purpose.) The next operation on this stream must 388 by the compressor for this purpose.) The next operation on this stream must
357 be inflateEnd to deallocate the decompression state. The use of Z_FINISH 389 be inflateEnd to deallocate the decompression state. The use of Z_FINISH
358 is never required, but can be used to inform inflate that a faster routine 390 is never required, but can be used to inform inflate that a faster approach
359 may be used for the single inflate() call. 391 may be used for the single inflate() call.
360 392
361 If a preset dictionary is needed at this point (see inflateSetDictionary 393 In this implementation, inflate() always flushes as much output as
362 below), inflate sets strm-adler to the adler32 checksum of the 394 possible to the output buffer, and always uses the faster approach on the
363 dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise 395 first call. So the only effect of the flush parameter in this implementation
364 it sets strm->adler to the adler32 checksum of all output produced 396 is on the return value of inflate(), as noted below, or when it returns early
365 so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or 397 because Z_BLOCK is used.
366 an error code as described below. At the end of the stream, inflate() 398
367 checks that its computed adler32 checksum is equal to that saved by the 399 If a preset dictionary is needed after this call (see inflateSetDictionary
368 compressor and returns Z_STREAM_END only if the checksum is correct. 400 below), inflate sets strm->adler to the adler32 checksum of the dictionary
401 chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
402 strm->adler to the adler32 checksum of all output produced so far (that is,
403 total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
404 below. At the end of the stream, inflate() checks that its computed adler32
405 checksum is equal to that saved by the compressor and returns Z_STREAM_END
406 only if the checksum is correct.
407
408 inflate() will decompress and check either zlib-wrapped or gzip-wrapped
409 deflate data. The header type is detected automatically. Any information
410 contained in the gzip header is not retained, so applications that need that
411 information should instead use raw inflate, see inflateInit2() below, or
412 inflateBack() and perform their own processing of the gzip header and
413 trailer.
369 414
370 inflate() returns Z_OK if some progress has been made (more input processed 415 inflate() returns Z_OK if some progress has been made (more input processed
371 or more output produced), Z_STREAM_END if the end of the compressed data has 416 or more output produced), Z_STREAM_END if the end of the compressed data has
372 been reached and all uncompressed output has been produced, Z_NEED_DICT if a 417 been reached and all uncompressed output has been produced, Z_NEED_DICT if a
373 preset dictionary is needed at this point, Z_DATA_ERROR if the input data was 418 preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
374 corrupted (input stream not conforming to the zlib format or incorrect 419 corrupted (input stream not conforming to the zlib format or incorrect check
375 adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent 420 value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
376 (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not 421 if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
377 enough memory, Z_BUF_ERROR if no progress is possible or if there was not 422 Z_BUF_ERROR if no progress is possible or if there was not enough room in the
378 enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR 423 output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
379 case, the application may then call inflateSync to look for a good 424 inflate() can be called again with more input and more output space to
380 compression block. 425 continue decompressing. If Z_DATA_ERROR is returned, the application may then
426 call inflateSync() to look for a good compression block if a partial recovery
427 of the data is desired.
381*/ 428*/
382 429
383 430
@@ -547,16 +594,36 @@ extern int inflateInit2 (z_streamp strm, int windowBits);
547 The windowBits parameter is the base two logarithm of the maximum window 594 The windowBits parameter is the base two logarithm of the maximum window
548 size (the size of the history buffer). It should be in the range 8..15 for 595 size (the size of the history buffer). It should be in the range 8..15 for
549 this version of the library. The default value is 15 if inflateInit is used 596 this version of the library. The default value is 15 if inflateInit is used
550 instead. If a compressed stream with a larger window size is given as 597 instead. windowBits must be greater than or equal to the windowBits value
551 input, inflate() will return with the error code Z_DATA_ERROR instead of 598 provided to deflateInit2() while compressing, or it must be equal to 15 if
552 trying to allocate a larger window. 599 deflateInit2() was not used. If a compressed stream with a larger window
553 600 size is given as input, inflate() will return with the error code
554 inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 601 Z_DATA_ERROR instead of trying to allocate a larger window.
555 memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative 602
556 memLevel). msg is set to null if there is no error message. inflateInit2 603 windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
557 does not perform any decompression apart from reading the zlib header if 604 determines the window size. inflate() will then process raw deflate data,
558 present: this will be done by inflate(). (So next_in and avail_in may be 605 not looking for a zlib or gzip header, not generating a check value, and not
559 modified, but next_out and avail_out are unchanged.) 606 looking for any check values for comparison at the end of the stream. This
607 is for use with other formats that use the deflate compressed data format
608 such as zip. Those formats provide their own check values. If a custom
609 format is developed using the raw deflate format for compressed data, it is
610 recommended that a check value such as an adler32 or a crc32 be applied to
611 the uncompressed data as is done in the zlib, gzip, and zip formats. For
612 most applications, the zlib format should be used as is. Note that comments
613 above on the use in deflateInit2() applies to the magnitude of windowBits.
614
615 windowBits can also be greater than 15 for optional gzip decoding. Add
616 32 to windowBits to enable zlib and gzip decoding with automatic header
617 detection, or add 16 to decode only the gzip format (the zlib format will
618 return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
619 a crc32 instead of an adler32.
620
621 inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
622 memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
623 is set to null if there is no error message. inflateInit2 does not perform
624 any decompression apart from reading the zlib header if present: this will
625 be done by inflate(). (So next_in and avail_in may be modified, but next_out
626 and avail_out are unchanged.)
560*/ 627*/
561 628
562extern int zlib_inflateSetDictionary (z_streamp strm, 629extern int zlib_inflateSetDictionary (z_streamp strm,
@@ -564,16 +631,19 @@ extern int zlib_inflateSetDictionary (z_streamp strm,
564 uInt dictLength); 631 uInt dictLength);
565/* 632/*
566 Initializes the decompression dictionary from the given uncompressed byte 633 Initializes the decompression dictionary from the given uncompressed byte
567 sequence. This function must be called immediately after a call of inflate 634 sequence. This function must be called immediately after a call of inflate,
568 if this call returned Z_NEED_DICT. The dictionary chosen by the compressor 635 if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
569 can be determined from the Adler32 value returned by this call of 636 can be determined from the adler32 value returned by that call of inflate.
570 inflate. The compressor and decompressor must use exactly the same 637 The compressor and decompressor must use exactly the same dictionary (see
571 dictionary (see deflateSetDictionary). 638 deflateSetDictionary). For raw inflate, this function can be called
639 immediately after inflateInit2() or inflateReset() and before any call of
640 inflate() to set the dictionary. The application must insure that the
641 dictionary that was used for compression is provided.
572 642
573 inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a 643 inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
574 parameter is invalid (such as NULL dictionary) or the stream state is 644 parameter is invalid (such as NULL dictionary) or the stream state is
575 inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the 645 inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
576 expected one (incorrect Adler32 value). inflateSetDictionary does not 646 expected one (incorrect adler32 value). inflateSetDictionary does not
577 perform any decompression: this will be done by subsequent calls of 647 perform any decompression: this will be done by subsequent calls of
578 inflate(). 648 inflate().
579*/ 649*/
@@ -614,40 +684,19 @@ extern int zlib_inflateIncomp (z_stream *strm);
614 containing the data at next_in (except that the data is not output). 684 containing the data at next_in (except that the data is not output).
615*/ 685*/
616 686
617 /* various hacks, don't look :) */
618
619/* deflateInit and inflateInit are macros to allow checking the zlib version
620 * and the compiler's view of z_stream:
621 */
622extern int zlib_deflateInit_ (z_streamp strm, int level,
623 const char *version, int stream_size);
624extern int zlib_inflateInit_ (z_streamp strm,
625 const char *version, int stream_size);
626extern int zlib_deflateInit2_ (z_streamp strm, int level, int method,
627 int windowBits, int memLevel,
628 int strategy, const char *version,
629 int stream_size);
630extern int zlib_inflateInit2_ (z_streamp strm, int windowBits,
631 const char *version, int stream_size);
632#define zlib_deflateInit(strm, level) \ 687#define zlib_deflateInit(strm, level) \
633 zlib_deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) 688 zlib_deflateInit2((strm), (level), Z_DEFLATED, MAX_WBITS, \
689 DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY)
634#define zlib_inflateInit(strm) \ 690#define zlib_inflateInit(strm) \
635 zlib_inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) 691 zlib_inflateInit2((strm), DEF_WBITS)
636#define zlib_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
637 zlib_deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
638 (strategy), ZLIB_VERSION, sizeof(z_stream))
639#define zlib_inflateInit2(strm, windowBits) \
640 zlib_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
641 692
693extern int zlib_deflateInit2(z_streamp strm, int level, int method,
694 int windowBits, int memLevel,
695 int strategy);
696extern int zlib_inflateInit2(z_streamp strm, int windowBits);
642 697
643#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) 698#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
644 struct internal_state {int dummy;}; /* hack for buggy compilers */ 699 struct internal_state {int dummy;}; /* hack for buggy compilers */
645#endif 700#endif
646 701
647extern const char * zlib_zError (int err);
648#if 0
649extern int zlib_inflateSyncPoint (z_streamp z);
650#endif
651extern const uLong * zlib_get_crc_table (void);
652
653#endif /* _ZLIB_H */ 702#endif /* _ZLIB_H */
diff --git a/include/linux/zutil.h b/include/linux/zutil.h
index ee0c59cf2136..6adfa9a6ffe9 100644
--- a/include/linux/zutil.h
+++ b/include/linux/zutil.h
@@ -23,18 +23,6 @@ typedef unsigned long ulg;
23 23
24 /* common constants */ 24 /* common constants */
25 25
26#ifndef DEF_WBITS
27# define DEF_WBITS MAX_WBITS
28#endif
29/* default windowBits for decompression. MAX_WBITS is for compression only */
30
31#if MAX_MEM_LEVEL >= 8
32# define DEF_MEM_LEVEL 8
33#else
34# define DEF_MEM_LEVEL MAX_MEM_LEVEL
35#endif
36/* default memLevel */
37
38#define STORED_BLOCK 0 26#define STORED_BLOCK 0
39#define STATIC_TREES 1 27#define STATIC_TREES 1
40#define DYN_TREES 2 28#define DYN_TREES 2
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index b45a73712748..446afc3ea27f 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -378,6 +378,7 @@
378#define AC97_HAS_NO_MIC (1<<15) /* no MIC volume */ 378#define AC97_HAS_NO_MIC (1<<15) /* no MIC volume */
379#define AC97_HAS_NO_TONE (1<<16) /* no Tone volume */ 379#define AC97_HAS_NO_TONE (1<<16) /* no Tone volume */
380#define AC97_HAS_NO_STD_PCM (1<<17) /* no standard AC97 PCM volume and mute */ 380#define AC97_HAS_NO_STD_PCM (1<<17) /* no standard AC97 PCM volume and mute */
381#define AC97_HAS_NO_AUX (1<<18) /* no standard AC97 AUX volume and mute */
381 382
382/* rates indexes */ 383/* rates indexes */
383#define AC97_RATES_FRONT_DAC 0 384#define AC97_RATES_FRONT_DAC 0
diff --git a/include/sound/asequencer.h b/include/sound/asequencer.h
index 6691e4aa4ea7..3f2f4042a20d 100644
--- a/include/sound/asequencer.h
+++ b/include/sound/asequencer.h
@@ -605,6 +605,10 @@ struct snd_seq_remove_events {
605#define SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE (1<<11) /* Sampling device (support sample download) */ 605#define SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE (1<<11) /* Sampling device (support sample download) */
606#define SNDRV_SEQ_PORT_TYPE_SAMPLE (1<<12) /* Sampling device (sample can be downloaded at any time) */ 606#define SNDRV_SEQ_PORT_TYPE_SAMPLE (1<<12) /* Sampling device (sample can be downloaded at any time) */
607/*...*/ 607/*...*/
608#define SNDRV_SEQ_PORT_TYPE_HARDWARE (1<<16) /* driver for a hardware device */
609#define SNDRV_SEQ_PORT_TYPE_SOFTWARE (1<<17) /* implemented in software */
610#define SNDRV_SEQ_PORT_TYPE_SYNTHESIZER (1<<18) /* generates sound */
611#define SNDRV_SEQ_PORT_TYPE_PORT (1<<19) /* connects to other device(s) */
608#define SNDRV_SEQ_PORT_TYPE_APPLICATION (1<<20) /* application (sequencer/editor) */ 612#define SNDRV_SEQ_PORT_TYPE_APPLICATION (1<<20) /* application (sequencer/editor) */
609 613
610/* misc. conditioning flags */ 614/* misc. conditioning flags */
diff --git a/include/sound/asound.h b/include/sound/asound.h
index 9cc021c7ee11..41885f48ad91 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -137,7 +137,7 @@ enum {
137 * * 137 * *
138 *****************************************************************************/ 138 *****************************************************************************/
139 139
140#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7) 140#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 8)
141 141
142typedef unsigned long snd_pcm_uframes_t; 142typedef unsigned long snd_pcm_uframes_t;
143typedef signed long snd_pcm_sframes_t; 143typedef signed long snd_pcm_sframes_t;
diff --git a/include/sound/core.h b/include/sound/core.h
index 5135147f20e8..5d184be0ff72 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -233,9 +233,8 @@ int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size
233 233
234/* init.c */ 234/* init.c */
235 235
236extern unsigned int snd_cards_lock;
237extern struct snd_card *snd_cards[SNDRV_CARDS]; 236extern struct snd_card *snd_cards[SNDRV_CARDS];
238extern rwlock_t snd_card_rwlock; 237int snd_card_locked(int card);
239#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 238#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
240#define SND_MIXER_OSS_NOTIFY_REGISTER 0 239#define SND_MIXER_OSS_NOTIFY_REGISTER 0
241#define SND_MIXER_OSS_NOTIFY_DISCONNECT 1 240#define SND_MIXER_OSS_NOTIFY_DISCONNECT 1
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 186e00ad9e79..884bbf54cd36 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -245,6 +245,7 @@
245#define A_IOCFG_GPOUT0 0x0044 /* analog/digital */ 245#define A_IOCFG_GPOUT0 0x0044 /* analog/digital */
246#define A_IOCFG_DISABLE_ANALOG 0x0040 /* = 'enable' for Audigy2 (chiprev=4) */ 246#define A_IOCFG_DISABLE_ANALOG 0x0040 /* = 'enable' for Audigy2 (chiprev=4) */
247#define A_IOCFG_ENABLE_DIGITAL 0x0004 247#define A_IOCFG_ENABLE_DIGITAL 0x0004
248#define A_IOCFG_ENABLE_DIGITAL_AUDIGY4 0x0080
248#define A_IOCFG_UNKNOWN_20 0x0020 249#define A_IOCFG_UNKNOWN_20 0x0020
249#define A_IOCFG_DISABLE_AC97_FRONT 0x0080 /* turn off ac97 front -> front (10k2.1) */ 250#define A_IOCFG_DISABLE_AC97_FRONT 0x0080 /* turn off ac97 front -> front (10k2.1) */
250#define A_IOCFG_GPOUT1 0x0002 /* IR? drive's internal bypass (?) */ 251#define A_IOCFG_GPOUT1 0x0002 /* IR? drive's internal bypass (?) */
@@ -1065,6 +1066,7 @@ struct snd_emu_chip_details {
1065 unsigned char emu1212m; /* EMU 1212m card */ 1066 unsigned char emu1212m; /* EMU 1212m card */
1066 unsigned char spi_dac; /* SPI interface for DAC */ 1067 unsigned char spi_dac; /* SPI interface for DAC */
1067 unsigned char i2c_adc; /* I2C interface for ADC */ 1068 unsigned char i2c_adc; /* I2C interface for ADC */
1069 unsigned char adc_1361t; /* Use Philips 1361T ADC */
1068 const char *driver; 1070 const char *driver;
1069 const char *name; 1071 const char *name;
1070 const char *id; /* for backward compatibility - can be NULL if not needed */ 1072 const char *id; /* for backward compatibility - can be NULL if not needed */
diff --git a/include/sound/info.h b/include/sound/info.h
index f23d8381c216..74f6996769c7 100644
--- a/include/sound/info.h
+++ b/include/sound/info.h
@@ -27,9 +27,9 @@
27/* buffer for information */ 27/* buffer for information */
28struct snd_info_buffer { 28struct snd_info_buffer {
29 char *buffer; /* pointer to begin of buffer */ 29 char *buffer; /* pointer to begin of buffer */
30 char *curr; /* current position in buffer */ 30 unsigned int curr; /* current position in buffer */
31 unsigned long size; /* current size */ 31 unsigned int size; /* current size */
32 unsigned long len; /* total length of buffer */ 32 unsigned int len; /* total length of buffer */
33 int stop; /* stop flag */ 33 int stop; /* stop flag */
34 int error; /* error code */ 34 int error; /* error code */
35}; 35};
@@ -40,8 +40,6 @@ struct snd_info_buffer {
40struct snd_info_entry; 40struct snd_info_entry;
41 41
42struct snd_info_entry_text { 42struct snd_info_entry_text {
43 unsigned long read_size;
44 unsigned long write_size;
45 void (*read) (struct snd_info_entry *entry, struct snd_info_buffer *buffer); 43 void (*read) (struct snd_info_entry *entry, struct snd_info_buffer *buffer);
46 void (*write) (struct snd_info_entry *entry, struct snd_info_buffer *buffer); 44 void (*write) (struct snd_info_entry *entry, struct snd_info_buffer *buffer);
47}; 45};
@@ -132,11 +130,9 @@ int snd_card_proc_new(struct snd_card *card, const char *name, struct snd_info_e
132 130
133static inline void snd_info_set_text_ops(struct snd_info_entry *entry, 131static inline void snd_info_set_text_ops(struct snd_info_entry *entry,
134 void *private_data, 132 void *private_data,
135 long read_size,
136 void (*read)(struct snd_info_entry *, struct snd_info_buffer *)) 133 void (*read)(struct snd_info_entry *, struct snd_info_buffer *))
137{ 134{
138 entry->private_data = private_data; 135 entry->private_data = private_data;
139 entry->c.text.read_size = read_size;
140 entry->c.text.read = read; 136 entry->c.text.read = read;
141} 137}
142 138
@@ -167,7 +163,6 @@ static inline int snd_card_proc_new(struct snd_card *card, const char *name,
167 struct snd_info_entry **entryp) { return -EINVAL; } 163 struct snd_info_entry **entryp) { return -EINVAL; }
168static inline void snd_info_set_text_ops(struct snd_info_entry *entry __attribute__((unused)), 164static inline void snd_info_set_text_ops(struct snd_info_entry *entry __attribute__((unused)),
169 void *private_data, 165 void *private_data,
170 long read_size,
171 void (*read)(struct snd_info_entry *, struct snd_info_buffer *)) {} 166 void (*read)(struct snd_info_entry *, struct snd_info_buffer *)) {}
172 167
173static inline int snd_info_check_reserved_words(const char *str) { return 1; } 168static inline int snd_info_check_reserved_words(const char *str) { return 1; }
diff --git a/include/sound/mpu401.h b/include/sound/mpu401.h
index 8e97ace78f16..ac504321ea56 100644
--- a/include/sound/mpu401.h
+++ b/include/sound/mpu401.h
@@ -45,6 +45,12 @@
45#define MPU401_HW_PC98II 18 /* Roland PC98II */ 45#define MPU401_HW_PC98II 18 /* Roland PC98II */
46#define MPU401_HW_AUREAL 19 /* Aureal Vortex */ 46#define MPU401_HW_AUREAL 19 /* Aureal Vortex */
47 47
48#define MPU401_INFO_INPUT (1 << 0) /* input stream */
49#define MPU401_INFO_OUTPUT (1 << 1) /* output stream */
50#define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */
51#define MPU401_INFO_MMIO (1 << 3) /* MMIO access */
52#define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */
53
48#define MPU401_MODE_BIT_INPUT 0 54#define MPU401_MODE_BIT_INPUT 0
49#define MPU401_MODE_BIT_OUTPUT 1 55#define MPU401_MODE_BIT_OUTPUT 1
50#define MPU401_MODE_BIT_INPUT_TRIGGER 2 56#define MPU401_MODE_BIT_INPUT_TRIGGER 2
@@ -62,6 +68,7 @@ struct snd_mpu401 {
62 struct snd_rawmidi *rmidi; 68 struct snd_rawmidi *rmidi;
63 69
64 unsigned short hardware; /* MPU401_HW_XXXX */ 70 unsigned short hardware; /* MPU401_HW_XXXX */
71 unsigned int info_flags; /* MPU401_INFO_XXX */
65 unsigned long port; /* base port of MPU-401 chip */ 72 unsigned long port; /* base port of MPU-401 chip */
66 unsigned long cport; /* port + 1 (usually) */ 73 unsigned long cport; /* port + 1 (usually) */
67 struct resource *res; /* port resource */ 74 struct resource *res; /* port resource */
@@ -99,13 +106,16 @@ struct snd_mpu401 {
99 106
100 */ 107 */
101 108
102irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs); 109irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id,
110 struct pt_regs *regs);
111irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id,
112 struct pt_regs *regs);
103 113
104int snd_mpu401_uart_new(struct snd_card *card, 114int snd_mpu401_uart_new(struct snd_card *card,
105 int device, 115 int device,
106 unsigned short hardware, 116 unsigned short hardware,
107 unsigned long port, 117 unsigned long port,
108 int integrated, 118 unsigned int info_flags,
109 int irq, 119 int irq,
110 int irq_flags, 120 int irq_flags,
111 struct snd_rawmidi ** rrawmidi); 121 struct snd_rawmidi ** rrawmidi);
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 373425895faa..f84d84993a31 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -300,7 +300,6 @@ struct snd_pcm_runtime {
300 /* -- mmap -- */ 300 /* -- mmap -- */
301 volatile struct snd_pcm_mmap_status *status; 301 volatile struct snd_pcm_mmap_status *status;
302 volatile struct snd_pcm_mmap_control *control; 302 volatile struct snd_pcm_mmap_control *control;
303 atomic_t mmap_count;
304 303
305 /* -- locking / scheduling -- */ 304 /* -- locking / scheduling -- */
306 wait_queue_head_t sleep; 305 wait_queue_head_t sleep;
@@ -368,7 +367,9 @@ struct snd_pcm_substream {
368 struct snd_pcm_group *group; /* pointer to current group */ 367 struct snd_pcm_group *group; /* pointer to current group */
369 /* -- assigned files -- */ 368 /* -- assigned files -- */
370 void *file; 369 void *file;
371 struct file *ffile; 370 int ref_count;
371 atomic_t mmap_count;
372 unsigned int f_flags;
372 void (*pcm_release)(struct snd_pcm_substream *); 373 void (*pcm_release)(struct snd_pcm_substream *);
373#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 374#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
374 /* -- OSS things -- */ 375 /* -- OSS things -- */
@@ -387,7 +388,7 @@ struct snd_pcm_substream {
387 unsigned int hw_opened: 1; 388 unsigned int hw_opened: 1;
388}; 389};
389 390
390#define SUBSTREAM_BUSY(substream) ((substream)->file != NULL) 391#define SUBSTREAM_BUSY(substream) ((substream)->ref_count > 0)
391 392
392 393
393struct snd_pcm_str { 394struct snd_pcm_str {
@@ -825,14 +826,6 @@ int snd_interval_ratnum(struct snd_interval *i,
825 826
826void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params); 827void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params);
827void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var); 828void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var);
828int snd_pcm_hw_param_near(struct snd_pcm_substream *substream,
829 struct snd_pcm_hw_params *params,
830 snd_pcm_hw_param_t var,
831 unsigned int val, int *dir);
832int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm,
833 struct snd_pcm_hw_params *params,
834 snd_pcm_hw_param_t var,
835 unsigned int val, int dir);
836int snd_pcm_hw_params_choose(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); 829int snd_pcm_hw_params_choose(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params);
837 830
838int snd_pcm_hw_refine(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); 831int snd_pcm_hw_refine(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params);
@@ -979,13 +972,13 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne
979static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area) 972static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
980{ 973{
981 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; 974 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data;
982 atomic_inc(&substream->runtime->mmap_count); 975 atomic_inc(&substream->mmap_count);
983} 976}
984 977
985static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area) 978static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area)
986{ 979{
987 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; 980 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data;
988 atomic_dec(&substream->runtime->mmap_count); 981 atomic_dec(&substream->mmap_count);
989} 982}
990 983
991/* mmap for io-memory area */ 984/* mmap for io-memory area */
diff --git a/include/sound/pcm_params.h b/include/sound/pcm_params.h
index fb18aef77341..85cf1cf4f31a 100644
--- a/include/sound/pcm_params.h
+++ b/include/sound/pcm_params.h
@@ -22,29 +22,21 @@
22 * 22 *
23 */ 23 */
24 24
25extern int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params, 25int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm,
26 snd_pcm_hw_param_t var, const struct snd_mask *val); 26 struct snd_pcm_hw_params *params,
27extern unsigned int snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params, 27 snd_pcm_hw_param_t var, int *dir);
28 snd_pcm_hw_param_t var, int *dir); 28int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
29extern unsigned int snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params, 29 struct snd_pcm_hw_params *params,
30 snd_pcm_hw_param_t var, int *dir); 30 snd_pcm_hw_param_t var, int *dir);
31extern int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, 31int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
32 snd_pcm_hw_param_t var, unsigned int val, int dir); 32 snd_pcm_hw_param_t var, int *dir);
33extern int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params,
34 snd_pcm_hw_param_t var);
35extern int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
36 snd_pcm_hw_param_t var, unsigned int val, int dir);
37
38/* To share the same code we have alsa-lib */
39#define INLINE static inline
40#define assert(a) (void)(a)
41 33
42#define SNDRV_MASK_BITS 64 /* we use so far 64bits only */ 34#define SNDRV_MASK_BITS 64 /* we use so far 64bits only */
43#define SNDRV_MASK_SIZE (SNDRV_MASK_BITS / 32) 35#define SNDRV_MASK_SIZE (SNDRV_MASK_BITS / 32)
44#define MASK_OFS(i) ((i) >> 5) 36#define MASK_OFS(i) ((i) >> 5)
45#define MASK_BIT(i) (1U << ((i) & 31)) 37#define MASK_BIT(i) (1U << ((i) & 31))
46 38
47INLINE unsigned int ld2(u_int32_t v) 39static inline unsigned int ld2(u_int32_t v)
48{ 40{
49 unsigned r = 0; 41 unsigned r = 0;
50 42
@@ -69,22 +61,22 @@ INLINE unsigned int ld2(u_int32_t v)
69 return r; 61 return r;
70} 62}
71 63
72INLINE size_t snd_mask_sizeof(void) 64static inline size_t snd_mask_sizeof(void)
73{ 65{
74 return sizeof(struct snd_mask); 66 return sizeof(struct snd_mask);
75} 67}
76 68
77INLINE void snd_mask_none(struct snd_mask *mask) 69static inline void snd_mask_none(struct snd_mask *mask)
78{ 70{
79 memset(mask, 0, sizeof(*mask)); 71 memset(mask, 0, sizeof(*mask));
80} 72}
81 73
82INLINE void snd_mask_any(struct snd_mask *mask) 74static inline void snd_mask_any(struct snd_mask *mask)
83{ 75{
84 memset(mask, 0xff, SNDRV_MASK_SIZE * sizeof(u_int32_t)); 76 memset(mask, 0xff, SNDRV_MASK_SIZE * sizeof(u_int32_t));
85} 77}
86 78
87INLINE int snd_mask_empty(const struct snd_mask *mask) 79static inline int snd_mask_empty(const struct snd_mask *mask)
88{ 80{
89 int i; 81 int i;
90 for (i = 0; i < SNDRV_MASK_SIZE; i++) 82 for (i = 0; i < SNDRV_MASK_SIZE; i++)
@@ -93,10 +85,9 @@ INLINE int snd_mask_empty(const struct snd_mask *mask)
93 return 1; 85 return 1;
94} 86}
95 87
96INLINE unsigned int snd_mask_min(const struct snd_mask *mask) 88static inline unsigned int snd_mask_min(const struct snd_mask *mask)
97{ 89{
98 int i; 90 int i;
99 assert(!snd_mask_empty(mask));
100 for (i = 0; i < SNDRV_MASK_SIZE; i++) { 91 for (i = 0; i < SNDRV_MASK_SIZE; i++) {
101 if (mask->bits[i]) 92 if (mask->bits[i])
102 return ffs(mask->bits[i]) - 1 + (i << 5); 93 return ffs(mask->bits[i]) - 1 + (i << 5);
@@ -104,10 +95,9 @@ INLINE unsigned int snd_mask_min(const struct snd_mask *mask)
104 return 0; 95 return 0;
105} 96}
106 97
107INLINE unsigned int snd_mask_max(const struct snd_mask *mask) 98static inline unsigned int snd_mask_max(const struct snd_mask *mask)
108{ 99{
109 int i; 100 int i;
110 assert(!snd_mask_empty(mask));
111 for (i = SNDRV_MASK_SIZE - 1; i >= 0; i--) { 101 for (i = SNDRV_MASK_SIZE - 1; i >= 0; i--) {
112 if (mask->bits[i]) 102 if (mask->bits[i])
113 return ld2(mask->bits[i]) + (i << 5); 103 return ld2(mask->bits[i]) + (i << 5);
@@ -115,70 +105,68 @@ INLINE unsigned int snd_mask_max(const struct snd_mask *mask)
115 return 0; 105 return 0;
116} 106}
117 107
118INLINE void snd_mask_set(struct snd_mask *mask, unsigned int val) 108static inline void snd_mask_set(struct snd_mask *mask, unsigned int val)
119{ 109{
120 assert(val <= SNDRV_MASK_BITS);
121 mask->bits[MASK_OFS(val)] |= MASK_BIT(val); 110 mask->bits[MASK_OFS(val)] |= MASK_BIT(val);
122} 111}
123 112
124INLINE void snd_mask_reset(struct snd_mask *mask, unsigned int val) 113static inline void snd_mask_reset(struct snd_mask *mask, unsigned int val)
125{ 114{
126 assert(val <= SNDRV_MASK_BITS);
127 mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val); 115 mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val);
128} 116}
129 117
130INLINE void snd_mask_set_range(struct snd_mask *mask, unsigned int from, unsigned int to) 118static inline void snd_mask_set_range(struct snd_mask *mask,
119 unsigned int from, unsigned int to)
131{ 120{
132 unsigned int i; 121 unsigned int i;
133 assert(to <= SNDRV_MASK_BITS && from <= to);
134 for (i = from; i <= to; i++) 122 for (i = from; i <= to; i++)
135 mask->bits[MASK_OFS(i)] |= MASK_BIT(i); 123 mask->bits[MASK_OFS(i)] |= MASK_BIT(i);
136} 124}
137 125
138INLINE void snd_mask_reset_range(struct snd_mask *mask, unsigned int from, unsigned int to) 126static inline void snd_mask_reset_range(struct snd_mask *mask,
127 unsigned int from, unsigned int to)
139{ 128{
140 unsigned int i; 129 unsigned int i;
141 assert(to <= SNDRV_MASK_BITS && from <= to);
142 for (i = from; i <= to; i++) 130 for (i = from; i <= to; i++)
143 mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i); 131 mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i);
144} 132}
145 133
146INLINE void snd_mask_leave(struct snd_mask *mask, unsigned int val) 134static inline void snd_mask_leave(struct snd_mask *mask, unsigned int val)
147{ 135{
148 unsigned int v; 136 unsigned int v;
149 assert(val <= SNDRV_MASK_BITS);
150 v = mask->bits[MASK_OFS(val)] & MASK_BIT(val); 137 v = mask->bits[MASK_OFS(val)] & MASK_BIT(val);
151 snd_mask_none(mask); 138 snd_mask_none(mask);
152 mask->bits[MASK_OFS(val)] = v; 139 mask->bits[MASK_OFS(val)] = v;
153} 140}
154 141
155INLINE void snd_mask_intersect(struct snd_mask *mask, const struct snd_mask *v) 142static inline void snd_mask_intersect(struct snd_mask *mask,
143 const struct snd_mask *v)
156{ 144{
157 int i; 145 int i;
158 for (i = 0; i < SNDRV_MASK_SIZE; i++) 146 for (i = 0; i < SNDRV_MASK_SIZE; i++)
159 mask->bits[i] &= v->bits[i]; 147 mask->bits[i] &= v->bits[i];
160} 148}
161 149
162INLINE int snd_mask_eq(const struct snd_mask *mask, const struct snd_mask *v) 150static inline int snd_mask_eq(const struct snd_mask *mask,
151 const struct snd_mask *v)
163{ 152{
164 return ! memcmp(mask, v, SNDRV_MASK_SIZE * sizeof(u_int32_t)); 153 return ! memcmp(mask, v, SNDRV_MASK_SIZE * sizeof(u_int32_t));
165} 154}
166 155
167INLINE void snd_mask_copy(struct snd_mask *mask, const struct snd_mask *v) 156static inline void snd_mask_copy(struct snd_mask *mask,
157 const struct snd_mask *v)
168{ 158{
169 *mask = *v; 159 *mask = *v;
170} 160}
171 161
172INLINE int snd_mask_test(const struct snd_mask *mask, unsigned int val) 162static inline int snd_mask_test(const struct snd_mask *mask, unsigned int val)
173{ 163{
174 assert(val <= SNDRV_MASK_BITS);
175 return mask->bits[MASK_OFS(val)] & MASK_BIT(val); 164 return mask->bits[MASK_OFS(val)] & MASK_BIT(val);
176} 165}
177 166
178INLINE int snd_mask_single(const struct snd_mask *mask) 167static inline int snd_mask_single(const struct snd_mask *mask)
179{ 168{
180 int i, c = 0; 169 int i, c = 0;
181 assert(!snd_mask_empty(mask));
182 for (i = 0; i < SNDRV_MASK_SIZE; i++) { 170 for (i = 0; i < SNDRV_MASK_SIZE; i++) {
183 if (! mask->bits[i]) 171 if (! mask->bits[i])
184 continue; 172 continue;
@@ -191,10 +179,10 @@ INLINE int snd_mask_single(const struct snd_mask *mask)
191 return 1; 179 return 1;
192} 180}
193 181
194INLINE int snd_mask_refine(struct snd_mask *mask, const struct snd_mask *v) 182static inline int snd_mask_refine(struct snd_mask *mask,
183 const struct snd_mask *v)
195{ 184{
196 struct snd_mask old; 185 struct snd_mask old;
197 assert(!snd_mask_empty(mask));
198 snd_mask_copy(&old, mask); 186 snd_mask_copy(&old, mask);
199 snd_mask_intersect(mask, v); 187 snd_mask_intersect(mask, v);
200 if (snd_mask_empty(mask)) 188 if (snd_mask_empty(mask))
@@ -202,27 +190,24 @@ INLINE int snd_mask_refine(struct snd_mask *mask, const struct snd_mask *v)
202 return !snd_mask_eq(mask, &old); 190 return !snd_mask_eq(mask, &old);
203} 191}
204 192
205INLINE int snd_mask_refine_first(struct snd_mask *mask) 193static inline int snd_mask_refine_first(struct snd_mask *mask)
206{ 194{
207 assert(!snd_mask_empty(mask));
208 if (snd_mask_single(mask)) 195 if (snd_mask_single(mask))
209 return 0; 196 return 0;
210 snd_mask_leave(mask, snd_mask_min(mask)); 197 snd_mask_leave(mask, snd_mask_min(mask));
211 return 1; 198 return 1;
212} 199}
213 200
214INLINE int snd_mask_refine_last(struct snd_mask *mask) 201static inline int snd_mask_refine_last(struct snd_mask *mask)
215{ 202{
216 assert(!snd_mask_empty(mask));
217 if (snd_mask_single(mask)) 203 if (snd_mask_single(mask))
218 return 0; 204 return 0;
219 snd_mask_leave(mask, snd_mask_max(mask)); 205 snd_mask_leave(mask, snd_mask_max(mask));
220 return 1; 206 return 1;
221} 207}
222 208
223INLINE int snd_mask_refine_min(struct snd_mask *mask, unsigned int val) 209static inline int snd_mask_refine_min(struct snd_mask *mask, unsigned int val)
224{ 210{
225 assert(!snd_mask_empty(mask));
226 if (snd_mask_min(mask) >= val) 211 if (snd_mask_min(mask) >= val)
227 return 0; 212 return 0;
228 snd_mask_reset_range(mask, 0, val - 1); 213 snd_mask_reset_range(mask, 0, val - 1);
@@ -231,9 +216,8 @@ INLINE int snd_mask_refine_min(struct snd_mask *mask, unsigned int val)
231 return 1; 216 return 1;
232} 217}
233 218
234INLINE int snd_mask_refine_max(struct snd_mask *mask, unsigned int val) 219static inline int snd_mask_refine_max(struct snd_mask *mask, unsigned int val)
235{ 220{
236 assert(!snd_mask_empty(mask));
237 if (snd_mask_max(mask) <= val) 221 if (snd_mask_max(mask) <= val)
238 return 0; 222 return 0;
239 snd_mask_reset_range(mask, val + 1, SNDRV_MASK_BITS); 223 snd_mask_reset_range(mask, val + 1, SNDRV_MASK_BITS);
@@ -242,10 +226,9 @@ INLINE int snd_mask_refine_max(struct snd_mask *mask, unsigned int val)
242 return 1; 226 return 1;
243} 227}
244 228
245INLINE int snd_mask_refine_set(struct snd_mask *mask, unsigned int val) 229static inline int snd_mask_refine_set(struct snd_mask *mask, unsigned int val)
246{ 230{
247 int changed; 231 int changed;
248 assert(!snd_mask_empty(mask));
249 changed = !snd_mask_single(mask); 232 changed = !snd_mask_single(mask);
250 snd_mask_leave(mask, val); 233 snd_mask_leave(mask, val);
251 if (snd_mask_empty(mask)) 234 if (snd_mask_empty(mask))
@@ -253,13 +236,12 @@ INLINE int snd_mask_refine_set(struct snd_mask *mask, unsigned int val)
253 return changed; 236 return changed;
254} 237}
255 238
256INLINE int snd_mask_value(const struct snd_mask *mask) 239static inline int snd_mask_value(const struct snd_mask *mask)
257{ 240{
258 assert(!snd_mask_empty(mask));
259 return snd_mask_min(mask); 241 return snd_mask_min(mask);
260} 242}
261 243
262INLINE void snd_interval_any(struct snd_interval *i) 244static inline void snd_interval_any(struct snd_interval *i)
263{ 245{
264 i->min = 0; 246 i->min = 0;
265 i->openmin = 0; 247 i->openmin = 0;
@@ -269,63 +251,59 @@ INLINE void snd_interval_any(struct snd_interval *i)
269 i->empty = 0; 251 i->empty = 0;
270} 252}
271 253
272INLINE void snd_interval_none(struct snd_interval *i) 254static inline void snd_interval_none(struct snd_interval *i)
273{ 255{
274 i->empty = 1; 256 i->empty = 1;
275} 257}
276 258
277INLINE int snd_interval_checkempty(const struct snd_interval *i) 259static inline int snd_interval_checkempty(const struct snd_interval *i)
278{ 260{
279 return (i->min > i->max || 261 return (i->min > i->max ||
280 (i->min == i->max && (i->openmin || i->openmax))); 262 (i->min == i->max && (i->openmin || i->openmax)));
281} 263}
282 264
283INLINE int snd_interval_empty(const struct snd_interval *i) 265static inline int snd_interval_empty(const struct snd_interval *i)
284{ 266{
285 return i->empty; 267 return i->empty;
286} 268}
287 269
288INLINE int snd_interval_single(const struct snd_interval *i) 270static inline int snd_interval_single(const struct snd_interval *i)
289{ 271{
290 assert(!snd_interval_empty(i));
291 return (i->min == i->max || 272 return (i->min == i->max ||
292 (i->min + 1 == i->max && i->openmax)); 273 (i->min + 1 == i->max && i->openmax));
293} 274}
294 275
295INLINE int snd_interval_value(const struct snd_interval *i) 276static inline int snd_interval_value(const struct snd_interval *i)
296{ 277{
297 assert(snd_interval_single(i));
298 return i->min; 278 return i->min;
299} 279}
300 280
301INLINE int snd_interval_min(const struct snd_interval *i) 281static inline int snd_interval_min(const struct snd_interval *i)
302{ 282{
303 assert(!snd_interval_empty(i));
304 return i->min; 283 return i->min;
305} 284}
306 285
307INLINE int snd_interval_max(const struct snd_interval *i) 286static inline int snd_interval_max(const struct snd_interval *i)
308{ 287{
309 unsigned int v; 288 unsigned int v;
310 assert(!snd_interval_empty(i));
311 v = i->max; 289 v = i->max;
312 if (i->openmax) 290 if (i->openmax)
313 v--; 291 v--;
314 return v; 292 return v;
315} 293}
316 294
317INLINE int snd_interval_test(const struct snd_interval *i, unsigned int val) 295static inline int snd_interval_test(const struct snd_interval *i, unsigned int val)
318{ 296{
319 return !((i->min > val || (i->min == val && i->openmin) || 297 return !((i->min > val || (i->min == val && i->openmin) ||
320 i->max < val || (i->max == val && i->openmax))); 298 i->max < val || (i->max == val && i->openmax)));
321} 299}
322 300
323INLINE void snd_interval_copy(struct snd_interval *d, const struct snd_interval *s) 301static inline void snd_interval_copy(struct snd_interval *d, const struct snd_interval *s)
324{ 302{
325 *d = *s; 303 *d = *s;
326} 304}
327 305
328INLINE int snd_interval_setinteger(struct snd_interval *i) 306static inline int snd_interval_setinteger(struct snd_interval *i)
329{ 307{
330 if (i->integer) 308 if (i->integer)
331 return 0; 309 return 0;
@@ -335,7 +313,7 @@ INLINE int snd_interval_setinteger(struct snd_interval *i)
335 return 1; 313 return 1;
336} 314}
337 315
338INLINE int snd_interval_eq(const struct snd_interval *i1, const struct snd_interval *i2) 316static inline int snd_interval_eq(const struct snd_interval *i1, const struct snd_interval *i2)
339{ 317{
340 if (i1->empty) 318 if (i1->empty)
341 return i2->empty; 319 return i2->empty;
@@ -359,8 +337,5 @@ static inline unsigned int sub(unsigned int a, unsigned int b)
359 return 0; 337 return 0;
360} 338}
361 339
362#undef INLINE
363#undef assert
364
365#endif /* __SOUND_PCM_PARAMS_H */ 340#endif /* __SOUND_PCM_PARAMS_H */
366 341
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index 584e73dd4793..7dbcd10fa215 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -46,6 +46,7 @@
46 46
47struct snd_rawmidi; 47struct snd_rawmidi;
48struct snd_rawmidi_substream; 48struct snd_rawmidi_substream;
49struct snd_seq_port_info;
49 50
50struct snd_rawmidi_ops { 51struct snd_rawmidi_ops {
51 int (*open) (struct snd_rawmidi_substream * substream); 52 int (*open) (struct snd_rawmidi_substream * substream);
@@ -57,6 +58,8 @@ struct snd_rawmidi_ops {
57struct snd_rawmidi_global_ops { 58struct snd_rawmidi_global_ops {
58 int (*dev_register) (struct snd_rawmidi * rmidi); 59 int (*dev_register) (struct snd_rawmidi * rmidi);
59 int (*dev_unregister) (struct snd_rawmidi * rmidi); 60 int (*dev_unregister) (struct snd_rawmidi * rmidi);
61 void (*get_port_info)(struct snd_rawmidi *rmidi, int number,
62 struct snd_seq_port_info *info);
60}; 63};
61 64
62struct snd_rawmidi_runtime { 65struct snd_rawmidi_runtime {
diff --git a/include/sound/version.h b/include/sound/version.h
index 4f0e65808cf1..2ee849d0e198 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
1/* include/version.h. Generated by configure. */ 1/* include/version.h. Generated by configure. */
2#define CONFIG_SND_VERSION "1.0.11rc4" 2#define CONFIG_SND_VERSION "1.0.12rc1"
3#define CONFIG_SND_DATE " (Wed Mar 22 10:27:24 2006 UTC)" 3#define CONFIG_SND_DATE " (Thu Jun 22 13:55:50 2006 UTC)"
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 0a907f0dc56b..cdf0f07af92f 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -15,7 +15,7 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/pm.h> 17#include <linux/pm.h>
18 18#include <linux/console.h>
19 19
20#include "power.h" 20#include "power.h"
21 21
diff --git a/kernel/sys.c b/kernel/sys.c
index 0b6ec0e7936f..fc9ebbbaba0c 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1860,23 +1860,20 @@ out:
1860 * fields when reaping, so a sample either gets all the additions of a 1860 * fields when reaping, so a sample either gets all the additions of a
1861 * given child after it's reaped, or none so this sample is before reaping. 1861 * given child after it's reaped, or none so this sample is before reaping.
1862 * 1862 *
1863 * tasklist_lock locking optimisation: 1863 * Locking:
1864 * If we are current and single threaded, we do not need to take the tasklist 1864 * We need to take the siglock for CHILDEREN, SELF and BOTH
1865 * lock or the siglock. No one else can take our signal_struct away, 1865 * for the cases current multithreaded, non-current single threaded
1866 * no one else can reap the children to update signal->c* counters, and 1866 * non-current multithreaded. Thread traversal is now safe with
1867 * no one else can race with the signal-> fields. 1867 * the siglock held.
1868 * If we do not take the tasklist_lock, the signal-> fields could be read 1868 * Strictly speaking, we donot need to take the siglock if we are current and
1869 * out of order while another thread was just exiting. So we place a 1869 * single threaded, as no one else can take our signal_struct away, no one
1870 * read memory barrier when we avoid the lock. On the writer side, 1870 * else can reap the children to update signal->c* counters, and no one else
1871 * write memory barrier is implied in __exit_signal as __exit_signal releases 1871 * can race with the signal-> fields. If we do not take any lock, the
1872 * the siglock spinlock after updating the signal-> fields. 1872 * signal-> fields could be read out of order while another thread was just
1873 * 1873 * exiting. So we should place a read memory barrier when we avoid the lock.
1874 * We don't really need the siglock when we access the non c* fields 1874 * On the writer side, write memory barrier is implied in __exit_signal
1875 * of the signal_struct (for RUSAGE_SELF) even in multithreaded 1875 * as __exit_signal releases the siglock spinlock after updating the signal->
1876 * case, since we take the tasklist lock for read and the non c* signal-> 1876 * fields. But we don't do this yet to keep things simple.
1877 * fields are updated only in __exit_signal, which is called with
1878 * tasklist_lock taken for write, hence these two threads cannot execute
1879 * concurrently.
1880 * 1877 *
1881 */ 1878 */
1882 1879
@@ -1885,35 +1882,25 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1885 struct task_struct *t; 1882 struct task_struct *t;
1886 unsigned long flags; 1883 unsigned long flags;
1887 cputime_t utime, stime; 1884 cputime_t utime, stime;
1888 int need_lock = 0;
1889 1885
1890 memset((char *) r, 0, sizeof *r); 1886 memset((char *) r, 0, sizeof *r);
1891 utime = stime = cputime_zero; 1887 utime = stime = cputime_zero;
1892 1888
1893 if (p != current || !thread_group_empty(p)) 1889 rcu_read_lock();
1894 need_lock = 1; 1890 if (!lock_task_sighand(p, &flags)) {
1895 1891 rcu_read_unlock();
1896 if (need_lock) { 1892 return;
1897 read_lock(&tasklist_lock); 1893 }
1898 if (unlikely(!p->signal)) {
1899 read_unlock(&tasklist_lock);
1900 return;
1901 }
1902 } else
1903 /* See locking comments above */
1904 smp_rmb();
1905 1894
1906 switch (who) { 1895 switch (who) {
1907 case RUSAGE_BOTH: 1896 case RUSAGE_BOTH:
1908 case RUSAGE_CHILDREN: 1897 case RUSAGE_CHILDREN:
1909 spin_lock_irqsave(&p->sighand->siglock, flags);
1910 utime = p->signal->cutime; 1898 utime = p->signal->cutime;
1911 stime = p->signal->cstime; 1899 stime = p->signal->cstime;
1912 r->ru_nvcsw = p->signal->cnvcsw; 1900 r->ru_nvcsw = p->signal->cnvcsw;
1913 r->ru_nivcsw = p->signal->cnivcsw; 1901 r->ru_nivcsw = p->signal->cnivcsw;
1914 r->ru_minflt = p->signal->cmin_flt; 1902 r->ru_minflt = p->signal->cmin_flt;
1915 r->ru_majflt = p->signal->cmaj_flt; 1903 r->ru_majflt = p->signal->cmaj_flt;
1916 spin_unlock_irqrestore(&p->sighand->siglock, flags);
1917 1904
1918 if (who == RUSAGE_CHILDREN) 1905 if (who == RUSAGE_CHILDREN)
1919 break; 1906 break;
@@ -1941,8 +1928,9 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1941 BUG(); 1928 BUG();
1942 } 1929 }
1943 1930
1944 if (need_lock) 1931 unlock_task_sighand(p, &flags);
1945 read_unlock(&tasklist_lock); 1932 rcu_read_unlock();
1933
1946 cputime_to_timeval(utime, &r->ru_utime); 1934 cputime_to_timeval(utime, &r->ru_utime);
1947 cputime_to_timeval(stime, &r->ru_stime); 1935 cputime_to_timeval(stime, &r->ru_stime);
1948} 1936}
diff --git a/kernel/user.c b/kernel/user.c
index 4b1eb745afa1..6408c0424291 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -148,7 +148,7 @@ struct user_struct * alloc_uid(uid_t uid)
148 new->mq_bytes = 0; 148 new->mq_bytes = 0;
149 new->locked_shm = 0; 149 new->locked_shm = 0;
150 150
151 if (alloc_uid_keyring(new) < 0) { 151 if (alloc_uid_keyring(new, current) < 0) {
152 kmem_cache_free(uid_cachep, new); 152 kmem_cache_free(uid_cachep, new);
153 return NULL; 153 return NULL;
154 } 154 }
diff --git a/lib/kobject.c b/lib/kobject.c
index 687ab418d292..8e7c71993487 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -198,14 +198,14 @@ int kobject_add(struct kobject * kobj)
198 198
199 /* be noisy on error issues */ 199 /* be noisy on error issues */
200 if (error == -EEXIST) 200 if (error == -EEXIST)
201 pr_debug("kobject_add failed for %s with -EEXIST, " 201 printk("kobject_add failed for %s with -EEXIST, "
202 "don't try to register things with the " 202 "don't try to register things with the "
203 "same name in the same directory.\n", 203 "same name in the same directory.\n",
204 kobject_name(kobj)); 204 kobject_name(kobj));
205 else 205 else
206 pr_debug("kobject_add failed for %s (%d)\n", 206 printk("kobject_add failed for %s (%d)\n",
207 kobject_name(kobj), error); 207 kobject_name(kobj), error);
208 /* dump_stack(); */ 208 dump_stack();
209 } 209 }
210 210
211 return error; 211 return error;
diff --git a/lib/zlib_deflate/deflate.c b/lib/zlib_deflate/deflate.c
index 1653dd9bb01a..c3e4a2baf835 100644
--- a/lib/zlib_deflate/deflate.c
+++ b/lib/zlib_deflate/deflate.c
@@ -164,34 +164,17 @@ static const config configuration_table[10] = {
164 memset((char *)s->head, 0, (unsigned)(s->hash_size-1)*sizeof(*s->head)); 164 memset((char *)s->head, 0, (unsigned)(s->hash_size-1)*sizeof(*s->head));
165 165
166/* ========================================================================= */ 166/* ========================================================================= */
167int zlib_deflateInit_( 167int zlib_deflateInit2(
168 z_streamp strm,
169 int level,
170 const char *version,
171 int stream_size
172)
173{
174 return zlib_deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS,
175 DEF_MEM_LEVEL,
176 Z_DEFAULT_STRATEGY, version, stream_size);
177 /* To do: ignore strm->next_in if we use it as window */
178}
179
180/* ========================================================================= */
181int zlib_deflateInit2_(
182 z_streamp strm, 168 z_streamp strm,
183 int level, 169 int level,
184 int method, 170 int method,
185 int windowBits, 171 int windowBits,
186 int memLevel, 172 int memLevel,
187 int strategy, 173 int strategy
188 const char *version,
189 int stream_size
190) 174)
191{ 175{
192 deflate_state *s; 176 deflate_state *s;
193 int noheader = 0; 177 int noheader = 0;
194 static char* my_version = ZLIB_VERSION;
195 deflate_workspace *mem; 178 deflate_workspace *mem;
196 179
197 ush *overlay; 180 ush *overlay;
@@ -199,10 +182,6 @@ int zlib_deflateInit2_(
199 * output size for (length,distance) codes is <= 24 bits. 182 * output size for (length,distance) codes is <= 24 bits.
200 */ 183 */
201 184
202 if (version == NULL || version[0] != my_version[0] ||
203 stream_size != sizeof(z_stream)) {
204 return Z_VERSION_ERROR;
205 }
206 if (strm == NULL) return Z_STREAM_ERROR; 185 if (strm == NULL) return Z_STREAM_ERROR;
207 186
208 strm->msg = NULL; 187 strm->msg = NULL;
diff --git a/lib/zlib_deflate/deflate_syms.c b/lib/zlib_deflate/deflate_syms.c
index 767b573d1ef6..ccfe25f3920f 100644
--- a/lib/zlib_deflate/deflate_syms.c
+++ b/lib/zlib_deflate/deflate_syms.c
@@ -12,8 +12,7 @@
12 12
13EXPORT_SYMBOL(zlib_deflate_workspacesize); 13EXPORT_SYMBOL(zlib_deflate_workspacesize);
14EXPORT_SYMBOL(zlib_deflate); 14EXPORT_SYMBOL(zlib_deflate);
15EXPORT_SYMBOL(zlib_deflateInit_); 15EXPORT_SYMBOL(zlib_deflateInit2);
16EXPORT_SYMBOL(zlib_deflateInit2_);
17EXPORT_SYMBOL(zlib_deflateEnd); 16EXPORT_SYMBOL(zlib_deflateEnd);
18EXPORT_SYMBOL(zlib_deflateReset); 17EXPORT_SYMBOL(zlib_deflateReset);
19MODULE_LICENSE("GPL"); 18MODULE_LICENSE("GPL");
diff --git a/lib/zlib_inflate/Makefile b/lib/zlib_inflate/Makefile
index 221c139e0df1..bf065482fa67 100644
--- a/lib/zlib_inflate/Makefile
+++ b/lib/zlib_inflate/Makefile
@@ -15,5 +15,5 @@
15 15
16obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o 16obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o
17 17
18zlib_inflate-objs := infblock.o infcodes.o inffast.o inflate.o \ 18zlib_inflate-objs := inffast.o inflate.o \
19 inflate_sync.o inftrees.o infutil.o inflate_syms.o 19 inftrees.o inflate_syms.o
diff --git a/lib/zlib_inflate/infblock.c b/lib/zlib_inflate/infblock.c
deleted file mode 100644
index c16cdeff51aa..000000000000
--- a/lib/zlib_inflate/infblock.c
+++ /dev/null
@@ -1,365 +0,0 @@
1/* infblock.c -- interpret and process block types to last block
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include <linux/zutil.h>
7#include "infblock.h"
8#include "inftrees.h"
9#include "infcodes.h"
10#include "infutil.h"
11
12struct inflate_codes_state;
13
14/* simplify the use of the inflate_huft type with some defines */
15#define exop word.what.Exop
16#define bits word.what.Bits
17
18/* Table for deflate from PKZIP's appnote.txt. */
19static const uInt border[] = { /* Order of the bit length code lengths */
20 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
21
22/*
23 Notes beyond the 1.93a appnote.txt:
24
25 1. Distance pointers never point before the beginning of the output
26 stream.
27 2. Distance pointers can point back across blocks, up to 32k away.
28 3. There is an implied maximum of 7 bits for the bit length table and
29 15 bits for the actual data.
30 4. If only one code exists, then it is encoded using one bit. (Zero
31 would be more efficient, but perhaps a little confusing.) If two
32 codes exist, they are coded using one bit each (0 and 1).
33 5. There is no way of sending zero distance codes--a dummy must be
34 sent if there are none. (History: a pre 2.0 version of PKZIP would
35 store blocks with no distance codes, but this was discovered to be
36 too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
37 zero distance codes, which is sent as one code of zero bits in
38 length.
39 6. There are up to 286 literal/length codes. Code 256 represents the
40 end-of-block. Note however that the static length tree defines
41 288 codes just to fill out the Huffman codes. Codes 286 and 287
42 cannot be used though, since there is no length base or extra bits
43 defined for them. Similarily, there are up to 30 distance codes.
44 However, static trees define 32 codes (all 5 bits) to fill out the
45 Huffman codes, but the last two had better not show up in the data.
46 7. Unzip can check dynamic Huffman blocks for complete code sets.
47 The exception is that a single code would not be complete (see #4).
48 8. The five bits following the block type is really the number of
49 literal codes sent minus 257.
50 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
51 (1+6+6). Therefore, to output three times the length, you output
52 three codes (1+1+1), whereas to output four times the same length,
53 you only need two codes (1+3). Hmm.
54 10. In the tree reconstruction algorithm, Code = Code + Increment
55 only if BitLength(i) is not zero. (Pretty obvious.)
56 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
57 12. Note: length code 284 can represent 227-258, but length code 285
58 really is 258. The last length deserves its own, short code
59 since it gets used a lot in very redundant files. The length
60 258 is special since 258 - 3 (the min match length) is 255.
61 13. The literal/length and distance code bit lengths are read as a
62 single stream of lengths. It is possible (and advantageous) for
63 a repeat code (16, 17, or 18) to go across the boundary between
64 the two sets of lengths.
65 */
66
67
68void zlib_inflate_blocks_reset(
69 inflate_blocks_statef *s,
70 z_streamp z,
71 uLong *c
72)
73{
74 if (c != NULL)
75 *c = s->check;
76 if (s->mode == CODES)
77 zlib_inflate_codes_free(s->sub.decode.codes, z);
78 s->mode = TYPE;
79 s->bitk = 0;
80 s->bitb = 0;
81 s->read = s->write = s->window;
82 if (s->checkfn != NULL)
83 z->adler = s->check = (*s->checkfn)(0L, NULL, 0);
84}
85
86inflate_blocks_statef *zlib_inflate_blocks_new(
87 z_streamp z,
88 check_func c,
89 uInt w
90)
91{
92 inflate_blocks_statef *s;
93
94 s = &WS(z)->working_blocks_state;
95 s->hufts = WS(z)->working_hufts;
96 s->window = WS(z)->working_window;
97 s->end = s->window + w;
98 s->checkfn = c;
99 s->mode = TYPE;
100 zlib_inflate_blocks_reset(s, z, NULL);
101 return s;
102}
103
104
105int zlib_inflate_blocks(
106 inflate_blocks_statef *s,
107 z_streamp z,
108 int r
109)
110{
111 uInt t; /* temporary storage */
112 uLong b; /* bit buffer */
113 uInt k; /* bits in bit buffer */
114 Byte *p; /* input data pointer */
115 uInt n; /* bytes available there */
116 Byte *q; /* output window write pointer */
117 uInt m; /* bytes to end of window or read pointer */
118
119 /* copy input/output information to locals (UPDATE macro restores) */
120 LOAD
121
122 /* process input based on current state */
123 while (1) switch (s->mode)
124 {
125 case TYPE:
126 NEEDBITS(3)
127 t = (uInt)b & 7;
128 s->last = t & 1;
129 switch (t >> 1)
130 {
131 case 0: /* stored */
132 DUMPBITS(3)
133 t = k & 7; /* go to byte boundary */
134 DUMPBITS(t)
135 s->mode = LENS; /* get length of stored block */
136 break;
137 case 1: /* fixed */
138 {
139 uInt bl, bd;
140 inflate_huft *tl, *td;
141
142 zlib_inflate_trees_fixed(&bl, &bd, &tl, &td, s->hufts, z);
143 s->sub.decode.codes = zlib_inflate_codes_new(bl, bd, tl, td, z);
144 if (s->sub.decode.codes == NULL)
145 {
146 r = Z_MEM_ERROR;
147 LEAVE
148 }
149 }
150 DUMPBITS(3)
151 s->mode = CODES;
152 break;
153 case 2: /* dynamic */
154 DUMPBITS(3)
155 s->mode = TABLE;
156 break;
157 case 3: /* illegal */
158 DUMPBITS(3)
159 s->mode = B_BAD;
160 z->msg = (char*)"invalid block type";
161 r = Z_DATA_ERROR;
162 LEAVE
163 }
164 break;
165 case LENS:
166 NEEDBITS(32)
167 if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
168 {
169 s->mode = B_BAD;
170 z->msg = (char*)"invalid stored block lengths";
171 r = Z_DATA_ERROR;
172 LEAVE
173 }
174 s->sub.left = (uInt)b & 0xffff;
175 b = k = 0; /* dump bits */
176 s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
177 break;
178 case STORED:
179 if (n == 0)
180 LEAVE
181 NEEDOUT
182 t = s->sub.left;
183 if (t > n) t = n;
184 if (t > m) t = m;
185 memcpy(q, p, t);
186 p += t; n -= t;
187 q += t; m -= t;
188 if ((s->sub.left -= t) != 0)
189 break;
190 s->mode = s->last ? DRY : TYPE;
191 break;
192 case TABLE:
193 NEEDBITS(14)
194 s->sub.trees.table = t = (uInt)b & 0x3fff;
195#ifndef PKZIP_BUG_WORKAROUND
196 if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
197 {
198 s->mode = B_BAD;
199 z->msg = (char*)"too many length or distance symbols";
200 r = Z_DATA_ERROR;
201 LEAVE
202 }
203#endif
204 {
205 s->sub.trees.blens = WS(z)->working_blens;
206 }
207 DUMPBITS(14)
208 s->sub.trees.index = 0;
209 s->mode = BTREE;
210 case BTREE:
211 while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
212 {
213 NEEDBITS(3)
214 s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
215 DUMPBITS(3)
216 }
217 while (s->sub.trees.index < 19)
218 s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
219 s->sub.trees.bb = 7;
220 t = zlib_inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
221 &s->sub.trees.tb, s->hufts, z);
222 if (t != Z_OK)
223 {
224 r = t;
225 if (r == Z_DATA_ERROR)
226 s->mode = B_BAD;
227 LEAVE
228 }
229 s->sub.trees.index = 0;
230 s->mode = DTREE;
231 case DTREE:
232 while (t = s->sub.trees.table,
233 s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
234 {
235 inflate_huft *h;
236 uInt i, j, c;
237
238 t = s->sub.trees.bb;
239 NEEDBITS(t)
240 h = s->sub.trees.tb + ((uInt)b & zlib_inflate_mask[t]);
241 t = h->bits;
242 c = h->base;
243 if (c < 16)
244 {
245 DUMPBITS(t)
246 s->sub.trees.blens[s->sub.trees.index++] = c;
247 }
248 else /* c == 16..18 */
249 {
250 i = c == 18 ? 7 : c - 14;
251 j = c == 18 ? 11 : 3;
252 NEEDBITS(t + i)
253 DUMPBITS(t)
254 j += (uInt)b & zlib_inflate_mask[i];
255 DUMPBITS(i)
256 i = s->sub.trees.index;
257 t = s->sub.trees.table;
258 if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
259 (c == 16 && i < 1))
260 {
261 s->mode = B_BAD;
262 z->msg = (char*)"invalid bit length repeat";
263 r = Z_DATA_ERROR;
264 LEAVE
265 }
266 c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
267 do {
268 s->sub.trees.blens[i++] = c;
269 } while (--j);
270 s->sub.trees.index = i;
271 }
272 }
273 s->sub.trees.tb = NULL;
274 {
275 uInt bl, bd;
276 inflate_huft *tl, *td;
277 inflate_codes_statef *c;
278
279 bl = 9; /* must be <= 9 for lookahead assumptions */
280 bd = 6; /* must be <= 9 for lookahead assumptions */
281 t = s->sub.trees.table;
282 t = zlib_inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
283 s->sub.trees.blens, &bl, &bd, &tl, &td,
284 s->hufts, z);
285 if (t != Z_OK)
286 {
287 if (t == (uInt)Z_DATA_ERROR)
288 s->mode = B_BAD;
289 r = t;
290 LEAVE
291 }
292 if ((c = zlib_inflate_codes_new(bl, bd, tl, td, z)) == NULL)
293 {
294 r = Z_MEM_ERROR;
295 LEAVE
296 }
297 s->sub.decode.codes = c;
298 }
299 s->mode = CODES;
300 case CODES:
301 UPDATE
302 if ((r = zlib_inflate_codes(s, z, r)) != Z_STREAM_END)
303 return zlib_inflate_flush(s, z, r);
304 r = Z_OK;
305 zlib_inflate_codes_free(s->sub.decode.codes, z);
306 LOAD
307 if (!s->last)
308 {
309 s->mode = TYPE;
310 break;
311 }
312 s->mode = DRY;
313 case DRY:
314 FLUSH
315 if (s->read != s->write)
316 LEAVE
317 s->mode = B_DONE;
318 case B_DONE:
319 r = Z_STREAM_END;
320 LEAVE
321 case B_BAD:
322 r = Z_DATA_ERROR;
323 LEAVE
324 default:
325 r = Z_STREAM_ERROR;
326 LEAVE
327 }
328}
329
330
331int zlib_inflate_blocks_free(
332 inflate_blocks_statef *s,
333 z_streamp z
334)
335{
336 zlib_inflate_blocks_reset(s, z, NULL);
337 return Z_OK;
338}
339
340
341#if 0
342void zlib_inflate_set_dictionary(
343 inflate_blocks_statef *s,
344 const Byte *d,
345 uInt n
346)
347{
348 memcpy(s->window, d, n);
349 s->read = s->write = s->window + n;
350}
351#endif /* 0 */
352
353
354/* Returns true if inflate is currently at the end of a block generated
355 * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
356 * IN assertion: s != NULL
357 */
358#if 0
359int zlib_inflate_blocks_sync_point(
360 inflate_blocks_statef *s
361)
362{
363 return s->mode == LENS;
364}
365#endif /* 0 */
diff --git a/lib/zlib_inflate/infblock.h b/lib/zlib_inflate/infblock.h
deleted file mode 100644
index ceee60b5107c..000000000000
--- a/lib/zlib_inflate/infblock.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/* infblock.h -- header to use infblock.c
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/* WARNING: this file should *not* be used by applications. It is
7 part of the implementation of the compression library and is
8 subject to change. Applications should only use zlib.h.
9 */
10
11#ifndef _INFBLOCK_H
12#define _INFBLOCK_H
13
14struct inflate_blocks_state;
15typedef struct inflate_blocks_state inflate_blocks_statef;
16
17extern inflate_blocks_statef * zlib_inflate_blocks_new (
18 z_streamp z,
19 check_func c, /* check function */
20 uInt w); /* window size */
21
22extern int zlib_inflate_blocks (
23 inflate_blocks_statef *,
24 z_streamp ,
25 int); /* initial return code */
26
27extern void zlib_inflate_blocks_reset (
28 inflate_blocks_statef *,
29 z_streamp ,
30 uLong *); /* check value on output */
31
32extern int zlib_inflate_blocks_free (
33 inflate_blocks_statef *,
34 z_streamp);
35
36#if 0
37extern void zlib_inflate_set_dictionary (
38 inflate_blocks_statef *s,
39 const Byte *d, /* dictionary */
40 uInt n); /* dictionary length */
41#endif /* 0 */
42
43#if 0
44extern int zlib_inflate_blocks_sync_point (
45 inflate_blocks_statef *s);
46#endif /* 0 */
47
48#endif /* _INFBLOCK_H */
diff --git a/lib/zlib_inflate/infcodes.c b/lib/zlib_inflate/infcodes.c
deleted file mode 100644
index 07cd7591cbb7..000000000000
--- a/lib/zlib_inflate/infcodes.c
+++ /dev/null
@@ -1,202 +0,0 @@
1/* infcodes.c -- process literals and length/distance pairs
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include <linux/zutil.h>
7#include "inftrees.h"
8#include "infblock.h"
9#include "infcodes.h"
10#include "infutil.h"
11#include "inffast.h"
12
13/* simplify the use of the inflate_huft type with some defines */
14#define exop word.what.Exop
15#define bits word.what.Bits
16
17inflate_codes_statef *zlib_inflate_codes_new(
18 uInt bl,
19 uInt bd,
20 inflate_huft *tl,
21 inflate_huft *td, /* need separate declaration for Borland C++ */
22 z_streamp z
23)
24{
25 inflate_codes_statef *c;
26
27 c = &WS(z)->working_state;
28 {
29 c->mode = START;
30 c->lbits = (Byte)bl;
31 c->dbits = (Byte)bd;
32 c->ltree = tl;
33 c->dtree = td;
34 }
35 return c;
36}
37
38
39int zlib_inflate_codes(
40 inflate_blocks_statef *s,
41 z_streamp z,
42 int r
43)
44{
45 uInt j; /* temporary storage */
46 inflate_huft *t; /* temporary pointer */
47 uInt e; /* extra bits or operation */
48 uLong b; /* bit buffer */
49 uInt k; /* bits in bit buffer */
50 Byte *p; /* input data pointer */
51 uInt n; /* bytes available there */
52 Byte *q; /* output window write pointer */
53 uInt m; /* bytes to end of window or read pointer */
54 Byte *f; /* pointer to copy strings from */
55 inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
56
57 /* copy input/output information to locals (UPDATE macro restores) */
58 LOAD
59
60 /* process input and output based on current state */
61 while (1) switch (c->mode)
62 { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
63 case START: /* x: set up for LEN */
64#ifndef SLOW
65 if (m >= 258 && n >= 10)
66 {
67 UPDATE
68 r = zlib_inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
69 LOAD
70 if (r != Z_OK)
71 {
72 c->mode = r == Z_STREAM_END ? WASH : BADCODE;
73 break;
74 }
75 }
76#endif /* !SLOW */
77 c->sub.code.need = c->lbits;
78 c->sub.code.tree = c->ltree;
79 c->mode = LEN;
80 case LEN: /* i: get length/literal/eob next */
81 j = c->sub.code.need;
82 NEEDBITS(j)
83 t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]);
84 DUMPBITS(t->bits)
85 e = (uInt)(t->exop);
86 if (e == 0) /* literal */
87 {
88 c->sub.lit = t->base;
89 c->mode = LIT;
90 break;
91 }
92 if (e & 16) /* length */
93 {
94 c->sub.copy.get = e & 15;
95 c->len = t->base;
96 c->mode = LENEXT;
97 break;
98 }
99 if ((e & 64) == 0) /* next table */
100 {
101 c->sub.code.need = e;
102 c->sub.code.tree = t + t->base;
103 break;
104 }
105 if (e & 32) /* end of block */
106 {
107 c->mode = WASH;
108 break;
109 }
110 c->mode = BADCODE; /* invalid code */
111 z->msg = (char*)"invalid literal/length code";
112 r = Z_DATA_ERROR;
113 LEAVE
114 case LENEXT: /* i: getting length extra (have base) */
115 j = c->sub.copy.get;
116 NEEDBITS(j)
117 c->len += (uInt)b & zlib_inflate_mask[j];
118 DUMPBITS(j)
119 c->sub.code.need = c->dbits;
120 c->sub.code.tree = c->dtree;
121 c->mode = DIST;
122 case DIST: /* i: get distance next */
123 j = c->sub.code.need;
124 NEEDBITS(j)
125 t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]);
126 DUMPBITS(t->bits)
127 e = (uInt)(t->exop);
128 if (e & 16) /* distance */
129 {
130 c->sub.copy.get = e & 15;
131 c->sub.copy.dist = t->base;
132 c->mode = DISTEXT;
133 break;
134 }
135 if ((e & 64) == 0) /* next table */
136 {
137 c->sub.code.need = e;
138 c->sub.code.tree = t + t->base;
139 break;
140 }
141 c->mode = BADCODE; /* invalid code */
142 z->msg = (char*)"invalid distance code";
143 r = Z_DATA_ERROR;
144 LEAVE
145 case DISTEXT: /* i: getting distance extra */
146 j = c->sub.copy.get;
147 NEEDBITS(j)
148 c->sub.copy.dist += (uInt)b & zlib_inflate_mask[j];
149 DUMPBITS(j)
150 c->mode = COPY;
151 case COPY: /* o: copying bytes in window, waiting for space */
152 f = q - c->sub.copy.dist;
153 while (f < s->window) /* modulo window size-"while" instead */
154 f += s->end - s->window; /* of "if" handles invalid distances */
155 while (c->len)
156 {
157 NEEDOUT
158 OUTBYTE(*f++)
159 if (f == s->end)
160 f = s->window;
161 c->len--;
162 }
163 c->mode = START;
164 break;
165 case LIT: /* o: got literal, waiting for output space */
166 NEEDOUT
167 OUTBYTE(c->sub.lit)
168 c->mode = START;
169 break;
170 case WASH: /* o: got eob, possibly more output */
171 if (k > 7) /* return unused byte, if any */
172 {
173 k -= 8;
174 n++;
175 p--; /* can always return one */
176 }
177 FLUSH
178 if (s->read != s->write)
179 LEAVE
180 c->mode = END;
181 case END:
182 r = Z_STREAM_END;
183 LEAVE
184 case BADCODE: /* x: got error */
185 r = Z_DATA_ERROR;
186 LEAVE
187 default:
188 r = Z_STREAM_ERROR;
189 LEAVE
190 }
191#ifdef NEED_DUMMY_RETURN
192 return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
193#endif
194}
195
196
197void zlib_inflate_codes_free(
198 inflate_codes_statef *c,
199 z_streamp z
200)
201{
202}
diff --git a/lib/zlib_inflate/infcodes.h b/lib/zlib_inflate/infcodes.h
deleted file mode 100644
index 5cff417523b0..000000000000
--- a/lib/zlib_inflate/infcodes.h
+++ /dev/null
@@ -1,33 +0,0 @@
1/* infcodes.h -- header to use infcodes.c
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/* WARNING: this file should *not* be used by applications. It is
7 part of the implementation of the compression library and is
8 subject to change. Applications should only use zlib.h.
9 */
10
11#ifndef _INFCODES_H
12#define _INFCODES_H
13
14#include "infblock.h"
15
16struct inflate_codes_state;
17typedef struct inflate_codes_state inflate_codes_statef;
18
19extern inflate_codes_statef *zlib_inflate_codes_new (
20 uInt, uInt,
21 inflate_huft *, inflate_huft *,
22 z_streamp );
23
24extern int zlib_inflate_codes (
25 inflate_blocks_statef *,
26 z_streamp ,
27 int);
28
29extern void zlib_inflate_codes_free (
30 inflate_codes_statef *,
31 z_streamp );
32
33#endif /* _INFCODES_H */
diff --git a/lib/zlib_inflate/inffast.c b/lib/zlib_inflate/inffast.c
index 0bd7623fc85a..02a16eacb72d 100644
--- a/lib/zlib_inflate/inffast.c
+++ b/lib/zlib_inflate/inffast.c
@@ -1,176 +1,312 @@
1/* inffast.c -- process literals and length/distance pairs fast 1/* inffast.c -- fast decoding
2 * Copyright (C) 1995-1998 Mark Adler 2 * Copyright (C) 1995-2004 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
6#include <linux/zutil.h> 6#include <linux/zutil.h>
7#include "inftrees.h" 7#include "inftrees.h"
8#include "infblock.h" 8#include "inflate.h"
9#include "infcodes.h"
10#include "infutil.h"
11#include "inffast.h" 9#include "inffast.h"
12 10
13struct inflate_codes_state; 11#ifndef ASMINF
14 12
15/* simplify the use of the inflate_huft type with some defines */ 13/* Allow machine dependent optimization for post-increment or pre-increment.
16#define exop word.what.Exop 14 Based on testing to date,
17#define bits word.what.Bits 15 Pre-increment preferred for:
18 16 - PowerPC G3 (Adler)
19/* macros for bit input with no checking and for returning unused bytes */ 17 - MIPS R5000 (Randers-Pehrson)
20#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} 18 Post-increment preferred for:
21#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;} 19 - none
22 20 No measurable difference:
23/* Called with number of bytes left to write in window at least 258 21 - Pentium III (Anderson)
24 (the maximum string length) and number of input bytes available 22 - M68060 (Nikl)
25 at least ten. The ten bytes are six bytes for the longest length/ 23 */
26 distance pair plus four bytes for overloading the bit buffer. */ 24#ifdef POSTINC
27 25# define OFF 0
28int zlib_inflate_fast( 26# define PUP(a) *(a)++
29 uInt bl, 27#else
30 uInt bd, 28# define OFF 1
31 inflate_huft *tl, 29# define PUP(a) *++(a)
32 inflate_huft *td, /* need separate declaration for Borland C++ */ 30#endif
33 inflate_blocks_statef *s, 31
34 z_streamp z 32/*
35) 33 Decode literal, length, and distance codes and write out the resulting
34 literal and match bytes until either not enough input or output is
35 available, an end-of-block is encountered, or a data error is encountered.
36 When large enough input and output buffers are supplied to inflate(), for
37 example, a 16K input buffer and a 64K output buffer, more than 95% of the
38 inflate execution time is spent in this routine.
39
40 Entry assumptions:
41
42 state->mode == LEN
43 strm->avail_in >= 6
44 strm->avail_out >= 258
45 start >= strm->avail_out
46 state->bits < 8
47
48 On return, state->mode is one of:
49
50 LEN -- ran out of enough output space or enough available input
51 TYPE -- reached end of block code, inflate() to interpret next block
52 BAD -- error in block data
53
54 Notes:
55
56 - The maximum input bits used by a length/distance pair is 15 bits for the
57 length code, 5 bits for the length extra, 15 bits for the distance code,
58 and 13 bits for the distance extra. This totals 48 bits, or six bytes.
59 Therefore if strm->avail_in >= 6, then there is enough input to avoid
60 checking for available input while decoding.
61
62 - The maximum bytes that a single length/distance pair can output is 258
63 bytes, which is the maximum length that can be coded. inflate_fast()
64 requires strm->avail_out >= 258 for each loop to avoid checking for
65 output space.
66 */
67void inflate_fast(strm, start)
68z_streamp strm;
69unsigned start; /* inflate()'s starting value for strm->avail_out */
36{ 70{
37 inflate_huft *t; /* temporary pointer */ 71 struct inflate_state *state;
38 uInt e; /* extra bits or operation */ 72 unsigned char *in; /* local strm->next_in */
39 uLong b; /* bit buffer */ 73 unsigned char *last; /* while in < last, enough input available */
40 uInt k; /* bits in bit buffer */ 74 unsigned char *out; /* local strm->next_out */
41 Byte *p; /* input data pointer */ 75 unsigned char *beg; /* inflate()'s initial strm->next_out */
42 uInt n; /* bytes available there */ 76 unsigned char *end; /* while out < end, enough space available */
43 Byte *q; /* output window write pointer */ 77#ifdef INFLATE_STRICT
44 uInt m; /* bytes to end of window or read pointer */ 78 unsigned dmax; /* maximum distance from zlib header */
45 uInt ml; /* mask for literal/length tree */ 79#endif
46 uInt md; /* mask for distance tree */ 80 unsigned wsize; /* window size or zero if not using window */
47 uInt c; /* bytes to copy */ 81 unsigned whave; /* valid bytes in the window */
48 uInt d; /* distance back to copy from */ 82 unsigned write; /* window write index */
49 Byte *r; /* copy source pointer */ 83 unsigned char *window; /* allocated sliding window, if wsize != 0 */
50 84 unsigned long hold; /* local strm->hold */
51 /* load input, output, bit values */ 85 unsigned bits; /* local strm->bits */
52 LOAD 86 code const *lcode; /* local strm->lencode */
53 87 code const *dcode; /* local strm->distcode */
54 /* initialize masks */ 88 unsigned lmask; /* mask for first level of length codes */
55 ml = zlib_inflate_mask[bl]; 89 unsigned dmask; /* mask for first level of distance codes */
56 md = zlib_inflate_mask[bd]; 90 code this; /* retrieved table entry */
57 91 unsigned op; /* code bits, operation, extra bits, or */
58 /* do until not enough input or output space for fast loop */ 92 /* window position, window bytes to copy */
59 do { /* assume called with m >= 258 && n >= 10 */ 93 unsigned len; /* match length, unused bytes */
60 /* get literal/length code */ 94 unsigned dist; /* match distance */
61 GRABBITS(20) /* max bits for literal/length code */ 95 unsigned char *from; /* where to copy match from */
62 if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) 96
63 { 97 /* copy state to local variables */
64 DUMPBITS(t->bits) 98 state = (struct inflate_state *)strm->state;
65 *q++ = (Byte)t->base; 99 in = strm->next_in - OFF;
66 m--; 100 last = in + (strm->avail_in - 5);
67 continue; 101 out = strm->next_out - OFF;
68 } 102 beg = out - (start - strm->avail_out);
103 end = out + (strm->avail_out - 257);
104#ifdef INFLATE_STRICT
105 dmax = state->dmax;
106#endif
107 wsize = state->wsize;
108 whave = state->whave;
109 write = state->write;
110 window = state->window;
111 hold = state->hold;
112 bits = state->bits;
113 lcode = state->lencode;
114 dcode = state->distcode;
115 lmask = (1U << state->lenbits) - 1;
116 dmask = (1U << state->distbits) - 1;
117
118 /* decode literals and length/distances until end-of-block or not enough
119 input data or output space */
69 do { 120 do {
70 DUMPBITS(t->bits) 121 if (bits < 15) {
71 if (e & 16) 122 hold += (unsigned long)(PUP(in)) << bits;
72 { 123 bits += 8;
73 /* get extra bits for length */ 124 hold += (unsigned long)(PUP(in)) << bits;
74 e &= 15; 125 bits += 8;
75 c = t->base + ((uInt)b & zlib_inflate_mask[e]); 126 }
76 DUMPBITS(e) 127 this = lcode[hold & lmask];
77 128 dolen:
78 /* decode distance base of block to copy */ 129 op = (unsigned)(this.bits);
79 GRABBITS(15); /* max bits for distance code */ 130 hold >>= op;
80 e = (t = td + ((uInt)b & md))->exop; 131 bits -= op;
81 do { 132 op = (unsigned)(this.op);
82 DUMPBITS(t->bits) 133 if (op == 0) { /* literal */
83 if (e & 16) 134 PUP(out) = (unsigned char)(this.val);
84 { 135 }
85 /* get extra bits to add to distance base */ 136 else if (op & 16) { /* length base */
86 e &= 15; 137 len = (unsigned)(this.val);
87 GRABBITS(e) /* get extra bits (up to 13) */ 138 op &= 15; /* number of extra bits */
88 d = t->base + ((uInt)b & zlib_inflate_mask[e]); 139 if (op) {
89 DUMPBITS(e) 140 if (bits < op) {
90 141 hold += (unsigned long)(PUP(in)) << bits;
91 /* do the copy */ 142 bits += 8;
92 m -= c; 143 }
93 r = q - d; 144 len += (unsigned)hold & ((1U << op) - 1);
94 if (r < s->window) /* wrap if needed */ 145 hold >>= op;
95 { 146 bits -= op;
96 do { 147 }
97 r += s->end - s->window; /* force pointer in window */ 148 if (bits < 15) {
98 } while (r < s->window); /* covers invalid distances */ 149 hold += (unsigned long)(PUP(in)) << bits;
99 e = s->end - r; 150 bits += 8;
100 if (c > e) 151 hold += (unsigned long)(PUP(in)) << bits;
101 { 152 bits += 8;
102 c -= e; /* wrapped copy */ 153 }
103 do { 154 this = dcode[hold & dmask];
104 *q++ = *r++; 155 dodist:
105 } while (--e); 156 op = (unsigned)(this.bits);
106 r = s->window; 157 hold >>= op;
107 do { 158 bits -= op;
108 *q++ = *r++; 159 op = (unsigned)(this.op);
109 } while (--c); 160 if (op & 16) { /* distance base */
110 } 161 dist = (unsigned)(this.val);
111 else /* normal copy */ 162 op &= 15; /* number of extra bits */
112 { 163 if (bits < op) {
113 *q++ = *r++; c--; 164 hold += (unsigned long)(PUP(in)) << bits;
114 *q++ = *r++; c--; 165 bits += 8;
115 do { 166 if (bits < op) {
116 *q++ = *r++; 167 hold += (unsigned long)(PUP(in)) << bits;
117 } while (--c); 168 bits += 8;
118 } 169 }
170 }
171 dist += (unsigned)hold & ((1U << op) - 1);
172#ifdef INFLATE_STRICT
173 if (dist > dmax) {
174 strm->msg = (char *)"invalid distance too far back";
175 state->mode = BAD;
176 break;
177 }
178#endif
179 hold >>= op;
180 bits -= op;
181 op = (unsigned)(out - beg); /* max distance in output */
182 if (dist > op) { /* see if copy from window */
183 op = dist - op; /* distance back in window */
184 if (op > whave) {
185 strm->msg = (char *)"invalid distance too far back";
186 state->mode = BAD;
187 break;
188 }
189 from = window - OFF;
190 if (write == 0) { /* very common case */
191 from += wsize - op;
192 if (op < len) { /* some from window */
193 len -= op;
194 do {
195 PUP(out) = PUP(from);
196 } while (--op);
197 from = out - dist; /* rest from output */
198 }
199 }
200 else if (write < op) { /* wrap around window */
201 from += wsize + write - op;
202 op -= write;
203 if (op < len) { /* some from end of window */
204 len -= op;
205 do {
206 PUP(out) = PUP(from);
207 } while (--op);
208 from = window - OFF;
209 if (write < len) { /* some from start of window */
210 op = write;
211 len -= op;
212 do {
213 PUP(out) = PUP(from);
214 } while (--op);
215 from = out - dist; /* rest from output */
216 }
217 }
218 }
219 else { /* contiguous in window */
220 from += write - op;
221 if (op < len) { /* some from window */
222 len -= op;
223 do {
224 PUP(out) = PUP(from);
225 } while (--op);
226 from = out - dist; /* rest from output */
227 }
228 }
229 while (len > 2) {
230 PUP(out) = PUP(from);
231 PUP(out) = PUP(from);
232 PUP(out) = PUP(from);
233 len -= 3;
234 }
235 if (len) {
236 PUP(out) = PUP(from);
237 if (len > 1)
238 PUP(out) = PUP(from);
239 }
240 }
241 else {
242 from = out - dist; /* copy direct from output */
243 do { /* minimum length is three */
244 PUP(out) = PUP(from);
245 PUP(out) = PUP(from);
246 PUP(out) = PUP(from);
247 len -= 3;
248 } while (len > 2);
249 if (len) {
250 PUP(out) = PUP(from);
251 if (len > 1)
252 PUP(out) = PUP(from);
253 }
254 }
255 }
256 else if ((op & 64) == 0) { /* 2nd level distance code */
257 this = dcode[this.val + (hold & ((1U << op) - 1))];
258 goto dodist;
119 } 259 }
120 else /* normal copy */ 260 else {
121 { 261 strm->msg = (char *)"invalid distance code";
122 *q++ = *r++; c--; 262 state->mode = BAD;
123 *q++ = *r++; c--; 263 break;
124 do {
125 *q++ = *r++;
126 } while (--c);
127 } 264 }
265 }
266 else if ((op & 64) == 0) { /* 2nd level length code */
267 this = lcode[this.val + (hold & ((1U << op) - 1))];
268 goto dolen;
269 }
270 else if (op & 32) { /* end-of-block */
271 state->mode = TYPE;
128 break; 272 break;
129 }
130 else if ((e & 64) == 0)
131 {
132 t += t->base;
133 e = (t += ((uInt)b & zlib_inflate_mask[e]))->exop;
134 }
135 else
136 {
137 z->msg = (char*)"invalid distance code";
138 UNGRAB
139 UPDATE
140 return Z_DATA_ERROR;
141 }
142 } while (1);
143 break;
144 }
145 if ((e & 64) == 0)
146 {
147 t += t->base;
148 if ((e = (t += ((uInt)b & zlib_inflate_mask[e]))->exop) == 0)
149 {
150 DUMPBITS(t->bits)
151 *q++ = (Byte)t->base;
152 m--;
153 break;
154 } 273 }
155 } 274 else {
156 else if (e & 32) 275 strm->msg = (char *)"invalid literal/length code";
157 { 276 state->mode = BAD;
158 UNGRAB 277 break;
159 UPDATE 278 }
160 return Z_STREAM_END; 279 } while (in < last && out < end);
161 } 280
162 else 281 /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
163 { 282 len = bits >> 3;
164 z->msg = (char*)"invalid literal/length code"; 283 in -= len;
165 UNGRAB 284 bits -= len << 3;
166 UPDATE 285 hold &= (1U << bits) - 1;
167 return Z_DATA_ERROR; 286
168 } 287 /* update state and return */
169 } while (1); 288 strm->next_in = in + OFF;
170 } while (m >= 258 && n >= 10); 289 strm->next_out = out + OFF;
171 290 strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
172 /* not enough input or output--restore pointers and return */ 291 strm->avail_out = (unsigned)(out < end ?
173 UNGRAB 292 257 + (end - out) : 257 - (out - end));
174 UPDATE 293 state->hold = hold;
175 return Z_OK; 294 state->bits = bits;
295 return;
176} 296}
297
298/*
299 inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
300 - Using bit fields for code structure
301 - Different op definition to avoid & for extra bits (do & for table bits)
302 - Three separate decoding do-loops for direct, window, and write == 0
303 - Special case for distance > 1 copies to do overlapped load and store copy
304 - Explicit branch predictions (based on measured branch probabilities)
305 - Deferring match copy and interspersed it with decoding subsequent codes
306 - Swapping literal/length else
307 - Swapping window/direct else
308 - Larger unrolled copy loops (three is about right)
309 - Moving len -= 3 statement into middle of loop
310 */
311
312#endif /* !ASMINF */
diff --git a/lib/zlib_inflate/inffast.h b/lib/zlib_inflate/inffast.h
index fc720f0fa7f5..40315d9fddc4 100644
--- a/lib/zlib_inflate/inffast.h
+++ b/lib/zlib_inflate/inffast.h
@@ -1,6 +1,6 @@
1/* inffast.h -- header to use inffast.c 1/* inffast.h -- header to use inffast.c
2 * Copyright (C) 1995-1998 Mark Adler 2 * Copyright (C) 1995-2003 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
6/* WARNING: this file should *not* be used by applications. It is 6/* WARNING: this file should *not* be used by applications. It is
@@ -8,10 +8,4 @@
8 subject to change. Applications should only use zlib.h. 8 subject to change. Applications should only use zlib.h.
9 */ 9 */
10 10
11extern int zlib_inflate_fast ( 11void inflate_fast (z_streamp strm, unsigned start);
12 uInt,
13 uInt,
14 inflate_huft *,
15 inflate_huft *,
16 inflate_blocks_statef *,
17 z_streamp );
diff --git a/lib/zlib_inflate/inffixed.h b/lib/zlib_inflate/inffixed.h
new file mode 100644
index 000000000000..75ed4b5978de
--- /dev/null
+++ b/lib/zlib_inflate/inffixed.h
@@ -0,0 +1,94 @@
1 /* inffixed.h -- table for decoding fixed codes
2 * Generated automatically by makefixed().
3 */
4
5 /* WARNING: this file should *not* be used by applications. It
6 is part of the implementation of the compression library and
7 is subject to change. Applications should only use zlib.h.
8 */
9
10 static const code lenfix[512] = {
11 {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
12 {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
13 {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
14 {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
15 {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
16 {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
17 {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
18 {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
19 {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
20 {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
21 {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
22 {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
23 {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
24 {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
25 {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
26 {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
27 {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
28 {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
29 {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
30 {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
31 {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
32 {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
33 {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
34 {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
35 {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
36 {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
37 {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
38 {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
39 {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
40 {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
41 {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
42 {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
43 {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
44 {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
45 {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
46 {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
47 {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
48 {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
49 {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
50 {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
51 {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
52 {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
53 {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
54 {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
55 {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
56 {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
57 {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
58 {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
59 {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
60 {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
61 {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
62 {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
63 {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
64 {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
65 {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
66 {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
67 {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
68 {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
69 {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
70 {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
71 {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
72 {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
73 {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
74 {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
75 {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
76 {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
77 {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
78 {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
79 {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
80 {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
81 {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
82 {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
83 {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
84 {0,9,255}
85 };
86
87 static const code distfix[32] = {
88 {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
89 {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
90 {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
91 {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
92 {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
93 {22,5,193},{64,5,0}
94 };
diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c
index 31b9e9054bf7..7f922dccf1a5 100644
--- a/lib/zlib_inflate/inflate.c
+++ b/lib/zlib_inflate/inflate.c
@@ -1,89 +1,148 @@
1/* inflate.c -- zlib interface to inflate modules 1/* inflate.c -- zlib decompression
2 * Copyright (C) 1995-1998 Mark Adler 2 * Copyright (C) 1995-2005 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 *
5 * Based on zlib 1.2.3 but modified for the Linux Kernel by
6 * Richard Purdie <richard@openedhand.com>
7 *
8 * Changes mainly for static instead of dynamic memory allocation
9 *
4 */ 10 */
5 11
6#include <linux/zutil.h> 12#include <linux/zutil.h>
7#include "infblock.h" 13#include "inftrees.h"
14#include "inflate.h"
15#include "inffast.h"
8#include "infutil.h" 16#include "infutil.h"
9 17
10int zlib_inflate_workspacesize(void) 18int zlib_inflate_workspacesize(void)
11{ 19{
12 return sizeof(struct inflate_workspace); 20 return sizeof(struct inflate_workspace);
13} 21}
14 22
23int zlib_inflateReset(z_streamp strm)
24{
25 struct inflate_state *state;
26
27 if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
28 state = (struct inflate_state *)strm->state;
29 strm->total_in = strm->total_out = state->total = 0;
30 strm->msg = NULL;
31 strm->adler = 1; /* to support ill-conceived Java test suite */
32 state->mode = HEAD;
33 state->last = 0;
34 state->havedict = 0;
35 state->dmax = 32768U;
36 state->hold = 0;
37 state->bits = 0;
38 state->lencode = state->distcode = state->next = state->codes;
15 39
16int zlib_inflateReset( 40 /* Initialise Window */
17 z_streamp z 41 state->wsize = 1U << state->wbits;
18) 42 state->write = 0;
43 state->whave = 0;
44
45 return Z_OK;
46}
47
48#if 0
49int zlib_inflatePrime(z_streamp strm, int bits, int value)
19{ 50{
20 if (z == NULL || z->state == NULL || z->workspace == NULL) 51 struct inflate_state *state;
21 return Z_STREAM_ERROR; 52
22 z->total_in = z->total_out = 0; 53 if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
23 z->msg = NULL; 54 state = (struct inflate_state *)strm->state;
24 z->state->mode = z->state->nowrap ? BLOCKS : METHOD; 55 if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
25 zlib_inflate_blocks_reset(z->state->blocks, z, NULL); 56 value &= (1L << bits) - 1;
26 return Z_OK; 57 state->hold += value << state->bits;
58 state->bits += bits;
59 return Z_OK;
27} 60}
61#endif
62
63int zlib_inflateInit2(z_streamp strm, int windowBits)
64{
65 struct inflate_state *state;
66
67 if (strm == NULL) return Z_STREAM_ERROR;
68 strm->msg = NULL; /* in case we return an error */
69
70 state = &WS(strm)->inflate_state;
71 strm->state = (struct internal_state *)state;
72
73 if (windowBits < 0) {
74 state->wrap = 0;
75 windowBits = -windowBits;
76 }
77 else {
78 state->wrap = (windowBits >> 4) + 1;
79 }
80 if (windowBits < 8 || windowBits > 15) {
81 return Z_STREAM_ERROR;
82 }
83 state->wbits = (unsigned)windowBits;
84 state->window = &WS(strm)->working_window[0];
28 85
86 return zlib_inflateReset(strm);
87}
29 88
30int zlib_inflateEnd( 89/*
31 z_streamp z 90 Return state with length and distance decoding tables and index sizes set to
32) 91 fixed code decoding. This returns fixed tables from inffixed.h.
92 */
93static void zlib_fixedtables(struct inflate_state *state)
33{ 94{
34 if (z == NULL || z->state == NULL || z->workspace == NULL) 95# include "inffixed.h"
35 return Z_STREAM_ERROR; 96 state->lencode = lenfix;
36 if (z->state->blocks != NULL) 97 state->lenbits = 9;
37 zlib_inflate_blocks_free(z->state->blocks, z); 98 state->distcode = distfix;
38 z->state = NULL; 99 state->distbits = 5;
39 return Z_OK;
40} 100}
41 101
42 102
43int zlib_inflateInit2_( 103/*
44 z_streamp z, 104 Update the window with the last wsize (normally 32K) bytes written before
45 int w, 105 returning. This is only called when a window is already in use, or when
46 const char *version, 106 output has been written during this inflate call, but the end of the deflate
47 int stream_size 107 stream has not been reached yet. It is also called to window dictionary data
48) 108 when a dictionary is loaded.
109
110 Providing output buffers larger than 32K to inflate() should provide a speed
111 advantage, since only the last 32K of output is copied to the sliding window
112 upon return from inflate(), and since all distances after the first 32K of
113 output will fall in the output data, making match copies simpler and faster.
114 The advantage may be dependent on the size of the processor's data caches.
115 */
116static void zlib_updatewindow(z_streamp strm, unsigned out)
49{ 117{
50 if (version == NULL || version[0] != ZLIB_VERSION[0] || 118 struct inflate_state *state;
51 stream_size != sizeof(z_stream) || z->workspace == NULL) 119 unsigned copy, dist;
52 return Z_VERSION_ERROR; 120
53 121 state = (struct inflate_state *)strm->state;
54 /* initialize state */ 122
55 z->msg = NULL; 123 /* copy state->wsize or less output bytes into the circular window */
56 z->state = &WS(z)->internal_state; 124 copy = out - strm->avail_out;
57 z->state->blocks = NULL; 125 if (copy >= state->wsize) {
58 126 memcpy(state->window, strm->next_out - state->wsize, state->wsize);
59 /* handle undocumented nowrap option (no zlib header or check) */ 127 state->write = 0;
60 z->state->nowrap = 0; 128 state->whave = state->wsize;
61 if (w < 0) 129 }
62 { 130 else {
63 w = - w; 131 dist = state->wsize - state->write;
64 z->state->nowrap = 1; 132 if (dist > copy) dist = copy;
65 } 133 memcpy(state->window + state->write, strm->next_out - copy, dist);
66 134 copy -= dist;
67 /* set window size */ 135 if (copy) {
68 if (w < 8 || w > 15) 136 memcpy(state->window, strm->next_out - copy, copy);
69 { 137 state->write = copy;
70 zlib_inflateEnd(z); 138 state->whave = state->wsize;
71 return Z_STREAM_ERROR; 139 }
72 } 140 else {
73 z->state->wbits = (uInt)w; 141 state->write += dist;
74 142 if (state->write == state->wsize) state->write = 0;
75 /* create inflate_blocks state */ 143 if (state->whave < state->wsize) state->whave += dist;
76 if ((z->state->blocks = 144 }
77 zlib_inflate_blocks_new(z, z->state->nowrap ? NULL : zlib_adler32, (uInt)1 << w)) 145 }
78 == NULL)
79 {
80 zlib_inflateEnd(z);
81 return Z_MEM_ERROR;
82 }
83
84 /* reset state */
85 zlib_inflateReset(z);
86 return Z_OK;
87} 146}
88 147
89 148
@@ -91,157 +150,764 @@ int zlib_inflateInit2_(
91 * At the end of a Deflate-compressed PPP packet, we expect to have seen 150 * At the end of a Deflate-compressed PPP packet, we expect to have seen
92 * a `stored' block type value but not the (zero) length bytes. 151 * a `stored' block type value but not the (zero) length bytes.
93 */ 152 */
94static int zlib_inflate_packet_flush(inflate_blocks_statef *s) 153/*
154 Returns true if inflate is currently at the end of a block generated by
155 Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
156 implementation to provide an additional safety check. PPP uses
157 Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
158 block. When decompressing, PPP checks that at the end of input packet,
159 inflate is waiting for these length bytes.
160 */
161static int zlib_inflateSyncPacket(z_streamp strm)
95{ 162{
96 if (s->mode != LENS) 163 struct inflate_state *state;
97 return Z_DATA_ERROR; 164
98 s->mode = TYPE; 165 if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
166 state = (struct inflate_state *)strm->state;
167
168 if (state->mode == STORED && state->bits == 0) {
169 state->mode = TYPE;
170 return Z_OK;
171 }
172 return Z_DATA_ERROR;
173}
174
175/* Macros for inflate(): */
176
177/* check function to use adler32() for zlib or crc32() for gzip */
178#define UPDATE(check, buf, len) zlib_adler32(check, buf, len)
179
180/* Load registers with state in inflate() for speed */
181#define LOAD() \
182 do { \
183 put = strm->next_out; \
184 left = strm->avail_out; \
185 next = strm->next_in; \
186 have = strm->avail_in; \
187 hold = state->hold; \
188 bits = state->bits; \
189 } while (0)
190
191/* Restore state from registers in inflate() */
192#define RESTORE() \
193 do { \
194 strm->next_out = put; \
195 strm->avail_out = left; \
196 strm->next_in = next; \
197 strm->avail_in = have; \
198 state->hold = hold; \
199 state->bits = bits; \
200 } while (0)
201
202/* Clear the input bit accumulator */
203#define INITBITS() \
204 do { \
205 hold = 0; \
206 bits = 0; \
207 } while (0)
208
209/* Get a byte of input into the bit accumulator, or return from inflate()
210 if there is no input available. */
211#define PULLBYTE() \
212 do { \
213 if (have == 0) goto inf_leave; \
214 have--; \
215 hold += (unsigned long)(*next++) << bits; \
216 bits += 8; \
217 } while (0)
218
219/* Assure that there are at least n bits in the bit accumulator. If there is
220 not enough available input to do that, then return from inflate(). */
221#define NEEDBITS(n) \
222 do { \
223 while (bits < (unsigned)(n)) \
224 PULLBYTE(); \
225 } while (0)
226
227/* Return the low n bits of the bit accumulator (n < 16) */
228#define BITS(n) \
229 ((unsigned)hold & ((1U << (n)) - 1))
230
231/* Remove n bits from the bit accumulator */
232#define DROPBITS(n) \
233 do { \
234 hold >>= (n); \
235 bits -= (unsigned)(n); \
236 } while (0)
237
238/* Remove zero to seven bits as needed to go to a byte boundary */
239#define BYTEBITS() \
240 do { \
241 hold >>= bits & 7; \
242 bits -= bits & 7; \
243 } while (0)
244
245/* Reverse the bytes in a 32-bit value */
246#define REVERSE(q) \
247 ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
248 (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
249
250/*
251 inflate() uses a state machine to process as much input data and generate as
252 much output data as possible before returning. The state machine is
253 structured roughly as follows:
254
255 for (;;) switch (state) {
256 ...
257 case STATEn:
258 if (not enough input data or output space to make progress)
259 return;
260 ... make progress ...
261 state = STATEm;
262 break;
263 ...
264 }
265
266 so when inflate() is called again, the same case is attempted again, and
267 if the appropriate resources are provided, the machine proceeds to the
268 next state. The NEEDBITS() macro is usually the way the state evaluates
269 whether it can proceed or should return. NEEDBITS() does the return if
270 the requested bits are not available. The typical use of the BITS macros
271 is:
272
273 NEEDBITS(n);
274 ... do something with BITS(n) ...
275 DROPBITS(n);
276
277 where NEEDBITS(n) either returns from inflate() if there isn't enough
278 input left to load n bits into the accumulator, or it continues. BITS(n)
279 gives the low n bits in the accumulator. When done, DROPBITS(n) drops
280 the low n bits off the accumulator. INITBITS() clears the accumulator
281 and sets the number of available bits to zero. BYTEBITS() discards just
282 enough bits to put the accumulator on a byte boundary. After BYTEBITS()
283 and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
284
285 NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
286 if there is no input available. The decoding of variable length codes uses
287 PULLBYTE() directly in order to pull just enough bytes to decode the next
288 code, and no more.
289
290 Some states loop until they get enough input, making sure that enough
291 state information is maintained to continue the loop where it left off
292 if NEEDBITS() returns in the loop. For example, want, need, and keep
293 would all have to actually be part of the saved state in case NEEDBITS()
294 returns:
295
296 case STATEw:
297 while (want < need) {
298 NEEDBITS(n);
299 keep[want++] = BITS(n);
300 DROPBITS(n);
301 }
302 state = STATEx;
303 case STATEx:
304
305 As shown above, if the next state is also the next case, then the break
306 is omitted.
307
308 A state may also return if there is not enough output space available to
309 complete that state. Those states are copying stored data, writing a
310 literal byte, and copying a matching string.
311
312 When returning, a "goto inf_leave" is used to update the total counters,
313 update the check value, and determine whether any progress has been made
314 during that inflate() call in order to return the proper return code.
315 Progress is defined as a change in either strm->avail_in or strm->avail_out.
316 When there is a window, goto inf_leave will update the window with the last
317 output written. If a goto inf_leave occurs in the middle of decompression
318 and there is no window currently, goto inf_leave will create one and copy
319 output to the window for the next call of inflate().
320
321 In this implementation, the flush parameter of inflate() only affects the
322 return code (per zlib.h). inflate() always writes as much as possible to
323 strm->next_out, given the space available and the provided input--the effect
324 documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
325 the allocation of and copying into a sliding window until necessary, which
326 provides the effect documented in zlib.h for Z_FINISH when the entire input
327 stream available. So the only thing the flush parameter actually does is:
328 when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
329 will return Z_BUF_ERROR if it has not reached the end of the stream.
330 */
331
332int zlib_inflate(z_streamp strm, int flush)
333{
334 struct inflate_state *state;
335 unsigned char *next; /* next input */
336 unsigned char *put; /* next output */
337 unsigned have, left; /* available input and output */
338 unsigned long hold; /* bit buffer */
339 unsigned bits; /* bits in bit buffer */
340 unsigned in, out; /* save starting available input and output */
341 unsigned copy; /* number of stored or match bytes to copy */
342 unsigned char *from; /* where to copy match bytes from */
343 code this; /* current decoding table entry */
344 code last; /* parent table entry */
345 unsigned len; /* length to copy for repeats, bits to drop */
346 int ret; /* return code */
347 static const unsigned short order[19] = /* permutation of code lengths */
348 {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
349
350 if (strm == NULL || strm->state == NULL || strm->next_out == NULL ||
351 (strm->next_in == NULL && strm->avail_in != 0))
352 return Z_STREAM_ERROR;
353
354 state = (struct inflate_state *)strm->state;
355
356 if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
357 LOAD();
358 in = have;
359 out = left;
360 ret = Z_OK;
361 for (;;)
362 switch (state->mode) {
363 case HEAD:
364 if (state->wrap == 0) {
365 state->mode = TYPEDO;
366 break;
367 }
368 NEEDBITS(16);
369 if (
370 ((BITS(8) << 8) + (hold >> 8)) % 31) {
371 strm->msg = (char *)"incorrect header check";
372 state->mode = BAD;
373 break;
374 }
375 if (BITS(4) != Z_DEFLATED) {
376 strm->msg = (char *)"unknown compression method";
377 state->mode = BAD;
378 break;
379 }
380 DROPBITS(4);
381 len = BITS(4) + 8;
382 if (len > state->wbits) {
383 strm->msg = (char *)"invalid window size";
384 state->mode = BAD;
385 break;
386 }
387 state->dmax = 1U << len;
388 strm->adler = state->check = zlib_adler32(0L, NULL, 0);
389 state->mode = hold & 0x200 ? DICTID : TYPE;
390 INITBITS();
391 break;
392 case DICTID:
393 NEEDBITS(32);
394 strm->adler = state->check = REVERSE(hold);
395 INITBITS();
396 state->mode = DICT;
397 case DICT:
398 if (state->havedict == 0) {
399 RESTORE();
400 return Z_NEED_DICT;
401 }
402 strm->adler = state->check = zlib_adler32(0L, NULL, 0);
403 state->mode = TYPE;
404 case TYPE:
405 if (flush == Z_BLOCK) goto inf_leave;
406 case TYPEDO:
407 if (state->last) {
408 BYTEBITS();
409 state->mode = CHECK;
410 break;
411 }
412 NEEDBITS(3);
413 state->last = BITS(1);
414 DROPBITS(1);
415 switch (BITS(2)) {
416 case 0: /* stored block */
417 state->mode = STORED;
418 break;
419 case 1: /* fixed block */
420 zlib_fixedtables(state);
421 state->mode = LEN; /* decode codes */
422 break;
423 case 2: /* dynamic block */
424 state->mode = TABLE;
425 break;
426 case 3:
427 strm->msg = (char *)"invalid block type";
428 state->mode = BAD;
429 }
430 DROPBITS(2);
431 break;
432 case STORED:
433 BYTEBITS(); /* go to byte boundary */
434 NEEDBITS(32);
435 if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
436 strm->msg = (char *)"invalid stored block lengths";
437 state->mode = BAD;
438 break;
439 }
440 state->length = (unsigned)hold & 0xffff;
441 INITBITS();
442 state->mode = COPY;
443 case COPY:
444 copy = state->length;
445 if (copy) {
446 if (copy > have) copy = have;
447 if (copy > left) copy = left;
448 if (copy == 0) goto inf_leave;
449 memcpy(put, next, copy);
450 have -= copy;
451 next += copy;
452 left -= copy;
453 put += copy;
454 state->length -= copy;
455 break;
456 }
457 state->mode = TYPE;
458 break;
459 case TABLE:
460 NEEDBITS(14);
461 state->nlen = BITS(5) + 257;
462 DROPBITS(5);
463 state->ndist = BITS(5) + 1;
464 DROPBITS(5);
465 state->ncode = BITS(4) + 4;
466 DROPBITS(4);
467#ifndef PKZIP_BUG_WORKAROUND
468 if (state->nlen > 286 || state->ndist > 30) {
469 strm->msg = (char *)"too many length or distance symbols";
470 state->mode = BAD;
471 break;
472 }
473#endif
474 state->have = 0;
475 state->mode = LENLENS;
476 case LENLENS:
477 while (state->have < state->ncode) {
478 NEEDBITS(3);
479 state->lens[order[state->have++]] = (unsigned short)BITS(3);
480 DROPBITS(3);
481 }
482 while (state->have < 19)
483 state->lens[order[state->have++]] = 0;
484 state->next = state->codes;
485 state->lencode = (code const *)(state->next);
486 state->lenbits = 7;
487 ret = zlib_inflate_table(CODES, state->lens, 19, &(state->next),
488 &(state->lenbits), state->work);
489 if (ret) {
490 strm->msg = (char *)"invalid code lengths set";
491 state->mode = BAD;
492 break;
493 }
494 state->have = 0;
495 state->mode = CODELENS;
496 case CODELENS:
497 while (state->have < state->nlen + state->ndist) {
498 for (;;) {
499 this = state->lencode[BITS(state->lenbits)];
500 if ((unsigned)(this.bits) <= bits) break;
501 PULLBYTE();
502 }
503 if (this.val < 16) {
504 NEEDBITS(this.bits);
505 DROPBITS(this.bits);
506 state->lens[state->have++] = this.val;
507 }
508 else {
509 if (this.val == 16) {
510 NEEDBITS(this.bits + 2);
511 DROPBITS(this.bits);
512 if (state->have == 0) {
513 strm->msg = (char *)"invalid bit length repeat";
514 state->mode = BAD;
515 break;
516 }
517 len = state->lens[state->have - 1];
518 copy = 3 + BITS(2);
519 DROPBITS(2);
520 }
521 else if (this.val == 17) {
522 NEEDBITS(this.bits + 3);
523 DROPBITS(this.bits);
524 len = 0;
525 copy = 3 + BITS(3);
526 DROPBITS(3);
527 }
528 else {
529 NEEDBITS(this.bits + 7);
530 DROPBITS(this.bits);
531 len = 0;
532 copy = 11 + BITS(7);
533 DROPBITS(7);
534 }
535 if (state->have + copy > state->nlen + state->ndist) {
536 strm->msg = (char *)"invalid bit length repeat";
537 state->mode = BAD;
538 break;
539 }
540 while (copy--)
541 state->lens[state->have++] = (unsigned short)len;
542 }
543 }
544
545 /* handle error breaks in while */
546 if (state->mode == BAD) break;
547
548 /* build code tables */
549 state->next = state->codes;
550 state->lencode = (code const *)(state->next);
551 state->lenbits = 9;
552 ret = zlib_inflate_table(LENS, state->lens, state->nlen, &(state->next),
553 &(state->lenbits), state->work);
554 if (ret) {
555 strm->msg = (char *)"invalid literal/lengths set";
556 state->mode = BAD;
557 break;
558 }
559 state->distcode = (code const *)(state->next);
560 state->distbits = 6;
561 ret = zlib_inflate_table(DISTS, state->lens + state->nlen, state->ndist,
562 &(state->next), &(state->distbits), state->work);
563 if (ret) {
564 strm->msg = (char *)"invalid distances set";
565 state->mode = BAD;
566 break;
567 }
568 state->mode = LEN;
569 case LEN:
570 if (have >= 6 && left >= 258) {
571 RESTORE();
572 inflate_fast(strm, out);
573 LOAD();
574 break;
575 }
576 for (;;) {
577 this = state->lencode[BITS(state->lenbits)];
578 if ((unsigned)(this.bits) <= bits) break;
579 PULLBYTE();
580 }
581 if (this.op && (this.op & 0xf0) == 0) {
582 last = this;
583 for (;;) {
584 this = state->lencode[last.val +
585 (BITS(last.bits + last.op) >> last.bits)];
586 if ((unsigned)(last.bits + this.bits) <= bits) break;
587 PULLBYTE();
588 }
589 DROPBITS(last.bits);
590 }
591 DROPBITS(this.bits);
592 state->length = (unsigned)this.val;
593 if ((int)(this.op) == 0) {
594 state->mode = LIT;
595 break;
596 }
597 if (this.op & 32) {
598 state->mode = TYPE;
599 break;
600 }
601 if (this.op & 64) {
602 strm->msg = (char *)"invalid literal/length code";
603 state->mode = BAD;
604 break;
605 }
606 state->extra = (unsigned)(this.op) & 15;
607 state->mode = LENEXT;
608 case LENEXT:
609 if (state->extra) {
610 NEEDBITS(state->extra);
611 state->length += BITS(state->extra);
612 DROPBITS(state->extra);
613 }
614 state->mode = DIST;
615 case DIST:
616 for (;;) {
617 this = state->distcode[BITS(state->distbits)];
618 if ((unsigned)(this.bits) <= bits) break;
619 PULLBYTE();
620 }
621 if ((this.op & 0xf0) == 0) {
622 last = this;
623 for (;;) {
624 this = state->distcode[last.val +
625 (BITS(last.bits + last.op) >> last.bits)];
626 if ((unsigned)(last.bits + this.bits) <= bits) break;
627 PULLBYTE();
628 }
629 DROPBITS(last.bits);
630 }
631 DROPBITS(this.bits);
632 if (this.op & 64) {
633 strm->msg = (char *)"invalid distance code";
634 state->mode = BAD;
635 break;
636 }
637 state->offset = (unsigned)this.val;
638 state->extra = (unsigned)(this.op) & 15;
639 state->mode = DISTEXT;
640 case DISTEXT:
641 if (state->extra) {
642 NEEDBITS(state->extra);
643 state->offset += BITS(state->extra);
644 DROPBITS(state->extra);
645 }
646#ifdef INFLATE_STRICT
647 if (state->offset > state->dmax) {
648 strm->msg = (char *)"invalid distance too far back";
649 state->mode = BAD;
650 break;
651 }
652#endif
653 if (state->offset > state->whave + out - left) {
654 strm->msg = (char *)"invalid distance too far back";
655 state->mode = BAD;
656 break;
657 }
658 state->mode = MATCH;
659 case MATCH:
660 if (left == 0) goto inf_leave;
661 copy = out - left;
662 if (state->offset > copy) { /* copy from window */
663 copy = state->offset - copy;
664 if (copy > state->write) {
665 copy -= state->write;
666 from = state->window + (state->wsize - copy);
667 }
668 else
669 from = state->window + (state->write - copy);
670 if (copy > state->length) copy = state->length;
671 }
672 else { /* copy from output */
673 from = put - state->offset;
674 copy = state->length;
675 }
676 if (copy > left) copy = left;
677 left -= copy;
678 state->length -= copy;
679 do {
680 *put++ = *from++;
681 } while (--copy);
682 if (state->length == 0) state->mode = LEN;
683 break;
684 case LIT:
685 if (left == 0) goto inf_leave;
686 *put++ = (unsigned char)(state->length);
687 left--;
688 state->mode = LEN;
689 break;
690 case CHECK:
691 if (state->wrap) {
692 NEEDBITS(32);
693 out -= left;
694 strm->total_out += out;
695 state->total += out;
696 if (out)
697 strm->adler = state->check =
698 UPDATE(state->check, put - out, out);
699 out = left;
700 if ((
701 REVERSE(hold)) != state->check) {
702 strm->msg = (char *)"incorrect data check";
703 state->mode = BAD;
704 break;
705 }
706 INITBITS();
707 }
708 state->mode = DONE;
709 case DONE:
710 ret = Z_STREAM_END;
711 goto inf_leave;
712 case BAD:
713 ret = Z_DATA_ERROR;
714 goto inf_leave;
715 case MEM:
716 return Z_MEM_ERROR;
717 case SYNC:
718 default:
719 return Z_STREAM_ERROR;
720 }
721
722 /*
723 Return from inflate(), updating the total counts and the check value.
724 If there was no progress during the inflate() call, return a buffer
725 error. Call zlib_updatewindow() to create and/or update the window state.
726 */
727 inf_leave:
728 RESTORE();
729 if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
730 zlib_updatewindow(strm, out);
731
732 in -= strm->avail_in;
733 out -= strm->avail_out;
734 strm->total_in += in;
735 strm->total_out += out;
736 state->total += out;
737 if (state->wrap && out)
738 strm->adler = state->check =
739 UPDATE(state->check, strm->next_out - out, out);
740
741 strm->data_type = state->bits + (state->last ? 64 : 0) +
742 (state->mode == TYPE ? 128 : 0);
743 if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
744 ret = Z_BUF_ERROR;
745
746 if (flush == Z_PACKET_FLUSH && ret == Z_OK &&
747 (strm->avail_out != 0 || strm->avail_in == 0))
748 return zlib_inflateSyncPacket(strm);
749 return ret;
750}
751
752int zlib_inflateEnd(z_streamp strm)
753{
754 if (strm == NULL || strm->state == NULL)
755 return Z_STREAM_ERROR;
99 return Z_OK; 756 return Z_OK;
100} 757}
101 758
759#if 0
760int zlib_inflateSetDictionary(z_streamp strm, const Byte *dictionary,
761 uInt dictLength)
762{
763 struct inflate_state *state;
764 unsigned long id;
765
766 /* check state */
767 if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
768 state = (struct inflate_state *)strm->state;
769 if (state->wrap != 0 && state->mode != DICT)
770 return Z_STREAM_ERROR;
771
772 /* check for correct dictionary id */
773 if (state->mode == DICT) {
774 id = zlib_adler32(0L, NULL, 0);
775 id = zlib_adler32(id, dictionary, dictLength);
776 if (id != state->check)
777 return Z_DATA_ERROR;
778 }
779
780 /* copy dictionary to window */
781 zlib_updatewindow(strm, strm->avail_out);
102 782
103int zlib_inflateInit_( 783 if (dictLength > state->wsize) {
104 z_streamp z, 784 memcpy(state->window, dictionary + dictLength - state->wsize,
105 const char *version, 785 state->wsize);
106 int stream_size 786 state->whave = state->wsize;
107) 787 }
788 else {
789 memcpy(state->window + state->wsize - dictLength, dictionary,
790 dictLength);
791 state->whave = dictLength;
792 }
793 state->havedict = 1;
794 return Z_OK;
795}
796#endif
797
798#if 0
799/*
800 Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
801 or when out of input. When called, *have is the number of pattern bytes
802 found in order so far, in 0..3. On return *have is updated to the new
803 state. If on return *have equals four, then the pattern was found and the
804 return value is how many bytes were read including the last byte of the
805 pattern. If *have is less than four, then the pattern has not been found
806 yet and the return value is len. In the latter case, zlib_syncsearch() can be
807 called again with more data and the *have state. *have is initialized to
808 zero for the first call.
809 */
810static unsigned zlib_syncsearch(unsigned *have, unsigned char *buf,
811 unsigned len)
108{ 812{
109 return zlib_inflateInit2_(z, DEF_WBITS, version, stream_size); 813 unsigned got;
814 unsigned next;
815
816 got = *have;
817 next = 0;
818 while (next < len && got < 4) {
819 if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
820 got++;
821 else if (buf[next])
822 got = 0;
823 else
824 got = 4 - got;
825 next++;
826 }
827 *have = got;
828 return next;
110} 829}
830#endif
111 831
112#undef NEEDBYTE 832#if 0
113#undef NEXTBYTE 833int zlib_inflateSync(z_streamp strm)
114#define NEEDBYTE {if(z->avail_in==0)goto empty;r=trv;} 834{
115#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) 835 unsigned len; /* number of bytes to look at or looked at */
836 unsigned long in, out; /* temporary to save total_in and total_out */
837 unsigned char buf[4]; /* to restore bit buffer to byte string */
838 struct inflate_state *state;
839
840 /* check parameters */
841 if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
842 state = (struct inflate_state *)strm->state;
843 if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
844
845 /* if first time, start search in bit buffer */
846 if (state->mode != SYNC) {
847 state->mode = SYNC;
848 state->hold <<= state->bits & 7;
849 state->bits -= state->bits & 7;
850 len = 0;
851 while (state->bits >= 8) {
852 buf[len++] = (unsigned char)(state->hold);
853 state->hold >>= 8;
854 state->bits -= 8;
855 }
856 state->have = 0;
857 zlib_syncsearch(&(state->have), buf, len);
858 }
859
860 /* search available input */
861 len = zlib_syncsearch(&(state->have), strm->next_in, strm->avail_in);
862 strm->avail_in -= len;
863 strm->next_in += len;
864 strm->total_in += len;
865
866 /* return no joy or set up to restart inflate() on a new block */
867 if (state->have != 4) return Z_DATA_ERROR;
868 in = strm->total_in; out = strm->total_out;
869 zlib_inflateReset(strm);
870 strm->total_in = in; strm->total_out = out;
871 state->mode = TYPE;
872 return Z_OK;
873}
874#endif
116 875
117int zlib_inflate( 876/*
118 z_streamp z, 877 * This subroutine adds the data at next_in/avail_in to the output history
119 int f 878 * without performing any output. The output buffer must be "caught up";
120) 879 * i.e. no pending output but this should always be the case. The state must
880 * be waiting on the start of a block (i.e. mode == TYPE or HEAD). On exit,
881 * the output will also be caught up, and the checksum will have been updated
882 * if need be.
883 */
884int zlib_inflateIncomp(z_stream *z)
121{ 885{
122 int r, trv; 886 struct inflate_state *state = (struct inflate_state *)z->state;
123 uInt b; 887 Byte *saved_no = z->next_out;
124 888 uInt saved_ao = z->avail_out;
125 if (z == NULL || z->state == NULL || z->next_in == NULL) 889
126 return Z_STREAM_ERROR; 890 if (state->mode != TYPE && state->mode != HEAD)
127 trv = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; 891 return Z_DATA_ERROR;
128 r = Z_BUF_ERROR; 892
129 while (1) switch (z->state->mode) 893 /* Setup some variables to allow misuse of updateWindow */
130 { 894 z->avail_out = 0;
131 case METHOD: 895 z->next_out = z->next_in + z->avail_in;
132 NEEDBYTE 896
133 if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) 897 zlib_updatewindow(z, z->avail_in);
134 { 898
135 z->state->mode = I_BAD; 899 /* Restore saved variables */
136 z->msg = (char*)"unknown compression method"; 900 z->avail_out = saved_ao;
137 z->state->sub.marker = 5; /* can't try inflateSync */ 901 z->next_out = saved_no;
138 break; 902
139 } 903 z->adler = state->check =
140 if ((z->state->sub.method >> 4) + 8 > z->state->wbits) 904 UPDATE(state->check, z->next_in, z->avail_in);
141 { 905
142 z->state->mode = I_BAD; 906 z->total_out += z->avail_in;
143 z->msg = (char*)"invalid window size"; 907 z->total_in += z->avail_in;
144 z->state->sub.marker = 5; /* can't try inflateSync */ 908 z->next_in += z->avail_in;
145 break; 909 state->total += z->avail_in;
146 } 910 z->avail_in = 0;
147 z->state->mode = FLAG; 911
148 case FLAG: 912 return Z_OK;
149 NEEDBYTE
150 b = NEXTBYTE;
151 if (((z->state->sub.method << 8) + b) % 31)
152 {
153 z->state->mode = I_BAD;
154 z->msg = (char*)"incorrect header check";
155 z->state->sub.marker = 5; /* can't try inflateSync */
156 break;
157 }
158 if (!(b & PRESET_DICT))
159 {
160 z->state->mode = BLOCKS;
161 break;
162 }
163 z->state->mode = DICT4;
164 case DICT4:
165 NEEDBYTE
166 z->state->sub.check.need = (uLong)NEXTBYTE << 24;
167 z->state->mode = DICT3;
168 case DICT3:
169 NEEDBYTE
170 z->state->sub.check.need += (uLong)NEXTBYTE << 16;
171 z->state->mode = DICT2;
172 case DICT2:
173 NEEDBYTE
174 z->state->sub.check.need += (uLong)NEXTBYTE << 8;
175 z->state->mode = DICT1;
176 case DICT1:
177 NEEDBYTE
178 z->state->sub.check.need += (uLong)NEXTBYTE;
179 z->adler = z->state->sub.check.need;
180 z->state->mode = DICT0;
181 return Z_NEED_DICT;
182 case DICT0:
183 z->state->mode = I_BAD;
184 z->msg = (char*)"need dictionary";
185 z->state->sub.marker = 0; /* can try inflateSync */
186 return Z_STREAM_ERROR;
187 case BLOCKS:
188 r = zlib_inflate_blocks(z->state->blocks, z, r);
189 if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
190 r = zlib_inflate_packet_flush(z->state->blocks);
191 if (r == Z_DATA_ERROR)
192 {
193 z->state->mode = I_BAD;
194 z->state->sub.marker = 0; /* can try inflateSync */
195 break;
196 }
197 if (r == Z_OK)
198 r = trv;
199 if (r != Z_STREAM_END)
200 return r;
201 r = trv;
202 zlib_inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
203 if (z->state->nowrap)
204 {
205 z->state->mode = I_DONE;
206 break;
207 }
208 z->state->mode = CHECK4;
209 case CHECK4:
210 NEEDBYTE
211 z->state->sub.check.need = (uLong)NEXTBYTE << 24;
212 z->state->mode = CHECK3;
213 case CHECK3:
214 NEEDBYTE
215 z->state->sub.check.need += (uLong)NEXTBYTE << 16;
216 z->state->mode = CHECK2;
217 case CHECK2:
218 NEEDBYTE
219 z->state->sub.check.need += (uLong)NEXTBYTE << 8;
220 z->state->mode = CHECK1;
221 case CHECK1:
222 NEEDBYTE
223 z->state->sub.check.need += (uLong)NEXTBYTE;
224
225 if (z->state->sub.check.was != z->state->sub.check.need)
226 {
227 z->state->mode = I_BAD;
228 z->msg = (char*)"incorrect data check";
229 z->state->sub.marker = 5; /* can't try inflateSync */
230 break;
231 }
232 z->state->mode = I_DONE;
233 case I_DONE:
234 return Z_STREAM_END;
235 case I_BAD:
236 return Z_DATA_ERROR;
237 default:
238 return Z_STREAM_ERROR;
239 }
240 empty:
241 if (f != Z_PACKET_FLUSH)
242 return r;
243 z->state->mode = I_BAD;
244 z->msg = (char *)"need more for packet flush";
245 z->state->sub.marker = 0; /* can try inflateSync */
246 return Z_DATA_ERROR;
247} 913}
diff --git a/lib/zlib_inflate/inflate.h b/lib/zlib_inflate/inflate.h
new file mode 100644
index 000000000000..df8a6c92052d
--- /dev/null
+++ b/lib/zlib_inflate/inflate.h
@@ -0,0 +1,107 @@
1/* inflate.h -- internal inflate state definition
2 * Copyright (C) 1995-2004 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/* WARNING: this file should *not* be used by applications. It is
7 part of the implementation of the compression library and is
8 subject to change. Applications should only use zlib.h.
9 */
10
11/* Possible inflate modes between inflate() calls */
12typedef enum {
13 HEAD, /* i: waiting for magic header */
14 FLAGS, /* i: waiting for method and flags (gzip) */
15 TIME, /* i: waiting for modification time (gzip) */
16 OS, /* i: waiting for extra flags and operating system (gzip) */
17 EXLEN, /* i: waiting for extra length (gzip) */
18 EXTRA, /* i: waiting for extra bytes (gzip) */
19 NAME, /* i: waiting for end of file name (gzip) */
20 COMMENT, /* i: waiting for end of comment (gzip) */
21 HCRC, /* i: waiting for header crc (gzip) */
22 DICTID, /* i: waiting for dictionary check value */
23 DICT, /* waiting for inflateSetDictionary() call */
24 TYPE, /* i: waiting for type bits, including last-flag bit */
25 TYPEDO, /* i: same, but skip check to exit inflate on new block */
26 STORED, /* i: waiting for stored size (length and complement) */
27 COPY, /* i/o: waiting for input or output to copy stored block */
28 TABLE, /* i: waiting for dynamic block table lengths */
29 LENLENS, /* i: waiting for code length code lengths */
30 CODELENS, /* i: waiting for length/lit and distance code lengths */
31 LEN, /* i: waiting for length/lit code */
32 LENEXT, /* i: waiting for length extra bits */
33 DIST, /* i: waiting for distance code */
34 DISTEXT, /* i: waiting for distance extra bits */
35 MATCH, /* o: waiting for output space to copy string */
36 LIT, /* o: waiting for output space to write literal */
37 CHECK, /* i: waiting for 32-bit check value */
38 LENGTH, /* i: waiting for 32-bit length (gzip) */
39 DONE, /* finished check, done -- remain here until reset */
40 BAD, /* got a data error -- remain here until reset */
41 MEM, /* got an inflate() memory error -- remain here until reset */
42 SYNC /* looking for synchronization bytes to restart inflate() */
43} inflate_mode;
44
45/*
46 State transitions between above modes -
47
48 (most modes can go to the BAD or MEM mode -- not shown for clarity)
49
50 Process header:
51 HEAD -> (gzip) or (zlib)
52 (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
53 NAME -> COMMENT -> HCRC -> TYPE
54 (zlib) -> DICTID or TYPE
55 DICTID -> DICT -> TYPE
56 Read deflate blocks:
57 TYPE -> STORED or TABLE or LEN or CHECK
58 STORED -> COPY -> TYPE
59 TABLE -> LENLENS -> CODELENS -> LEN
60 Read deflate codes:
61 LEN -> LENEXT or LIT or TYPE
62 LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
63 LIT -> LEN
64 Process trailer:
65 CHECK -> LENGTH -> DONE
66 */
67
68/* state maintained between inflate() calls. Approximately 7K bytes. */
69struct inflate_state {
70 inflate_mode mode; /* current inflate mode */
71 int last; /* true if processing last block */
72 int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
73 int havedict; /* true if dictionary provided */
74 int flags; /* gzip header method and flags (0 if zlib) */
75 unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
76 unsigned long check; /* protected copy of check value */
77 unsigned long total; /* protected copy of output count */
78 /* gz_headerp head; */ /* where to save gzip header information */
79 /* sliding window */
80 unsigned wbits; /* log base 2 of requested window size */
81 unsigned wsize; /* window size or zero if not using window */
82 unsigned whave; /* valid bytes in the window */
83 unsigned write; /* window write index */
84 unsigned char *window; /* allocated sliding window, if needed */
85 /* bit accumulator */
86 unsigned long hold; /* input bit accumulator */
87 unsigned bits; /* number of bits in "in" */
88 /* for string and stored block copying */
89 unsigned length; /* literal or length of data to copy */
90 unsigned offset; /* distance back to copy string from */
91 /* for table and code decoding */
92 unsigned extra; /* extra bits needed */
93 /* fixed and dynamic code tables */
94 code const *lencode; /* starting table for length/literal codes */
95 code const *distcode; /* starting table for distance codes */
96 unsigned lenbits; /* index bits for lencode */
97 unsigned distbits; /* index bits for distcode */
98 /* dynamic table building */
99 unsigned ncode; /* number of code length code lengths */
100 unsigned nlen; /* number of length code lengths */
101 unsigned ndist; /* number of distance code lengths */
102 unsigned have; /* number of code lengths in lens[] */
103 code *next; /* next available space in codes[] */
104 unsigned short lens[320]; /* temporary storage for code lengths */
105 unsigned short work[288]; /* work area for code table building */
106 code codes[ENOUGH]; /* space for code tables */
107};
diff --git a/lib/zlib_inflate/inflate_syms.c b/lib/zlib_inflate/inflate_syms.c
index ef49738f57ec..2061d4f06765 100644
--- a/lib/zlib_inflate/inflate_syms.c
+++ b/lib/zlib_inflate/inflate_syms.c
@@ -12,8 +12,7 @@
12 12
13EXPORT_SYMBOL(zlib_inflate_workspacesize); 13EXPORT_SYMBOL(zlib_inflate_workspacesize);
14EXPORT_SYMBOL(zlib_inflate); 14EXPORT_SYMBOL(zlib_inflate);
15EXPORT_SYMBOL(zlib_inflateInit_); 15EXPORT_SYMBOL(zlib_inflateInit2);
16EXPORT_SYMBOL(zlib_inflateInit2_);
17EXPORT_SYMBOL(zlib_inflateEnd); 16EXPORT_SYMBOL(zlib_inflateEnd);
18EXPORT_SYMBOL(zlib_inflateReset); 17EXPORT_SYMBOL(zlib_inflateReset);
19EXPORT_SYMBOL(zlib_inflateIncomp); 18EXPORT_SYMBOL(zlib_inflateIncomp);
diff --git a/lib/zlib_inflate/inflate_sync.c b/lib/zlib_inflate/inflate_sync.c
deleted file mode 100644
index 61411ff89d61..000000000000
--- a/lib/zlib_inflate/inflate_sync.c
+++ /dev/null
@@ -1,152 +0,0 @@
1/* inflate.c -- zlib interface to inflate modules
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include <linux/zutil.h>
7#include "infblock.h"
8#include "infutil.h"
9
10#if 0
11int zlib_inflateSync(
12 z_streamp z
13)
14{
15 uInt n; /* number of bytes to look at */
16 Byte *p; /* pointer to bytes */
17 uInt m; /* number of marker bytes found in a row */
18 uLong r, w; /* temporaries to save total_in and total_out */
19
20 /* set up */
21 if (z == NULL || z->state == NULL)
22 return Z_STREAM_ERROR;
23 if (z->state->mode != I_BAD)
24 {
25 z->state->mode = I_BAD;
26 z->state->sub.marker = 0;
27 }
28 if ((n = z->avail_in) == 0)
29 return Z_BUF_ERROR;
30 p = z->next_in;
31 m = z->state->sub.marker;
32
33 /* search */
34 while (n && m < 4)
35 {
36 static const Byte mark[4] = {0, 0, 0xff, 0xff};
37 if (*p == mark[m])
38 m++;
39 else if (*p)
40 m = 0;
41 else
42 m = 4 - m;
43 p++, n--;
44 }
45
46 /* restore */
47 z->total_in += p - z->next_in;
48 z->next_in = p;
49 z->avail_in = n;
50 z->state->sub.marker = m;
51
52 /* return no joy or set up to restart on a new block */
53 if (m != 4)
54 return Z_DATA_ERROR;
55 r = z->total_in; w = z->total_out;
56 zlib_inflateReset(z);
57 z->total_in = r; z->total_out = w;
58 z->state->mode = BLOCKS;
59 return Z_OK;
60}
61#endif /* 0 */
62
63
64/* Returns true if inflate is currently at the end of a block generated
65 * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
66 * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
67 * but removes the length bytes of the resulting empty stored block. When
68 * decompressing, PPP checks that at the end of input packet, inflate is
69 * waiting for these length bytes.
70 */
71#if 0
72int zlib_inflateSyncPoint(
73 z_streamp z
74)
75{
76 if (z == NULL || z->state == NULL || z->state->blocks == NULL)
77 return Z_STREAM_ERROR;
78 return zlib_inflate_blocks_sync_point(z->state->blocks);
79}
80#endif /* 0 */
81
82/*
83 * This subroutine adds the data at next_in/avail_in to the output history
84 * without performing any output. The output buffer must be "caught up";
85 * i.e. no pending output (hence s->read equals s->write), and the state must
86 * be BLOCKS (i.e. we should be willing to see the start of a series of
87 * BLOCKS). On exit, the output will also be caught up, and the checksum
88 * will have been updated if need be.
89 */
90static int zlib_inflate_addhistory(inflate_blocks_statef *s,
91 z_stream *z)
92{
93 uLong b; /* bit buffer */ /* NOT USED HERE */
94 uInt k; /* bits in bit buffer */ /* NOT USED HERE */
95 uInt t; /* temporary storage */
96 Byte *p; /* input data pointer */
97 uInt n; /* bytes available there */
98 Byte *q; /* output window write pointer */
99 uInt m; /* bytes to end of window or read pointer */
100
101 if (s->read != s->write)
102 return Z_STREAM_ERROR;
103 if (s->mode != TYPE)
104 return Z_DATA_ERROR;
105
106 /* we're ready to rock */
107 LOAD
108 /* while there is input ready, copy to output buffer, moving
109 * pointers as needed.
110 */
111 while (n) {
112 t = n; /* how many to do */
113 /* is there room until end of buffer? */
114 if (t > m) t = m;
115 /* update check information */
116 if (s->checkfn != NULL)
117 s->check = (*s->checkfn)(s->check, q, t);
118 memcpy(q, p, t);
119 q += t;
120 p += t;
121 n -= t;
122 z->total_out += t;
123 s->read = q; /* drag read pointer forward */
124/* WWRAP */ /* expand WWRAP macro by hand to handle s->read */
125 if (q == s->end) {
126 s->read = q = s->window;
127 m = WAVAIL;
128 }
129 }
130 UPDATE
131 return Z_OK;
132}
133
134
135/*
136 * This subroutine adds the data at next_in/avail_in to the output history
137 * without performing any output. The output buffer must be "caught up";
138 * i.e. no pending output (hence s->read equals s->write), and the state must
139 * be BLOCKS (i.e. we should be willing to see the start of a series of
140 * BLOCKS). On exit, the output will also be caught up, and the checksum
141 * will have been updated if need be.
142 */
143
144int zlib_inflateIncomp(
145 z_stream *z
146
147)
148{
149 if (z->state->mode != BLOCKS)
150 return Z_DATA_ERROR;
151 return zlib_inflate_addhistory(z->state->blocks, z);
152}
diff --git a/lib/zlib_inflate/inftrees.c b/lib/zlib_inflate/inftrees.c
index 874950ec4858..62343c53bf7e 100644
--- a/lib/zlib_inflate/inftrees.c
+++ b/lib/zlib_inflate/inftrees.c
@@ -1,412 +1,329 @@
1/* inftrees.c -- generate Huffman trees for efficient decoding 1/* inftrees.c -- generate Huffman trees for efficient decoding
2 * Copyright (C) 1995-1998 Mark Adler 2 * Copyright (C) 1995-2005 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
6#include <linux/zutil.h> 6#include <linux/zutil.h>
7#include "inftrees.h" 7#include "inftrees.h"
8#include "infutil.h"
9 8
10static const char inflate_copyright[] __attribute_used__ = 9#define MAXBITS 15
11 " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; 10
11const char inflate_copyright[] =
12 " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
12/* 13/*
13 If you use the zlib library in a product, an acknowledgment is welcome 14 If you use the zlib library in a product, an acknowledgment is welcome
14 in the documentation of your product. If for some reason you cannot 15 in the documentation of your product. If for some reason you cannot
15 include such an acknowledgment, I would appreciate that you keep this 16 include such an acknowledgment, I would appreciate that you keep this
16 copyright string in the executable of your product. 17 copyright string in the executable of your product.
17 */ 18 */
18struct internal_state;
19
20/* simplify the use of the inflate_huft type with some defines */
21#define exop word.what.Exop
22#define bits word.what.Bits
23
24
25static int huft_build (
26 uInt *, /* code lengths in bits */
27 uInt, /* number of codes */
28 uInt, /* number of "simple" codes */
29 const uInt *, /* list of base values for non-simple codes */
30 const uInt *, /* list of extra bits for non-simple codes */
31 inflate_huft **, /* result: starting table */
32 uInt *, /* maximum lookup bits (returns actual) */
33 inflate_huft *, /* space for trees */
34 uInt *, /* hufts used in space */
35 uInt * ); /* space for values */
36
37/* Tables for deflate from PKZIP's appnote.txt. */
38static const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
39 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
40 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
41 /* see note #13 above about 258 */
42static const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
43 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
44 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
45static const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
46 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
47 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
48 8193, 12289, 16385, 24577};
49static const uInt cpdext[30] = { /* Extra bits for distance codes */
50 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
51 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
52 12, 12, 13, 13};
53 19
54/* 20/*
55 Huffman code decoding is performed using a multi-level table lookup. 21 Build a set of tables to decode the provided canonical Huffman code.
56 The fastest way to decode is to simply build a lookup table whose 22 The code lengths are lens[0..codes-1]. The result starts at *table,
57 size is determined by the longest code. However, the time it takes 23 whose indices are 0..2^bits-1. work is a writable array of at least
58 to build this table can also be a factor if the data being decoded 24 lens shorts, which is used as a work area. type is the type of code
59 is not very long. The most common codes are necessarily the 25 to be generated, CODES, LENS, or DISTS. On return, zero is success,
60 shortest codes, so those codes dominate the decoding time, and hence 26 -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
61 the speed. The idea is you can have a shorter table that decodes the 27 on return points to the next available entry's address. bits is the
62 shorter, more probable codes, and then point to subsidiary tables for 28 requested root table index bits, and on return it is the actual root
63 the longer codes. The time it costs to decode the longer codes is 29 table index bits. It will differ if the request is greater than the
64 then traded against the time it takes to make longer tables. 30 longest code or if it is less than the shortest code.
65
66 This results of this trade are in the variables lbits and dbits
67 below. lbits is the number of bits the first level table for literal/
68 length codes can decode in one step, and dbits is the same thing for
69 the distance codes. Subsequent tables are also less than or equal to
70 those sizes. These values may be adjusted either when all of the
71 codes are shorter than that, in which case the longest code length in
72 bits is used, or when the shortest code is *longer* than the requested
73 table size, in which case the length of the shortest code in bits is
74 used.
75
76 There are two different values for the two tables, since they code a
77 different number of possibilities each. The literal/length table
78 codes 286 possible values, or in a flat code, a little over eight
79 bits. The distance table codes 30 possible values, or a little less
80 than five bits, flat. The optimum values for speed end up being
81 about one bit more than those, so lbits is 8+1 and dbits is 5+1.
82 The optimum values may differ though from machine to machine, and
83 possibly even between compilers. Your mileage may vary.
84 */ 31 */
85 32int zlib_inflate_table(type, lens, codes, table, bits, work)
86 33codetype type;
87/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ 34unsigned short *lens;
88#define BMAX 15 /* maximum bit length of any code */ 35unsigned codes;
89 36code **table;
90static int huft_build( 37unsigned *bits;
91 uInt *b, /* code lengths in bits (all assumed <= BMAX) */ 38unsigned short *work;
92 uInt n, /* number of codes (assumed <= 288) */
93 uInt s, /* number of simple-valued codes (0..s-1) */
94 const uInt *d, /* list of base values for non-simple codes */
95 const uInt *e, /* list of extra bits for non-simple codes */
96 inflate_huft **t, /* result: starting table */
97 uInt *m, /* maximum lookup bits, returns actual */
98 inflate_huft *hp, /* space for trees */
99 uInt *hn, /* hufts used in space */
100 uInt *v /* working area: values in order of bit length */
101)
102/* Given a list of code lengths and a maximum table size, make a set of
103 tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
104 if the given code set is incomplete (the tables are still built in this
105 case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
106 lengths), or Z_MEM_ERROR if not enough memory. */
107{ 39{
40 unsigned len; /* a code's length in bits */
41 unsigned sym; /* index of code symbols */
42 unsigned min, max; /* minimum and maximum code lengths */
43 unsigned root; /* number of index bits for root table */
44 unsigned curr; /* number of index bits for current table */
45 unsigned drop; /* code bits to drop for sub-table */
46 int left; /* number of prefix codes available */
47 unsigned used; /* code entries in table used */
48 unsigned huff; /* Huffman code */
49 unsigned incr; /* for incrementing code, index */
50 unsigned fill; /* index for replicating entries */
51 unsigned low; /* low bits for current root entry */
52 unsigned mask; /* mask for low root bits */
53 code this; /* table entry for duplication */
54 code *next; /* next available space in table */
55 const unsigned short *base; /* base value table to use */
56 const unsigned short *extra; /* extra bits table to use */
57 int end; /* use base and extra for symbol > end */
58 unsigned short count[MAXBITS+1]; /* number of codes of each length */
59 unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
60 static const unsigned short lbase[31] = { /* Length codes 257..285 base */
61 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
62 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
63 static const unsigned short lext[31] = { /* Length codes 257..285 extra */
64 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
65 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
66 static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
67 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
68 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
69 8193, 12289, 16385, 24577, 0, 0};
70 static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
71 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
72 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
73 28, 28, 29, 29, 64, 64};
74
75 /*
76 Process a set of code lengths to create a canonical Huffman code. The
77 code lengths are lens[0..codes-1]. Each length corresponds to the
78 symbols 0..codes-1. The Huffman code is generated by first sorting the
79 symbols by length from short to long, and retaining the symbol order
80 for codes with equal lengths. Then the code starts with all zero bits
81 for the first code of the shortest length, and the codes are integer
82 increments for the same length, and zeros are appended as the length
83 increases. For the deflate format, these bits are stored backwards
84 from their more natural integer increment ordering, and so when the
85 decoding tables are built in the large loop below, the integer codes
86 are incremented backwards.
87
88 This routine assumes, but does not check, that all of the entries in
89 lens[] are in the range 0..MAXBITS. The caller must assure this.
90 1..MAXBITS is interpreted as that code length. zero means that that
91 symbol does not occur in this code.
92
93 The codes are sorted by computing a count of codes for each length,
94 creating from that a table of starting indices for each length in the
95 sorted table, and then entering the symbols in order in the sorted
96 table. The sorted table is work[], with that space being provided by
97 the caller.
98
99 The length counts are used for other purposes as well, i.e. finding
100 the minimum and maximum length codes, determining if there are any
101 codes at all, checking for a valid set of lengths, and looking ahead
102 at length counts to determine sub-table sizes when building the
103 decoding tables.
104 */
105
106 /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
107 for (len = 0; len <= MAXBITS; len++)
108 count[len] = 0;
109 for (sym = 0; sym < codes; sym++)
110 count[lens[sym]]++;
111
112 /* bound code lengths, force root to be within code lengths */
113 root = *bits;
114 for (max = MAXBITS; max >= 1; max--)
115 if (count[max] != 0) break;
116 if (root > max) root = max;
117 if (max == 0) { /* no symbols to code at all */
118 this.op = (unsigned char)64; /* invalid code marker */
119 this.bits = (unsigned char)1;
120 this.val = (unsigned short)0;
121 *(*table)++ = this; /* make a table to force an error */
122 *(*table)++ = this;
123 *bits = 1;
124 return 0; /* no symbols, but wait for decoding to report error */
125 }
126 for (min = 1; min <= MAXBITS; min++)
127 if (count[min] != 0) break;
128 if (root < min) root = min;
129
130 /* check for an over-subscribed or incomplete set of lengths */
131 left = 1;
132 for (len = 1; len <= MAXBITS; len++) {
133 left <<= 1;
134 left -= count[len];
135 if (left < 0) return -1; /* over-subscribed */
136 }
137 if (left > 0 && (type == CODES || max != 1))
138 return -1; /* incomplete set */
139
140 /* generate offsets into symbol table for each length for sorting */
141 offs[1] = 0;
142 for (len = 1; len < MAXBITS; len++)
143 offs[len + 1] = offs[len] + count[len];
144
145 /* sort symbols by length, by symbol order within each length */
146 for (sym = 0; sym < codes; sym++)
147 if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
148
149 /*
150 Create and fill in decoding tables. In this loop, the table being
151 filled is at next and has curr index bits. The code being used is huff
152 with length len. That code is converted to an index by dropping drop
153 bits off of the bottom. For codes where len is less than drop + curr,
154 those top drop + curr - len bits are incremented through all values to
155 fill the table with replicated entries.
156
157 root is the number of index bits for the root table. When len exceeds
158 root, sub-tables are created pointed to by the root entry with an index
159 of the low root bits of huff. This is saved in low to check for when a
160 new sub-table should be started. drop is zero when the root table is
161 being filled, and drop is root when sub-tables are being filled.
162
163 When a new sub-table is needed, it is necessary to look ahead in the
164 code lengths to determine what size sub-table is needed. The length
165 counts are used for this, and so count[] is decremented as codes are
166 entered in the tables.
167
168 used keeps track of how many table entries have been allocated from the
169 provided *table space. It is checked when a LENS table is being made
170 against the space in *table, ENOUGH, minus the maximum space needed by
171 the worst case distance code, MAXD. This should never happen, but the
172 sufficiency of ENOUGH has not been proven exhaustively, hence the check.
173 This assumes that when type == LENS, bits == 9.
174
175 sym increments through all symbols, and the loop terminates when
176 all codes of length max, i.e. all codes, have been processed. This
177 routine permits incomplete codes, so another loop after this one fills
178 in the rest of the decoding tables with invalid code markers.
179 */
180
181 /* set up for code type */
182 switch (type) {
183 case CODES:
184 base = extra = work; /* dummy value--not used */
185 end = 19;
186 break;
187 case LENS:
188 base = lbase;
189 base -= 257;
190 extra = lext;
191 extra -= 257;
192 end = 256;
193 break;
194 default: /* DISTS */
195 base = dbase;
196 extra = dext;
197 end = -1;
198 }
108 199
109 uInt a; /* counter for codes of length k */ 200 /* initialize state for loop */
110 uInt c[BMAX+1]; /* bit length count table */ 201 huff = 0; /* starting code */
111 uInt f; /* i repeats in table every f entries */ 202 sym = 0; /* starting code symbol */
112 int g; /* maximum code length */ 203 len = min; /* starting code length */
113 int h; /* table level */ 204 next = *table; /* current table to fill in */
114 register uInt i; /* counter, current code */ 205 curr = root; /* current table index bits */
115 register uInt j; /* counter */ 206 drop = 0; /* current bits to drop from code for index */
116 register int k; /* number of bits in current code */ 207 low = (unsigned)(-1); /* trigger new sub-table when len > root */
117 int l; /* bits per table (returned in m) */ 208 used = 1U << root; /* use root table entries */
118 uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ 209 mask = used - 1; /* mask for comparing low */
119 register uInt *p; /* pointer into c[], b[], or v[] */ 210
120 inflate_huft *q; /* points to current table */ 211 /* check available table space */
121 struct inflate_huft_s r; /* table entry for structure assignment */ 212 if (type == LENS && used >= ENOUGH - MAXD)
122 inflate_huft *u[BMAX]; /* table stack */ 213 return 1;
123 register int w; /* bits before this table == (l * h) */ 214
124 uInt x[BMAX+1]; /* bit offsets, then code stack */ 215 /* process all codes and make table entries */
125 uInt *xp; /* pointer into x */ 216 for (;;) {
126 int y; /* number of dummy codes added */ 217 /* create table entry */
127 uInt z; /* number of entries in current table */ 218 this.bits = (unsigned char)(len - drop);
128 219 if ((int)(work[sym]) < end) {
129 220 this.op = (unsigned char)0;
130 /* Generate counts for each bit length */ 221 this.val = work[sym];
131 p = c;
132#define C0 *p++ = 0;
133#define C2 C0 C0 C0 C0
134#define C4 C2 C2 C2 C2
135 C4 /* clear c[]--assume BMAX+1 is 16 */
136 p = b; i = n;
137 do {
138 c[*p++]++; /* assume all entries <= BMAX */
139 } while (--i);
140 if (c[0] == n) /* null input--all zero length codes */
141 {
142 *t = NULL;
143 *m = 0;
144 return Z_OK;
145 }
146
147
148 /* Find minimum and maximum length, bound *m by those */
149 l = *m;
150 for (j = 1; j <= BMAX; j++)
151 if (c[j])
152 break;
153 k = j; /* minimum code length */
154 if ((uInt)l < j)
155 l = j;
156 for (i = BMAX; i; i--)
157 if (c[i])
158 break;
159 g = i; /* maximum code length */
160 if ((uInt)l > i)
161 l = i;
162 *m = l;
163
164
165 /* Adjust last length count to fill out codes, if needed */
166 for (y = 1 << j; j < i; j++, y <<= 1)
167 if ((y -= c[j]) < 0)
168 return Z_DATA_ERROR;
169 if ((y -= c[i]) < 0)
170 return Z_DATA_ERROR;
171 c[i] += y;
172
173
174 /* Generate starting offsets into the value table for each length */
175 x[1] = j = 0;
176 p = c + 1; xp = x + 2;
177 while (--i) { /* note that i == g from above */
178 *xp++ = (j += *p++);
179 }
180
181
182 /* Make a table of values in order of bit lengths */
183 p = b; i = 0;
184 do {
185 if ((j = *p++) != 0)
186 v[x[j]++] = i;
187 } while (++i < n);
188 n = x[g]; /* set n to length of v */
189
190
191 /* Generate the Huffman codes and for each, make the table entries */
192 x[0] = i = 0; /* first Huffman code is zero */
193 p = v; /* grab values in bit order */
194 h = -1; /* no tables yet--level -1 */
195 w = -l; /* bits decoded == (l * h) */
196 u[0] = NULL; /* just to keep compilers happy */
197 q = NULL; /* ditto */
198 z = 0; /* ditto */
199
200 /* go through the bit lengths (k already is bits in shortest code) */
201 for (; k <= g; k++)
202 {
203 a = c[k];
204 while (a--)
205 {
206 /* here i is the Huffman code of length k bits for value *p */
207 /* make tables up to required level */
208 while (k > w + l)
209 {
210 h++;
211 w += l; /* previous table always l bits */
212
213 /* compute minimum size table less than or equal to l bits */
214 z = g - w;
215 z = z > (uInt)l ? l : z; /* table size upper limit */
216 if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
217 { /* too few codes for k-w bit table */
218 f -= a + 1; /* deduct codes from patterns left */
219 xp = c + k;
220 if (j < z)
221 while (++j < z) /* try smaller tables up to z bits */
222 {
223 if ((f <<= 1) <= *++xp)
224 break; /* enough codes to use up j bits */
225 f -= *xp; /* else deduct codes from patterns */
226 }
227 } 222 }
228 z = 1 << j; /* table entries for j-bit table */ 223 else if ((int)(work[sym]) > end) {
229 224 this.op = (unsigned char)(extra[work[sym]]);
230 /* allocate new table */ 225 this.val = base[work[sym]];
231 if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ 226 }
232 return Z_DATA_ERROR; /* overflow of MANY */ 227 else {
233 u[h] = q = hp + *hn; 228 this.op = (unsigned char)(32 + 64); /* end of block */
234 *hn += z; 229 this.val = 0;
235
236 /* connect to last table, if there is one */
237 if (h)
238 {
239 x[h] = i; /* save pattern for backing up */
240 r.bits = (Byte)l; /* bits to dump before this table */
241 r.exop = (Byte)j; /* bits in this table */
242 j = i >> (w - l);
243 r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
244 u[h-1][j] = r; /* connect to last table */
245 } 230 }
246 else
247 *t = q; /* first table is returned result */
248 }
249
250 /* set up table entry in r */
251 r.bits = (Byte)(k - w);
252 if (p >= v + n)
253 r.exop = 128 + 64; /* out of values--invalid code */
254 else if (*p < s)
255 {
256 r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
257 r.base = *p++; /* simple code is just the value */
258 }
259 else
260 {
261 r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
262 r.base = d[*p++ - s];
263 }
264
265 /* fill code-like entries with r */
266 f = 1 << (k - w);
267 for (j = i >> w; j < z; j += f)
268 q[j] = r;
269
270 /* backwards increment the k-bit code i */
271 for (j = 1 << (k - 1); i & j; j >>= 1)
272 i ^= j;
273 i ^= j;
274
275 /* backup over finished tables */
276 mask = (1 << w) - 1; /* needed on HP, cc -O bug */
277 while ((i & mask) != x[h])
278 {
279 h--; /* don't need to update q */
280 w -= l;
281 mask = (1 << w) - 1;
282 }
283 }
284 }
285 231
232 /* replicate for those indices with low len bits equal to huff */
233 incr = 1U << (len - drop);
234 fill = 1U << curr;
235 min = fill; /* save offset to next table */
236 do {
237 fill -= incr;
238 next[(huff >> drop) + fill] = this;
239 } while (fill != 0);
240
241 /* backwards increment the len-bit code huff */
242 incr = 1U << (len - 1);
243 while (huff & incr)
244 incr >>= 1;
245 if (incr != 0) {
246 huff &= incr - 1;
247 huff += incr;
248 }
249 else
250 huff = 0;
286 251
287 /* Return Z_BUF_ERROR if we were given an incomplete table */ 252 /* go to next symbol, update count, len */
288 return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; 253 sym++;
289} 254 if (--(count[len]) == 0) {
255 if (len == max) break;
256 len = lens[work[sym]];
257 }
290 258
259 /* create new sub-table if needed */
260 if (len > root && (huff & mask) != low) {
261 /* if first time, transition to sub-tables */
262 if (drop == 0)
263 drop = root;
264
265 /* increment past last table */
266 next += min; /* here min is 1 << curr */
267
268 /* determine length of next table */
269 curr = len - drop;
270 left = (int)(1 << curr);
271 while (curr + drop < max) {
272 left -= count[curr + drop];
273 if (left <= 0) break;
274 curr++;
275 left <<= 1;
276 }
291 277
292int zlib_inflate_trees_bits( 278 /* check for enough space */
293 uInt *c, /* 19 code lengths */ 279 used += 1U << curr;
294 uInt *bb, /* bits tree desired/actual depth */ 280 if (type == LENS && used >= ENOUGH - MAXD)
295 inflate_huft **tb, /* bits tree result */ 281 return 1;
296 inflate_huft *hp, /* space for trees */
297 z_streamp z /* for messages */
298)
299{
300 int r;
301 uInt hn = 0; /* hufts used in space */
302 uInt *v; /* work area for huft_build */
303
304 v = WS(z)->tree_work_area_1;
305 r = huft_build(c, 19, 19, NULL, NULL, tb, bb, hp, &hn, v);
306 if (r == Z_DATA_ERROR)
307 z->msg = (char*)"oversubscribed dynamic bit lengths tree";
308 else if (r == Z_BUF_ERROR || *bb == 0)
309 {
310 z->msg = (char*)"incomplete dynamic bit lengths tree";
311 r = Z_DATA_ERROR;
312 }
313 return r;
314}
315 282
316int zlib_inflate_trees_dynamic( 283 /* point entry in root table to sub-table */
317 uInt nl, /* number of literal/length codes */ 284 low = huff & mask;
318 uInt nd, /* number of distance codes */ 285 (*table)[low].op = (unsigned char)curr;
319 uInt *c, /* that many (total) code lengths */ 286 (*table)[low].bits = (unsigned char)root;
320 uInt *bl, /* literal desired/actual bit depth */ 287 (*table)[low].val = (unsigned short)(next - *table);
321 uInt *bd, /* distance desired/actual bit depth */ 288 }
322 inflate_huft **tl, /* literal/length tree result */
323 inflate_huft **td, /* distance tree result */
324 inflate_huft *hp, /* space for trees */
325 z_streamp z /* for messages */
326)
327{
328 int r;
329 uInt hn = 0; /* hufts used in space */
330 uInt *v; /* work area for huft_build */
331
332 /* allocate work area */
333 v = WS(z)->tree_work_area_2;
334
335 /* build literal/length tree */
336 r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
337 if (r != Z_OK || *bl == 0)
338 {
339 if (r == Z_DATA_ERROR)
340 z->msg = (char*)"oversubscribed literal/length tree";
341 else if (r != Z_MEM_ERROR)
342 {
343 z->msg = (char*)"incomplete literal/length tree";
344 r = Z_DATA_ERROR;
345 }
346 return r;
347 }
348
349 /* build distance tree */
350 r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
351 if (r != Z_OK || (*bd == 0 && nl > 257))
352 {
353 if (r == Z_DATA_ERROR)
354 z->msg = (char*)"oversubscribed distance tree";
355 else if (r == Z_BUF_ERROR) {
356#ifdef PKZIP_BUG_WORKAROUND
357 r = Z_OK;
358 }
359#else
360 z->msg = (char*)"incomplete distance tree";
361 r = Z_DATA_ERROR;
362 }
363 else if (r != Z_MEM_ERROR)
364 {
365 z->msg = (char*)"empty distance tree with lengths";
366 r = Z_DATA_ERROR;
367 } 289 }
368 return r;
369#endif
370 }
371 290
372 /* done */ 291 /*
373 return Z_OK; 292 Fill in rest of table for incomplete codes. This loop is similar to the
374} 293 loop above in incrementing huff for table indices. It is assumed that
294 len is equal to curr + drop, so there is no loop needed to increment
295 through high index bits. When the current sub-table is filled, the loop
296 drops back to the root table to fill in any remaining entries there.
297 */
298 this.op = (unsigned char)64; /* invalid code marker */
299 this.bits = (unsigned char)(len - drop);
300 this.val = (unsigned short)0;
301 while (huff != 0) {
302 /* when done with sub-table, drop back to root table */
303 if (drop != 0 && (huff & mask) != low) {
304 drop = 0;
305 len = root;
306 next = *table;
307 this.bits = (unsigned char)len;
308 }
375 309
310 /* put invalid code marker in table */
311 next[huff >> drop] = this;
376 312
377int zlib_inflate_trees_fixed( 313 /* backwards increment the len-bit code huff */
378 uInt *bl, /* literal desired/actual bit depth */ 314 incr = 1U << (len - 1);
379 uInt *bd, /* distance desired/actual bit depth */ 315 while (huff & incr)
380 inflate_huft **tl, /* literal/length tree result */ 316 incr >>= 1;
381 inflate_huft **td, /* distance tree result */ 317 if (incr != 0) {
382 inflate_huft *hp, /* space for trees */ 318 huff &= incr - 1;
383 z_streamp z /* for memory allocation */ 319 huff += incr;
384) 320 }
385{ 321 else
386 int i; /* temporary variable */ 322 huff = 0;
387 unsigned l[288]; /* length list for huft_build */ 323 }
388 uInt *v; /* work area for huft_build */ 324
389 325 /* set return parameters */
390 /* set up literal table */ 326 *table += used;
391 for (i = 0; i < 144; i++) 327 *bits = root;
392 l[i] = 8; 328 return 0;
393 for (; i < 256; i++)
394 l[i] = 9;
395 for (; i < 280; i++)
396 l[i] = 7;
397 for (; i < 288; i++) /* make a complete, but wrong code set */
398 l[i] = 8;
399 *bl = 9;
400 v = WS(z)->tree_work_area_1;
401 if ((i = huft_build(l, 288, 257, cplens, cplext, tl, bl, hp, &i, v)) != 0)
402 return i;
403
404 /* set up distance table */
405 for (i = 0; i < 30; i++) /* make an incomplete code set */
406 l[i] = 5;
407 *bd = 5;
408 if ((i = huft_build(l, 30, 0, cpdist, cpdext, td, bd, hp, &i, v)) > 1)
409 return i;
410
411 return Z_OK;
412} 329}
diff --git a/lib/zlib_inflate/inftrees.h b/lib/zlib_inflate/inftrees.h
index e37705adc008..5f5219b1240e 100644
--- a/lib/zlib_inflate/inftrees.h
+++ b/lib/zlib_inflate/inftrees.h
@@ -1,6 +1,6 @@
1/* inftrees.h -- header to use inftrees.c 1/* inftrees.h -- header to use inftrees.c
2 * Copyright (C) 1995-1998 Mark Adler 2 * Copyright (C) 1995-2005 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
6/* WARNING: this file should *not* be used by applications. It is 6/* WARNING: this file should *not* be used by applications. It is
@@ -8,57 +8,48 @@
8 subject to change. Applications should only use zlib.h. 8 subject to change. Applications should only use zlib.h.
9 */ 9 */
10 10
11/* Huffman code lookup table entry--this entry is four bytes for machines 11/* Structure for decoding tables. Each entry provides either the
12 that have 16-bit pointers (e.g. PC's in the small or medium model). */ 12 information needed to do the operation requested by the code that
13 13 indexed that table entry, or it provides a pointer to another
14#ifndef _INFTREES_H 14 table that indexes more bits of the code. op indicates whether
15#define _INFTREES_H 15 the entry is a pointer to another table, a literal, a length or
16 16 distance, an end-of-block, or an invalid code. For a table
17typedef struct inflate_huft_s inflate_huft; 17 pointer, the low four bits of op is the number of index bits of
18 18 that table. For a length or distance, the low four bits of op
19struct inflate_huft_s { 19 is the number of extra bits to get after the code. bits is
20 union { 20 the number of bits in this code or part of the code to drop off
21 struct { 21 of the bit buffer. val is the actual byte to output in the case
22 Byte Exop; /* number of extra bits or operation */ 22 of a literal, the base length or distance, or the offset from
23 Byte Bits; /* number of bits in this code or subcode */ 23 the current table to the next table. Each entry is four bytes. */
24 } what; 24typedef struct {
25 uInt pad; /* pad structure to a power of 2 (4 bytes for */ 25 unsigned char op; /* operation, extra bits, table bits */
26 } word; /* 16-bit, 8 bytes for 32-bit int's) */ 26 unsigned char bits; /* bits in this part of the code */
27 uInt base; /* literal, length base, distance base, 27 unsigned short val; /* offset in table or code value */
28 or table offset */ 28} code;
29}; 29
30/* op values as set by inflate_table():
31 00000000 - literal
32 0000tttt - table link, tttt != 0 is the number of table index bits
33 0001eeee - length or distance, eeee is the number of extra bits
34 01100000 - end of block
35 01000000 - invalid code
36 */
30 37
31/* Maximum size of dynamic tree. The maximum found in a long but non- 38/* Maximum size of dynamic tree. The maximum found in a long but non-
32 exhaustive search was 1004 huft structures (850 for length/literals 39 exhaustive search was 1444 code structures (852 for length/literals
33 and 154 for distances, the latter actually the result of an 40 and 592 for distances, the latter actually the result of an
34 exhaustive search). The actual maximum is not known, but the 41 exhaustive search). The true maximum is not known, but the value
35 value below is more than safe. */ 42 below is more than safe. */
36#define MANY 1440 43#define ENOUGH 2048
37 44#define MAXD 592
38extern int zlib_inflate_trees_bits ( 45
39 uInt *, /* 19 code lengths */ 46/* Type of code to build for inftable() */
40 uInt *, /* bits tree desired/actual depth */ 47typedef enum {
41 inflate_huft **, /* bits tree result */ 48 CODES,
42 inflate_huft *, /* space for trees */ 49 LENS,
43 z_streamp); /* for messages */ 50 DISTS
44 51} codetype;
45extern int zlib_inflate_trees_dynamic ( 52
46 uInt, /* number of literal/length codes */ 53extern int zlib_inflate_table (codetype type, unsigned short *lens,
47 uInt, /* number of distance codes */ 54 unsigned codes, code **table,
48 uInt *, /* that many (total) code lengths */ 55 unsigned *bits, unsigned short *work);
49 uInt *, /* literal desired/actual bit depth */
50 uInt *, /* distance desired/actual bit depth */
51 inflate_huft **, /* literal/length tree result */
52 inflate_huft **, /* distance tree result */
53 inflate_huft *, /* space for trees */
54 z_streamp); /* for messages */
55
56extern int zlib_inflate_trees_fixed (
57 uInt *, /* literal desired/actual bit depth */
58 uInt *, /* distance desired/actual bit depth */
59 inflate_huft **, /* literal/length tree result */
60 inflate_huft **, /* distance tree result */
61 inflate_huft *, /* space for trees */
62 z_streamp); /* for memory allocation */
63
64#endif /* _INFTREES_H */
diff --git a/lib/zlib_inflate/infutil.c b/lib/zlib_inflate/infutil.c
deleted file mode 100644
index 00202b3438e1..000000000000
--- a/lib/zlib_inflate/infutil.c
+++ /dev/null
@@ -1,88 +0,0 @@
1/* inflate_util.c -- data and routines common to blocks and codes
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include <linux/zutil.h>
7#include "infblock.h"
8#include "inftrees.h"
9#include "infcodes.h"
10#include "infutil.h"
11
12struct inflate_codes_state;
13
14/* And'ing with mask[n] masks the lower n bits */
15uInt zlib_inflate_mask[17] = {
16 0x0000,
17 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
18 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
19};
20
21
22/* copy as much as possible from the sliding window to the output area */
23int zlib_inflate_flush(
24 inflate_blocks_statef *s,
25 z_streamp z,
26 int r
27)
28{
29 uInt n;
30 Byte *p;
31 Byte *q;
32
33 /* local copies of source and destination pointers */
34 p = z->next_out;
35 q = s->read;
36
37 /* compute number of bytes to copy as far as end of window */
38 n = (uInt)((q <= s->write ? s->write : s->end) - q);
39 if (n > z->avail_out) n = z->avail_out;
40 if (n && r == Z_BUF_ERROR) r = Z_OK;
41
42 /* update counters */
43 z->avail_out -= n;
44 z->total_out += n;
45
46 /* update check information */
47 if (s->checkfn != NULL)
48 z->adler = s->check = (*s->checkfn)(s->check, q, n);
49
50 /* copy as far as end of window */
51 memcpy(p, q, n);
52 p += n;
53 q += n;
54
55 /* see if more to copy at beginning of window */
56 if (q == s->end)
57 {
58 /* wrap pointers */
59 q = s->window;
60 if (s->write == s->end)
61 s->write = s->window;
62
63 /* compute bytes to copy */
64 n = (uInt)(s->write - q);
65 if (n > z->avail_out) n = z->avail_out;
66 if (n && r == Z_BUF_ERROR) r = Z_OK;
67
68 /* update counters */
69 z->avail_out -= n;
70 z->total_out += n;
71
72 /* update check information */
73 if (s->checkfn != NULL)
74 z->adler = s->check = (*s->checkfn)(s->check, q, n);
75
76 /* copy */
77 memcpy(p, q, n);
78 p += n;
79 q += n;
80 }
81
82 /* update pointers */
83 z->next_out = p;
84 s->read = q;
85
86 /* done */
87 return r;
88}
diff --git a/lib/zlib_inflate/infutil.h b/lib/zlib_inflate/infutil.h
index a15875fc5f72..eb1a9007bd86 100644
--- a/lib/zlib_inflate/infutil.h
+++ b/lib/zlib_inflate/infutil.h
@@ -11,184 +11,12 @@
11#ifndef _INFUTIL_H 11#ifndef _INFUTIL_H
12#define _INFUTIL_H 12#define _INFUTIL_H
13 13
14#include <linux/zconf.h> 14#include <linux/zlib.h>
15#include "inftrees.h"
16#include "infcodes.h"
17
18typedef enum {
19 TYPE, /* get type bits (3, including end bit) */
20 LENS, /* get lengths for stored */
21 STORED, /* processing stored block */
22 TABLE, /* get table lengths */
23 BTREE, /* get bit lengths tree for a dynamic block */
24 DTREE, /* get length, distance trees for a dynamic block */
25 CODES, /* processing fixed or dynamic block */
26 DRY, /* output remaining window bytes */
27 B_DONE, /* finished last block, done */
28 B_BAD} /* got a data error--stuck here */
29inflate_block_mode;
30
31/* inflate blocks semi-private state */
32struct inflate_blocks_state {
33
34 /* mode */
35 inflate_block_mode mode; /* current inflate_block mode */
36
37 /* mode dependent information */
38 union {
39 uInt left; /* if STORED, bytes left to copy */
40 struct {
41 uInt table; /* table lengths (14 bits) */
42 uInt index; /* index into blens (or border) */
43 uInt *blens; /* bit lengths of codes */
44 uInt bb; /* bit length tree depth */
45 inflate_huft *tb; /* bit length decoding tree */
46 } trees; /* if DTREE, decoding info for trees */
47 struct {
48 inflate_codes_statef
49 *codes;
50 } decode; /* if CODES, current state */
51 } sub; /* submode */
52 uInt last; /* true if this block is the last block */
53
54 /* mode independent information */
55 uInt bitk; /* bits in bit buffer */
56 uLong bitb; /* bit buffer */
57 inflate_huft *hufts; /* single malloc for tree space */
58 Byte *window; /* sliding window */
59 Byte *end; /* one byte after sliding window */
60 Byte *read; /* window read pointer */
61 Byte *write; /* window write pointer */
62 check_func checkfn; /* check function */
63 uLong check; /* check on output */
64
65};
66
67
68/* defines for inflate input/output */
69/* update pointers and return */
70#define UPDBITS {s->bitb=b;s->bitk=k;}
71#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
72#define UPDOUT {s->write=q;}
73#define UPDATE {UPDBITS UPDIN UPDOUT}
74#define LEAVE {UPDATE return zlib_inflate_flush(s,z,r);}
75/* get bytes and bits */
76#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
77#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
78#define NEXTBYTE (n--,*p++)
79#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
80#define DUMPBITS(j) {b>>=(j);k-=(j);}
81/* output bytes */
82#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
83#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
84#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
85#define FLUSH {UPDOUT r=zlib_inflate_flush(s,z,r); LOADOUT}
86#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
87#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
88/* load local pointers */
89#define LOAD {LOADIN LOADOUT}
90
91/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
92extern uInt zlib_inflate_mask[17];
93
94/* copy as much as possible from the sliding window to the output area */
95extern int zlib_inflate_flush (
96 inflate_blocks_statef *,
97 z_streamp ,
98 int);
99
100/* inflate private state */
101typedef enum {
102 METHOD, /* waiting for method byte */
103 FLAG, /* waiting for flag byte */
104 DICT4, /* four dictionary check bytes to go */
105 DICT3, /* three dictionary check bytes to go */
106 DICT2, /* two dictionary check bytes to go */
107 DICT1, /* one dictionary check byte to go */
108 DICT0, /* waiting for inflateSetDictionary */
109 BLOCKS, /* decompressing blocks */
110 CHECK4, /* four check bytes to go */
111 CHECK3, /* three check bytes to go */
112 CHECK2, /* two check bytes to go */
113 CHECK1, /* one check byte to go */
114 I_DONE, /* finished check, done */
115 I_BAD} /* got an error--stay here */
116inflate_mode;
117
118struct internal_state {
119
120 /* mode */
121 inflate_mode mode; /* current inflate mode */
122
123 /* mode dependent information */
124 union {
125 uInt method; /* if FLAGS, method byte */
126 struct {
127 uLong was; /* computed check value */
128 uLong need; /* stream check value */
129 } check; /* if CHECK, check values to compare */
130 uInt marker; /* if BAD, inflateSync's marker bytes count */
131 } sub; /* submode */
132
133 /* mode independent information */
134 int nowrap; /* flag for no wrapper */
135 uInt wbits; /* log2(window size) (8..15, defaults to 15) */
136 inflate_blocks_statef
137 *blocks; /* current inflate_blocks state */
138
139};
140
141/* inflate codes private state */
142typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
143 START, /* x: set up for LEN */
144 LEN, /* i: get length/literal/eob next */
145 LENEXT, /* i: getting length extra (have base) */
146 DIST, /* i: get distance next */
147 DISTEXT, /* i: getting distance extra */
148 COPY, /* o: copying bytes in window, waiting for space */
149 LIT, /* o: got literal, waiting for output space */
150 WASH, /* o: got eob, possibly still output waiting */
151 END, /* x: got eob and all data flushed */
152 BADCODE} /* x: got error */
153inflate_codes_mode;
154
155struct inflate_codes_state {
156
157 /* mode */
158 inflate_codes_mode mode; /* current inflate_codes mode */
159
160 /* mode dependent information */
161 uInt len;
162 union {
163 struct {
164 inflate_huft *tree; /* pointer into tree */
165 uInt need; /* bits needed */
166 } code; /* if LEN or DIST, where in tree */
167 uInt lit; /* if LIT, literal */
168 struct {
169 uInt get; /* bits to get for extra */
170 uInt dist; /* distance back to copy from */
171 } copy; /* if EXT or COPY, where and how much */
172 } sub; /* submode */
173
174 /* mode independent information */
175 Byte lbits; /* ltree bits decoded per branch */
176 Byte dbits; /* dtree bits decoder per branch */
177 inflate_huft *ltree; /* literal/length/eob tree */
178 inflate_huft *dtree; /* distance tree */
179
180};
181 15
182/* memory allocation for inflation */ 16/* memory allocation for inflation */
183 17
184struct inflate_workspace { 18struct inflate_workspace {
185 inflate_codes_statef working_state; 19 struct inflate_state inflate_state;
186 struct inflate_blocks_state working_blocks_state;
187 struct internal_state internal_state;
188 unsigned int tree_work_area_1[19];
189 unsigned int tree_work_area_2[288];
190 unsigned working_blens[258 + 0x1f + 0x1f];
191 inflate_huft working_hufts[MANY];
192 unsigned char working_window[1 << MAX_WBITS]; 20 unsigned char working_window[1 << MAX_WBITS];
193}; 21};
194 22
diff --git a/security/dummy.c b/security/dummy.c
index 64f6da0f422e..6de4a4a5eb13 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -860,7 +860,7 @@ static int dummy_setprocattr(struct task_struct *p, char *name, void *value, siz
860} 860}
861 861
862#ifdef CONFIG_KEYS 862#ifdef CONFIG_KEYS
863static inline int dummy_key_alloc(struct key *key) 863static inline int dummy_key_alloc(struct key *key, struct task_struct *ctx)
864{ 864{
865 return 0; 865 return 0;
866} 866}
diff --git a/security/keys/key.c b/security/keys/key.c
index 3fdc49c6a02c..51f851557389 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -247,8 +247,8 @@ static inline void key_alloc_serial(struct key *key)
247 * instantiate the key or discard it before returning 247 * instantiate the key or discard it before returning
248 */ 248 */
249struct key *key_alloc(struct key_type *type, const char *desc, 249struct key *key_alloc(struct key_type *type, const char *desc,
250 uid_t uid, gid_t gid, key_perm_t perm, 250 uid_t uid, gid_t gid, struct task_struct *ctx,
251 int not_in_quota) 251 key_perm_t perm, int not_in_quota)
252{ 252{
253 struct key_user *user = NULL; 253 struct key_user *user = NULL;
254 struct key *key; 254 struct key *key;
@@ -318,7 +318,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
318#endif 318#endif
319 319
320 /* let the security module know about the key */ 320 /* let the security module know about the key */
321 ret = security_key_alloc(key); 321 ret = security_key_alloc(key, ctx);
322 if (ret < 0) 322 if (ret < 0)
323 goto security_error; 323 goto security_error;
324 324
@@ -822,7 +822,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
822 822
823 /* allocate a new key */ 823 /* allocate a new key */
824 key = key_alloc(ktype, description, current->fsuid, current->fsgid, 824 key = key_alloc(ktype, description, current->fsuid, current->fsgid,
825 perm, not_in_quota); 825 current, perm, not_in_quota);
826 if (IS_ERR(key)) { 826 if (IS_ERR(key)) {
827 key_ref = ERR_PTR(PTR_ERR(key)); 827 key_ref = ERR_PTR(PTR_ERR(key));
828 goto error_3; 828 goto error_3;
@@ -907,6 +907,10 @@ void key_revoke(struct key *key)
907 * it */ 907 * it */
908 down_write(&key->sem); 908 down_write(&key->sem);
909 set_bit(KEY_FLAG_REVOKED, &key->flags); 909 set_bit(KEY_FLAG_REVOKED, &key->flags);
910
911 if (key->type->revoke)
912 key->type->revoke(key);
913
910 up_write(&key->sem); 914 up_write(&key->sem);
911 915
912} /* end key_revoke() */ 916} /* end key_revoke() */
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index bffa924c1f88..1357207fc9df 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -240,13 +240,14 @@ static long keyring_read(const struct key *keyring,
240 * allocate a keyring and link into the destination keyring 240 * allocate a keyring and link into the destination keyring
241 */ 241 */
242struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 242struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
243 int not_in_quota, struct key *dest) 243 struct task_struct *ctx, int not_in_quota,
244 struct key *dest)
244{ 245{
245 struct key *keyring; 246 struct key *keyring;
246 int ret; 247 int ret;
247 248
248 keyring = key_alloc(&key_type_keyring, description, 249 keyring = key_alloc(&key_type_keyring, description,
249 uid, gid, 250 uid, gid, ctx,
250 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, 251 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
251 not_in_quota); 252 not_in_quota);
252 253
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 217a0bef3c82..4d9825f9962c 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -67,7 +67,8 @@ struct key root_session_keyring = {
67/* 67/*
68 * allocate the keyrings to be associated with a UID 68 * allocate the keyrings to be associated with a UID
69 */ 69 */
70int alloc_uid_keyring(struct user_struct *user) 70int alloc_uid_keyring(struct user_struct *user,
71 struct task_struct *ctx)
71{ 72{
72 struct key *uid_keyring, *session_keyring; 73 struct key *uid_keyring, *session_keyring;
73 char buf[20]; 74 char buf[20];
@@ -76,7 +77,7 @@ int alloc_uid_keyring(struct user_struct *user)
76 /* concoct a default session keyring */ 77 /* concoct a default session keyring */
77 sprintf(buf, "_uid_ses.%u", user->uid); 78 sprintf(buf, "_uid_ses.%u", user->uid);
78 79
79 session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0, NULL); 80 session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0, NULL);
80 if (IS_ERR(session_keyring)) { 81 if (IS_ERR(session_keyring)) {
81 ret = PTR_ERR(session_keyring); 82 ret = PTR_ERR(session_keyring);
82 goto error; 83 goto error;
@@ -86,7 +87,7 @@ int alloc_uid_keyring(struct user_struct *user)
86 * keyring */ 87 * keyring */
87 sprintf(buf, "_uid.%u", user->uid); 88 sprintf(buf, "_uid.%u", user->uid);
88 89
89 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0, 90 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0,
90 session_keyring); 91 session_keyring);
91 if (IS_ERR(uid_keyring)) { 92 if (IS_ERR(uid_keyring)) {
92 key_put(session_keyring); 93 key_put(session_keyring);
@@ -143,7 +144,7 @@ int install_thread_keyring(struct task_struct *tsk)
143 144
144 sprintf(buf, "_tid.%u", tsk->pid); 145 sprintf(buf, "_tid.%u", tsk->pid);
145 146
146 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); 147 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
147 if (IS_ERR(keyring)) { 148 if (IS_ERR(keyring)) {
148 ret = PTR_ERR(keyring); 149 ret = PTR_ERR(keyring);
149 goto error; 150 goto error;
@@ -177,7 +178,7 @@ int install_process_keyring(struct task_struct *tsk)
177 if (!tsk->signal->process_keyring) { 178 if (!tsk->signal->process_keyring) {
178 sprintf(buf, "_pid.%u", tsk->tgid); 179 sprintf(buf, "_pid.%u", tsk->tgid);
179 180
180 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); 181 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
181 if (IS_ERR(keyring)) { 182 if (IS_ERR(keyring)) {
182 ret = PTR_ERR(keyring); 183 ret = PTR_ERR(keyring);
183 goto error; 184 goto error;
@@ -217,7 +218,7 @@ static int install_session_keyring(struct task_struct *tsk,
217 if (!keyring) { 218 if (!keyring) {
218 sprintf(buf, "_ses.%u", tsk->tgid); 219 sprintf(buf, "_ses.%u", tsk->tgid);
219 220
220 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); 221 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
221 if (IS_ERR(keyring)) 222 if (IS_ERR(keyring))
222 return PTR_ERR(keyring); 223 return PTR_ERR(keyring);
223 } 224 }
@@ -390,6 +391,8 @@ key_ref_t search_process_keyrings(struct key_type *type,
390 struct request_key_auth *rka; 391 struct request_key_auth *rka;
391 key_ref_t key_ref, ret, err; 392 key_ref_t key_ref, ret, err;
392 393
394 might_sleep();
395
393 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 396 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
394 * searchable, but we failed to find a key or we found a negative key; 397 * searchable, but we failed to find a key or we found a negative key;
395 * otherwise we want to return a sample error (probably -EACCES) if 398 * otherwise we want to return a sample error (probably -EACCES) if
@@ -495,27 +498,35 @@ key_ref_t search_process_keyrings(struct key_type *type,
495 */ 498 */
496 if (context->request_key_auth && 499 if (context->request_key_auth &&
497 context == current && 500 context == current &&
498 type != &key_type_request_key_auth && 501 type != &key_type_request_key_auth
499 key_validate(context->request_key_auth) == 0
500 ) { 502 ) {
501 rka = context->request_key_auth->payload.data; 503 /* defend against the auth key being revoked */
504 down_read(&context->request_key_auth->sem);
502 505
503 key_ref = search_process_keyrings(type, description, match, 506 if (key_validate(context->request_key_auth) == 0) {
504 rka->context); 507 rka = context->request_key_auth->payload.data;
505 508
506 if (!IS_ERR(key_ref)) 509 key_ref = search_process_keyrings(type, description,
507 goto found; 510 match, rka->context);
508 511
509 switch (PTR_ERR(key_ref)) { 512 up_read(&context->request_key_auth->sem);
510 case -EAGAIN: /* no key */ 513
511 if (ret) 514 if (!IS_ERR(key_ref))
515 goto found;
516
517 switch (PTR_ERR(key_ref)) {
518 case -EAGAIN: /* no key */
519 if (ret)
520 break;
521 case -ENOKEY: /* negative key */
522 ret = key_ref;
512 break; 523 break;
513 case -ENOKEY: /* negative key */ 524 default:
514 ret = key_ref; 525 err = key_ref;
515 break; 526 break;
516 default: 527 }
517 err = key_ref; 528 } else {
518 break; 529 up_read(&context->request_key_auth->sem);
519 } 530 }
520 } 531 }
521 532
@@ -717,7 +728,7 @@ long join_session_keyring(const char *name)
717 keyring = find_keyring_by_name(name, 0); 728 keyring = find_keyring_by_name(name, 0);
718 if (PTR_ERR(keyring) == -ENOKEY) { 729 if (PTR_ERR(keyring) == -ENOKEY) {
719 /* not found - try and create a new one */ 730 /* not found - try and create a new one */
720 keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL); 731 keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk, 0, NULL);
721 if (IS_ERR(keyring)) { 732 if (IS_ERR(keyring)) {
722 ret = PTR_ERR(keyring); 733 ret = PTR_ERR(keyring);
723 goto error2; 734 goto error2;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index f030a0ccbb93..eab66a06ca53 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -48,7 +48,8 @@ static int call_sbin_request_key(struct key *key,
48 /* allocate a new session keyring */ 48 /* allocate a new session keyring */
49 sprintf(desc, "_req.%u", key->serial); 49 sprintf(desc, "_req.%u", key->serial);
50 50
51 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL); 51 keyring = keyring_alloc(desc, current->fsuid, current->fsgid,
52 current, 1, NULL);
52 if (IS_ERR(keyring)) { 53 if (IS_ERR(keyring)) {
53 ret = PTR_ERR(keyring); 54 ret = PTR_ERR(keyring);
54 goto error_alloc; 55 goto error_alloc;
@@ -137,7 +138,8 @@ static struct key *__request_key_construction(struct key_type *type,
137 138
138 /* create a key and add it to the queue */ 139 /* create a key and add it to the queue */
139 key = key_alloc(type, description, 140 key = key_alloc(type, description,
140 current->fsuid, current->fsgid, KEY_POS_ALL, 0); 141 current->fsuid, current->fsgid,
142 current, KEY_POS_ALL, 0);
141 if (IS_ERR(key)) 143 if (IS_ERR(key))
142 goto alloc_failed; 144 goto alloc_failed;
143 145
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index cce6ba6b0323..cb9817ced3fd 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -20,6 +20,7 @@
20 20
21static int request_key_auth_instantiate(struct key *, const void *, size_t); 21static int request_key_auth_instantiate(struct key *, const void *, size_t);
22static void request_key_auth_describe(const struct key *, struct seq_file *); 22static void request_key_auth_describe(const struct key *, struct seq_file *);
23static void request_key_auth_revoke(struct key *);
23static void request_key_auth_destroy(struct key *); 24static void request_key_auth_destroy(struct key *);
24static long request_key_auth_read(const struct key *, char __user *, size_t); 25static long request_key_auth_read(const struct key *, char __user *, size_t);
25 26
@@ -31,6 +32,7 @@ struct key_type key_type_request_key_auth = {
31 .def_datalen = sizeof(struct request_key_auth), 32 .def_datalen = sizeof(struct request_key_auth),
32 .instantiate = request_key_auth_instantiate, 33 .instantiate = request_key_auth_instantiate,
33 .describe = request_key_auth_describe, 34 .describe = request_key_auth_describe,
35 .revoke = request_key_auth_revoke,
34 .destroy = request_key_auth_destroy, 36 .destroy = request_key_auth_destroy,
35 .read = request_key_auth_read, 37 .read = request_key_auth_read,
36}; 38};
@@ -93,6 +95,24 @@ static long request_key_auth_read(const struct key *key,
93 95
94/*****************************************************************************/ 96/*****************************************************************************/
95/* 97/*
98 * handle revocation of an authorisation token key
99 * - called with the key sem write-locked
100 */
101static void request_key_auth_revoke(struct key *key)
102{
103 struct request_key_auth *rka = key->payload.data;
104
105 kenter("{%d}", key->serial);
106
107 if (rka->context) {
108 put_task_struct(rka->context);
109 rka->context = NULL;
110 }
111
112} /* end request_key_auth_revoke() */
113
114/*****************************************************************************/
115/*
96 * destroy an instantiation authorisation token key 116 * destroy an instantiation authorisation token key
97 */ 117 */
98static void request_key_auth_destroy(struct key *key) 118static void request_key_auth_destroy(struct key *key)
@@ -101,6 +121,11 @@ static void request_key_auth_destroy(struct key *key)
101 121
102 kenter("{%d}", key->serial); 122 kenter("{%d}", key->serial);
103 123
124 if (rka->context) {
125 put_task_struct(rka->context);
126 rka->context = NULL;
127 }
128
104 key_put(rka->target_key); 129 key_put(rka->target_key);
105 kfree(rka); 130 kfree(rka);
106 131
@@ -131,14 +156,26 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
131 * another process */ 156 * another process */
132 if (current->request_key_auth) { 157 if (current->request_key_auth) {
133 /* it is - use that instantiation context here too */ 158 /* it is - use that instantiation context here too */
159 down_read(&current->request_key_auth->sem);
160
161 /* if the auth key has been revoked, then the key we're
162 * servicing is already instantiated */
163 if (test_bit(KEY_FLAG_REVOKED,
164 &current->request_key_auth->flags))
165 goto auth_key_revoked;
166
134 irka = current->request_key_auth->payload.data; 167 irka = current->request_key_auth->payload.data;
135 rka->context = irka->context; 168 rka->context = irka->context;
136 rka->pid = irka->pid; 169 rka->pid = irka->pid;
170 get_task_struct(rka->context);
171
172 up_read(&current->request_key_auth->sem);
137 } 173 }
138 else { 174 else {
139 /* it isn't - use this process as the context */ 175 /* it isn't - use this process as the context */
140 rka->context = current; 176 rka->context = current;
141 rka->pid = current->pid; 177 rka->pid = current->pid;
178 get_task_struct(rka->context);
142 } 179 }
143 180
144 rka->target_key = key_get(target); 181 rka->target_key = key_get(target);
@@ -148,7 +185,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
148 sprintf(desc, "%x", target->serial); 185 sprintf(desc, "%x", target->serial);
149 186
150 authkey = key_alloc(&key_type_request_key_auth, desc, 187 authkey = key_alloc(&key_type_request_key_auth, desc,
151 current->fsuid, current->fsgid, 188 current->fsuid, current->fsgid, current,
152 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | 189 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
153 KEY_USR_VIEW, 1); 190 KEY_USR_VIEW, 1);
154 if (IS_ERR(authkey)) { 191 if (IS_ERR(authkey)) {
@@ -161,9 +198,15 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
161 if (ret < 0) 198 if (ret < 0)
162 goto error_inst; 199 goto error_inst;
163 200
164 kleave(" = {%d})", authkey->serial); 201 kleave(" = {%d}", authkey->serial);
165 return authkey; 202 return authkey;
166 203
204auth_key_revoked:
205 up_read(&current->request_key_auth->sem);
206 kfree(rka);
207 kleave("= -EKEYREVOKED");
208 return ERR_PTR(-EKEYREVOKED);
209
167error_inst: 210error_inst:
168 key_revoke(authkey); 211 key_revoke(authkey);
169 key_put(authkey); 212 key_put(authkey);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 54adc9d31e92..524915dfda64 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4252,6 +4252,57 @@ static int selinux_setprocattr(struct task_struct *p,
4252 return size; 4252 return size;
4253} 4253}
4254 4254
4255#ifdef CONFIG_KEYS
4256
4257static int selinux_key_alloc(struct key *k, struct task_struct *tsk)
4258{
4259 struct task_security_struct *tsec = tsk->security;
4260 struct key_security_struct *ksec;
4261
4262 ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
4263 if (!ksec)
4264 return -ENOMEM;
4265
4266 ksec->obj = k;
4267 ksec->sid = tsec->sid;
4268 k->security = ksec;
4269
4270 return 0;
4271}
4272
4273static void selinux_key_free(struct key *k)
4274{
4275 struct key_security_struct *ksec = k->security;
4276
4277 k->security = NULL;
4278 kfree(ksec);
4279}
4280
4281static int selinux_key_permission(key_ref_t key_ref,
4282 struct task_struct *ctx,
4283 key_perm_t perm)
4284{
4285 struct key *key;
4286 struct task_security_struct *tsec;
4287 struct key_security_struct *ksec;
4288
4289 key = key_ref_to_ptr(key_ref);
4290
4291 tsec = ctx->security;
4292 ksec = key->security;
4293
4294 /* if no specific permissions are requested, we skip the
4295 permission check. No serious, additional covert channels
4296 appear to be created. */
4297 if (perm == 0)
4298 return 0;
4299
4300 return avc_has_perm(tsec->sid, ksec->sid,
4301 SECCLASS_KEY, perm, NULL);
4302}
4303
4304#endif
4305
4255static struct security_operations selinux_ops = { 4306static struct security_operations selinux_ops = {
4256 .ptrace = selinux_ptrace, 4307 .ptrace = selinux_ptrace,
4257 .capget = selinux_capget, 4308 .capget = selinux_capget,
@@ -4406,6 +4457,12 @@ static struct security_operations selinux_ops = {
4406 .xfrm_state_delete_security = selinux_xfrm_state_delete, 4457 .xfrm_state_delete_security = selinux_xfrm_state_delete,
4407 .xfrm_policy_lookup = selinux_xfrm_policy_lookup, 4458 .xfrm_policy_lookup = selinux_xfrm_policy_lookup,
4408#endif 4459#endif
4460
4461#ifdef CONFIG_KEYS
4462 .key_alloc = selinux_key_alloc,
4463 .key_free = selinux_key_free,
4464 .key_permission = selinux_key_permission,
4465#endif
4409}; 4466};
4410 4467
4411static __init int selinux_init(void) 4468static __init int selinux_init(void)
@@ -4441,6 +4498,13 @@ static __init int selinux_init(void)
4441 } else { 4498 } else {
4442 printk(KERN_INFO "SELinux: Starting in permissive mode\n"); 4499 printk(KERN_INFO "SELinux: Starting in permissive mode\n");
4443 } 4500 }
4501
4502#ifdef CONFIG_KEYS
4503 /* Add security information to initial keyrings */
4504 security_key_alloc(&root_user_keyring, current);
4505 security_key_alloc(&root_session_keyring, current);
4506#endif
4507
4444 return 0; 4508 return 0;
4445} 4509}
4446 4510
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
index 70ee65a58817..bc020bde6c86 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -242,3 +242,9 @@
242 S_(SECCLASS_PACKET, PACKET__SEND, "send") 242 S_(SECCLASS_PACKET, PACKET__SEND, "send")
243 S_(SECCLASS_PACKET, PACKET__RECV, "recv") 243 S_(SECCLASS_PACKET, PACKET__RECV, "recv")
244 S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto") 244 S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto")
245 S_(SECCLASS_KEY, KEY__VIEW, "view")
246 S_(SECCLASS_KEY, KEY__READ, "read")
247 S_(SECCLASS_KEY, KEY__WRITE, "write")
248 S_(SECCLASS_KEY, KEY__SEARCH, "search")
249 S_(SECCLASS_KEY, KEY__LINK, "link")
250 S_(SECCLASS_KEY, KEY__SETATTR, "setattr")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index 1d9cf3d306bc..1205227a3a33 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -959,3 +959,11 @@
959#define PACKET__SEND 0x00000001UL 959#define PACKET__SEND 0x00000001UL
960#define PACKET__RECV 0x00000002UL 960#define PACKET__RECV 0x00000002UL
961#define PACKET__RELABELTO 0x00000004UL 961#define PACKET__RELABELTO 0x00000004UL
962
963#define KEY__VIEW 0x00000001UL
964#define KEY__READ 0x00000002UL
965#define KEY__WRITE 0x00000004UL
966#define KEY__SEARCH 0x00000008UL
967#define KEY__LINK 0x00000010UL
968#define KEY__SETATTR 0x00000020UL
969
diff --git a/security/selinux/include/class_to_string.h b/security/selinux/include/class_to_string.h
index 3aec75fee4f7..24303b61309f 100644
--- a/security/selinux/include/class_to_string.h
+++ b/security/selinux/include/class_to_string.h
@@ -60,3 +60,4 @@
60 S_("netlink_kobject_uevent_socket") 60 S_("netlink_kobject_uevent_socket")
61 S_("appletalk_socket") 61 S_("appletalk_socket")
62 S_("packet") 62 S_("packet")
63 S_("key")
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h
index a0eb9e281d18..95887aed2a68 100644
--- a/security/selinux/include/flask.h
+++ b/security/selinux/include/flask.h
@@ -62,6 +62,7 @@
62#define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 55 62#define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 55
63#define SECCLASS_APPLETALK_SOCKET 56 63#define SECCLASS_APPLETALK_SOCKET 56
64#define SECCLASS_PACKET 57 64#define SECCLASS_PACKET 57
65#define SECCLASS_KEY 58
65 66
66/* 67/*
67 * Security identifier indices for initial entities 68 * Security identifier indices for initial entities
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 54c030778882..8f5547ad1856 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -99,6 +99,11 @@ struct sk_security_struct {
99 u32 peer_sid; /* SID of peer */ 99 u32 peer_sid; /* SID of peer */
100}; 100};
101 101
102struct key_security_struct {
103 struct key *obj; /* back pointer */
104 u32 sid; /* SID of key */
105};
106
102extern unsigned int selinux_checkreqprot; 107extern unsigned int selinux_checkreqprot;
103 108
104#endif /* _SELINUX_OBJSEC_H_ */ 109#endif /* _SELINUX_OBJSEC_H_ */
diff --git a/sound/Kconfig b/sound/Kconfig
index b65ee4701f98..e0d791a98452 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -58,6 +58,8 @@ source "sound/pci/Kconfig"
58 58
59source "sound/ppc/Kconfig" 59source "sound/ppc/Kconfig"
60 60
61source "sound/aoa/Kconfig"
62
61source "sound/arm/Kconfig" 63source "sound/arm/Kconfig"
62 64
63source "sound/mips/Kconfig" 65source "sound/mips/Kconfig"
diff --git a/sound/Makefile b/sound/Makefile
index f352bb235968..a682ea30f0c9 100644
--- a/sound/Makefile
+++ b/sound/Makefile
@@ -4,7 +4,7 @@
4obj-$(CONFIG_SOUND) += soundcore.o 4obj-$(CONFIG_SOUND) += soundcore.o
5obj-$(CONFIG_SOUND_PRIME) += oss/ 5obj-$(CONFIG_SOUND_PRIME) += oss/
6obj-$(CONFIG_DMASOUND) += oss/ 6obj-$(CONFIG_DMASOUND) += oss/
7obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ 7obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ aoa/
8 8
9ifeq ($(CONFIG_SND),y) 9ifeq ($(CONFIG_SND),y)
10 obj-y += last.o 10 obj-y += last.o
diff --git a/sound/aoa/Kconfig b/sound/aoa/Kconfig
new file mode 100644
index 000000000000..a85194fe0b06
--- /dev/null
+++ b/sound/aoa/Kconfig
@@ -0,0 +1,17 @@
1menu "Apple Onboard Audio driver"
2 depends on SND!=n && PPC
3
4config SND_AOA
5 tristate "Apple Onboard Audio driver"
6 depends on SOUND && SND_PCM
7 ---help---
8 This option enables the new driver for the various
9 Apple Onboard Audio components.
10
11source "sound/aoa/fabrics/Kconfig"
12
13source "sound/aoa/codecs/Kconfig"
14
15source "sound/aoa/soundbus/Kconfig"
16
17endmenu
diff --git a/sound/aoa/Makefile b/sound/aoa/Makefile
new file mode 100644
index 000000000000..d8de3e7df48d
--- /dev/null
+++ b/sound/aoa/Makefile
@@ -0,0 +1,4 @@
1obj-$(CONFIG_SND_AOA) += core/
2obj-$(CONFIG_SND_AOA) += codecs/
3obj-$(CONFIG_SND_AOA) += fabrics/
4obj-$(CONFIG_SND_AOA_SOUNDBUS) += soundbus/
diff --git a/sound/aoa/aoa-gpio.h b/sound/aoa/aoa-gpio.h
new file mode 100644
index 000000000000..3a61f3115573
--- /dev/null
+++ b/sound/aoa/aoa-gpio.h
@@ -0,0 +1,81 @@
1/*
2 * Apple Onboard Audio GPIO definitions
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#ifndef __AOA_GPIO_H
10#define __AOA_GPIO_H
11#include <linux/workqueue.h>
12#include <linux/mutex.h>
13#include <asm/prom.h>
14
15typedef void (*notify_func_t)(void *data);
16
17enum notify_type {
18 AOA_NOTIFY_HEADPHONE,
19 AOA_NOTIFY_LINE_IN,
20 AOA_NOTIFY_LINE_OUT,
21};
22
23struct gpio_runtime;
24struct gpio_methods {
25 /* for initialisation/de-initialisation of the GPIO layer */
26 void (*init)(struct gpio_runtime *rt);
27 void (*exit)(struct gpio_runtime *rt);
28
29 /* turn off headphone, speakers, lineout */
30 void (*all_amps_off)(struct gpio_runtime *rt);
31 /* turn headphone, speakers, lineout back to previous setting */
32 void (*all_amps_restore)(struct gpio_runtime *rt);
33
34 void (*set_headphone)(struct gpio_runtime *rt, int on);
35 void (*set_speakers)(struct gpio_runtime *rt, int on);
36 void (*set_lineout)(struct gpio_runtime *rt, int on);
37
38 int (*get_headphone)(struct gpio_runtime *rt);
39 int (*get_speakers)(struct gpio_runtime *rt);
40 int (*get_lineout)(struct gpio_runtime *rt);
41
42 void (*set_hw_reset)(struct gpio_runtime *rt, int on);
43
44 /* use this to be notified of any events. The notification
45 * function is passed the data, and is called in process
46 * context by the use of schedule_work.
47 * The interface for it is that setting a function to NULL
48 * removes it, and they return 0 if the operation succeeded,
49 * and -EBUSY if the notification is already assigned by
50 * someone else. */
51 int (*set_notify)(struct gpio_runtime *rt,
52 enum notify_type type,
53 notify_func_t notify,
54 void *data);
55 /* returns 0 if not plugged in, 1 if plugged in
56 * or a negative error code */
57 int (*get_detect)(struct gpio_runtime *rt,
58 enum notify_type type);
59};
60
61struct gpio_notification {
62 notify_func_t notify;
63 void *data;
64 void *gpio_private;
65 struct work_struct work;
66 struct mutex mutex;
67};
68
69struct gpio_runtime {
70 /* to be assigned by fabric */
71 struct device_node *node;
72 /* since everyone needs this pointer anyway... */
73 struct gpio_methods *methods;
74 /* to be used by the gpio implementation */
75 int implementation_private;
76 struct gpio_notification headphone_notify;
77 struct gpio_notification line_in_notify;
78 struct gpio_notification line_out_notify;
79};
80
81#endif /* __AOA_GPIO_H */
diff --git a/sound/aoa/aoa.h b/sound/aoa/aoa.h
new file mode 100644
index 000000000000..378ef1e9879b
--- /dev/null
+++ b/sound/aoa/aoa.h
@@ -0,0 +1,131 @@
1/*
2 * Apple Onboard Audio definitions
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#ifndef __AOA_H
10#define __AOA_H
11#include <asm/prom.h>
12#include <linux/module.h>
13/* So apparently there's a reason for requiring driver.h to be included first! */
14#include <sound/driver.h>
15#include <sound/core.h>
16#include <sound/asound.h>
17#include <sound/control.h>
18#include "aoa-gpio.h"
19#include "soundbus/soundbus.h"
20
21#define MAX_CODEC_NAME_LEN 32
22
23struct aoa_codec {
24 char name[MAX_CODEC_NAME_LEN];
25
26 struct module *owner;
27
28 /* called when the fabric wants to init this codec.
29 * Do alsa card manipulations from here. */
30 int (*init)(struct aoa_codec *codec);
31
32 /* called when the fabric is done with the codec.
33 * The alsa card will be cleaned up so don't bother. */
34 void (*exit)(struct aoa_codec *codec);
35
36 /* May be NULL, but can be used by the fabric.
37 * Refcounting is the codec driver's responsibility */
38 struct device_node *node;
39
40 /* assigned by fabric before init() is called, points
41 * to the soundbus device. Cannot be NULL. */
42 struct soundbus_dev *soundbus_dev;
43
44 /* assigned by the fabric before init() is called, points
45 * to the fabric's gpio runtime record for the relevant
46 * device. */
47 struct gpio_runtime *gpio;
48
49 /* assigned by the fabric before init() is called, contains
50 * a codec specific bitmask of what outputs and inputs are
51 * actually connected */
52 u32 connected;
53
54 /* data the fabric can associate with this structure */
55 void *fabric_data;
56
57 /* private! */
58 struct list_head list;
59 struct aoa_fabric *fabric;
60};
61
62/* return 0 on success */
63extern int
64aoa_codec_register(struct aoa_codec *codec);
65extern void
66aoa_codec_unregister(struct aoa_codec *codec);
67
68#define MAX_LAYOUT_NAME_LEN 32
69
70struct aoa_fabric {
71 char name[MAX_LAYOUT_NAME_LEN];
72
73 struct module *owner;
74
75 /* once codecs register, they are passed here after.
76 * They are of course not initialised, since the
77 * fabric is responsible for initialising some fields
78 * in the codec structure! */
79 int (*found_codec)(struct aoa_codec *codec);
80 /* called for each codec when it is removed,
81 * also in the case that aoa_fabric_unregister
82 * is called and all codecs are removed
83 * from this fabric.
84 * Also called if found_codec returned 0 but
85 * the codec couldn't initialise. */
86 void (*remove_codec)(struct aoa_codec *codec);
87 /* If found_codec returned 0, and the codec
88 * could be initialised, this is called. */
89 void (*attached_codec)(struct aoa_codec *codec);
90};
91
92/* return 0 on success, -EEXIST if another fabric is
93 * registered, -EALREADY if the same fabric is registered.
94 * Passing NULL can be used to test for the presence
95 * of another fabric, if -EALREADY is returned there is
96 * no other fabric present.
97 * In the case that the function returns -EALREADY
98 * and the fabric passed is not NULL, all codecs
99 * that are not assigned yet are passed to the fabric
100 * again for reconsideration. */
101extern int
102aoa_fabric_register(struct aoa_fabric *fabric);
103
104/* it is vital to call this when the fabric exits!
105 * When calling, the remove_codec will be called
106 * for all codecs, unless it is NULL. */
107extern void
108aoa_fabric_unregister(struct aoa_fabric *fabric);
109
110/* if for some reason you want to get rid of a codec
111 * before the fabric is removed, use this.
112 * Note that remove_codec is called for it! */
113extern void
114aoa_fabric_unlink_codec(struct aoa_codec *codec);
115
116/* alsa help methods */
117struct aoa_card {
118 struct snd_card *alsa_card;
119};
120
121extern int aoa_snd_device_new(snd_device_type_t type,
122 void * device_data, struct snd_device_ops * ops);
123extern struct snd_card *aoa_get_card(void);
124extern int aoa_snd_ctl_add(struct snd_kcontrol* control);
125
126/* GPIO stuff */
127extern struct gpio_methods *pmf_gpio_methods;
128extern struct gpio_methods *ftr_gpio_methods;
129/* extern struct gpio_methods *map_gpio_methods; */
130
131#endif /* __AOA_H */
diff --git a/sound/aoa/codecs/Kconfig b/sound/aoa/codecs/Kconfig
new file mode 100644
index 000000000000..90cf58f68630
--- /dev/null
+++ b/sound/aoa/codecs/Kconfig
@@ -0,0 +1,32 @@
1config SND_AOA_ONYX
2 tristate "support Onyx chip"
3 depends on SND_AOA
4 ---help---
5 This option enables support for the Onyx (pcm3052)
6 codec chip found in the latest Apple machines
7 (most of those with digital audio output).
8
9#config SND_AOA_TOPAZ
10# tristate "support Topaz chips"
11# depends on SND_AOA
12# ---help---
13# This option enables support for the Topaz (CS84xx)
14# codec chips found in the latest Apple machines,
15# these chips do the digital input and output on
16# some PowerMacs.
17
18config SND_AOA_TAS
19 tristate "support TAS chips"
20 depends on SND_AOA
21 ---help---
22 This option enables support for the tas chips
23 found in a lot of Apple Machines, especially
24 iBooks and PowerBooks without digital.
25
26config SND_AOA_TOONIE
27 tristate "support Toonie chip"
28 depends on SND_AOA
29 ---help---
30 This option enables support for the toonie codec
31 found in the Mac Mini. If you have a Mac Mini and
32 want to hear sound, select this option.
diff --git a/sound/aoa/codecs/Makefile b/sound/aoa/codecs/Makefile
new file mode 100644
index 000000000000..31cbe68fd42f
--- /dev/null
+++ b/sound/aoa/codecs/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_SND_AOA_ONYX) += snd-aoa-codec-onyx.o
2obj-$(CONFIG_SND_AOA_TAS) += snd-aoa-codec-tas.o
3obj-$(CONFIG_SND_AOA_TOONIE) += snd-aoa-codec-toonie.o
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/snd-aoa-codec-onyx.c
new file mode 100644
index 000000000000..0b7650788f1f
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-onyx.c
@@ -0,0 +1,1113 @@
1/*
2 * Apple Onboard Audio driver for Onyx codec
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 *
8 *
9 * This is a driver for the pcm3052 codec chip (codenamed Onyx)
10 * that is present in newer Apple hardware (with digital output).
11 *
12 * The Onyx codec has the following connections (listed by the bit
13 * to be used in aoa_codec.connected):
14 * 0: analog output
15 * 1: digital output
16 * 2: line input
17 * 3: microphone input
18 * Note that even though I know of no machine that has for example
19 * the digital output connected but not the analog, I have handled
20 * all the different cases in the code so that this driver may serve
21 * as a good example of what to do.
22 *
23 * NOTE: This driver assumes that there's at most one chip to be
24 * used with one alsa card, in form of creating all kinds
25 * of mixer elements without regard for their existence.
26 * But snd-aoa assumes that there's at most one card, so
27 * this means you can only have one onyx on a system. This
28 * should probably be fixed by changing the assumption of
29 * having just a single card on a system, and making the
30 * 'card' pointer accessible to anyone who needs it instead
31 * of hiding it in the aoa_snd_* functions...
32 *
33 */
34#include <linux/delay.h>
35#include <linux/module.h>
36MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
37MODULE_LICENSE("GPL");
38MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");
39
40#include "snd-aoa-codec-onyx.h"
41#include "../aoa.h"
42#include "../soundbus/soundbus.h"
43
44
45#define PFX "snd-aoa-codec-onyx: "
46
47struct onyx {
48 /* cache registers 65 to 80, they are write-only! */
49 u8 cache[16];
50 struct i2c_client i2c;
51 struct aoa_codec codec;
52 u32 initialised:1,
53 spdif_locked:1,
54 analog_locked:1,
55 original_mute:2;
56 int open_count;
57 struct codec_info *codec_info;
58
59 /* mutex serializes concurrent access to the device
60 * and this structure.
61 */
62 struct mutex mutex;
63};
64#define codec_to_onyx(c) container_of(c, struct onyx, codec)
65
66/* both return 0 if all ok, else on error */
67static int onyx_read_register(struct onyx *onyx, u8 reg, u8 *value)
68{
69 s32 v;
70
71 if (reg != ONYX_REG_CONTROL) {
72 *value = onyx->cache[reg-FIRSTREGISTER];
73 return 0;
74 }
75 v = i2c_smbus_read_byte_data(&onyx->i2c, reg);
76 if (v < 0)
77 return -1;
78 *value = (u8)v;
79 onyx->cache[ONYX_REG_CONTROL-FIRSTREGISTER] = *value;
80 return 0;
81}
82
83static int onyx_write_register(struct onyx *onyx, u8 reg, u8 value)
84{
85 int result;
86
87 result = i2c_smbus_write_byte_data(&onyx->i2c, reg, value);
88 if (!result)
89 onyx->cache[reg-FIRSTREGISTER] = value;
90 return result;
91}
92
93/* alsa stuff */
94
95static int onyx_dev_register(struct snd_device *dev)
96{
97 return 0;
98}
99
100static struct snd_device_ops ops = {
101 .dev_register = onyx_dev_register,
102};
103
104/* this is necessary because most alsa mixer programs
105 * can't properly handle the negative range */
106#define VOLUME_RANGE_SHIFT 128
107
108static int onyx_snd_vol_info(struct snd_kcontrol *kcontrol,
109 struct snd_ctl_elem_info *uinfo)
110{
111 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
112 uinfo->count = 2;
113 uinfo->value.integer.min = -128 + VOLUME_RANGE_SHIFT;
114 uinfo->value.integer.max = -1 + VOLUME_RANGE_SHIFT;
115 return 0;
116}
117
118static int onyx_snd_vol_get(struct snd_kcontrol *kcontrol,
119 struct snd_ctl_elem_value *ucontrol)
120{
121 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
122 s8 l, r;
123
124 mutex_lock(&onyx->mutex);
125 onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
126 onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);
127 mutex_unlock(&onyx->mutex);
128
129 ucontrol->value.integer.value[0] = l + VOLUME_RANGE_SHIFT;
130 ucontrol->value.integer.value[1] = r + VOLUME_RANGE_SHIFT;
131
132 return 0;
133}
134
135static int onyx_snd_vol_put(struct snd_kcontrol *kcontrol,
136 struct snd_ctl_elem_value *ucontrol)
137{
138 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
139 s8 l, r;
140
141 mutex_lock(&onyx->mutex);
142 onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_LEFT, &l);
143 onyx_read_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT, &r);
144
145 if (l + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[0] &&
146 r + VOLUME_RANGE_SHIFT == ucontrol->value.integer.value[1]) {
147 mutex_unlock(&onyx->mutex);
148 return 0;
149 }
150
151 onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_LEFT,
152 ucontrol->value.integer.value[0]
153 - VOLUME_RANGE_SHIFT);
154 onyx_write_register(onyx, ONYX_REG_DAC_ATTEN_RIGHT,
155 ucontrol->value.integer.value[1]
156 - VOLUME_RANGE_SHIFT);
157 mutex_unlock(&onyx->mutex);
158
159 return 1;
160}
161
162static struct snd_kcontrol_new volume_control = {
163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
164 .name = "Master Playback Volume",
165 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
166 .info = onyx_snd_vol_info,
167 .get = onyx_snd_vol_get,
168 .put = onyx_snd_vol_put,
169};
170
171/* like above, this is necessary because a lot
172 * of alsa mixer programs don't handle ranges
173 * that don't start at 0 properly.
174 * even alsamixer is one of them... */
175#define INPUTGAIN_RANGE_SHIFT (-3)
176
177static int onyx_snd_inputgain_info(struct snd_kcontrol *kcontrol,
178 struct snd_ctl_elem_info *uinfo)
179{
180 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
181 uinfo->count = 1;
182 uinfo->value.integer.min = 3 + INPUTGAIN_RANGE_SHIFT;
183 uinfo->value.integer.max = 28 + INPUTGAIN_RANGE_SHIFT;
184 return 0;
185}
186
187static int onyx_snd_inputgain_get(struct snd_kcontrol *kcontrol,
188 struct snd_ctl_elem_value *ucontrol)
189{
190 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
191 u8 ig;
192
193 mutex_lock(&onyx->mutex);
194 onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &ig);
195 mutex_unlock(&onyx->mutex);
196
197 ucontrol->value.integer.value[0] =
198 (ig & ONYX_ADC_PGA_GAIN_MASK) + INPUTGAIN_RANGE_SHIFT;
199
200 return 0;
201}
202
203static int onyx_snd_inputgain_put(struct snd_kcontrol *kcontrol,
204 struct snd_ctl_elem_value *ucontrol)
205{
206 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
207 u8 v, n;
208
209 mutex_lock(&onyx->mutex);
210 onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
211 n = v;
212 n &= ~ONYX_ADC_PGA_GAIN_MASK;
213 n |= (ucontrol->value.integer.value[0] - INPUTGAIN_RANGE_SHIFT)
214 & ONYX_ADC_PGA_GAIN_MASK;
215 onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, n);
216 mutex_unlock(&onyx->mutex);
217
218 return n != v;
219}
220
221static struct snd_kcontrol_new inputgain_control = {
222 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
223 .name = "Master Capture Volume",
224 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
225 .info = onyx_snd_inputgain_info,
226 .get = onyx_snd_inputgain_get,
227 .put = onyx_snd_inputgain_put,
228};
229
230static int onyx_snd_capture_source_info(struct snd_kcontrol *kcontrol,
231 struct snd_ctl_elem_info *uinfo)
232{
233 static char *texts[] = { "Line-In", "Microphone" };
234
235 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
236 uinfo->count = 1;
237 uinfo->value.enumerated.items = 2;
238 if (uinfo->value.enumerated.item > 1)
239 uinfo->value.enumerated.item = 1;
240 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
241 return 0;
242}
243
244static int onyx_snd_capture_source_get(struct snd_kcontrol *kcontrol,
245 struct snd_ctl_elem_value *ucontrol)
246{
247 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
248 s8 v;
249
250 mutex_lock(&onyx->mutex);
251 onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
252 mutex_unlock(&onyx->mutex);
253
254 ucontrol->value.enumerated.item[0] = !!(v&ONYX_ADC_INPUT_MIC);
255
256 return 0;
257}
258
259static void onyx_set_capture_source(struct onyx *onyx, int mic)
260{
261 s8 v;
262
263 mutex_lock(&onyx->mutex);
264 onyx_read_register(onyx, ONYX_REG_ADC_CONTROL, &v);
265 v &= ~ONYX_ADC_INPUT_MIC;
266 if (mic)
267 v |= ONYX_ADC_INPUT_MIC;
268 onyx_write_register(onyx, ONYX_REG_ADC_CONTROL, v);
269 mutex_unlock(&onyx->mutex);
270}
271
272static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol,
273 struct snd_ctl_elem_value *ucontrol)
274{
275 onyx_set_capture_source(snd_kcontrol_chip(kcontrol),
276 ucontrol->value.enumerated.item[0]);
277 return 1;
278}
279
280static struct snd_kcontrol_new capture_source_control = {
281 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
282 /* If we name this 'Input Source', it properly shows up in
283 * alsamixer as a selection, * but it's shown under the
284 * 'Playback' category.
285 * If I name it 'Capture Source', it shows up in strange
286 * ways (two bools of which one can be selected at a
287 * time) but at least it's shown in the 'Capture'
288 * category.
289 * I was told that this was due to backward compatibility,
290 * but I don't understand then why the mangling is *not*
291 * done when I name it "Input Source".....
292 */
293 .name = "Capture Source",
294 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
295 .info = onyx_snd_capture_source_info,
296 .get = onyx_snd_capture_source_get,
297 .put = onyx_snd_capture_source_put,
298};
299
300static int onyx_snd_mute_info(struct snd_kcontrol *kcontrol,
301 struct snd_ctl_elem_info *uinfo)
302{
303 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
304 uinfo->count = 2;
305 uinfo->value.integer.min = 0;
306 uinfo->value.integer.max = 1;
307 return 0;
308}
309
310static int onyx_snd_mute_get(struct snd_kcontrol *kcontrol,
311 struct snd_ctl_elem_value *ucontrol)
312{
313 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
314 u8 c;
315
316 mutex_lock(&onyx->mutex);
317 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &c);
318 mutex_unlock(&onyx->mutex);
319
320 ucontrol->value.integer.value[0] = !(c & ONYX_MUTE_LEFT);
321 ucontrol->value.integer.value[1] = !(c & ONYX_MUTE_RIGHT);
322
323 return 0;
324}
325
326static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol,
327 struct snd_ctl_elem_value *ucontrol)
328{
329 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
330 u8 v = 0, c = 0;
331 int err = -EBUSY;
332
333 mutex_lock(&onyx->mutex);
334 if (onyx->analog_locked)
335 goto out_unlock;
336
337 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
338 c = v;
339 c &= ~(ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT);
340 if (!ucontrol->value.integer.value[0])
341 c |= ONYX_MUTE_LEFT;
342 if (!ucontrol->value.integer.value[1])
343 c |= ONYX_MUTE_RIGHT;
344 err = onyx_write_register(onyx, ONYX_REG_DAC_CONTROL, c);
345
346 out_unlock:
347 mutex_unlock(&onyx->mutex);
348
349 return !err ? (v != c) : err;
350}
351
352static struct snd_kcontrol_new mute_control = {
353 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
354 .name = "Master Playback Switch",
355 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
356 .info = onyx_snd_mute_info,
357 .get = onyx_snd_mute_get,
358 .put = onyx_snd_mute_put,
359};
360
361
362static int onyx_snd_single_bit_info(struct snd_kcontrol *kcontrol,
363 struct snd_ctl_elem_info *uinfo)
364{
365 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
366 uinfo->count = 1;
367 uinfo->value.integer.min = 0;
368 uinfo->value.integer.max = 1;
369 return 0;
370}
371
372#define FLAG_POLARITY_INVERT 1
373#define FLAG_SPDIFLOCK 2
374
375static int onyx_snd_single_bit_get(struct snd_kcontrol *kcontrol,
376 struct snd_ctl_elem_value *ucontrol)
377{
378 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
379 u8 c;
380 long int pv = kcontrol->private_value;
381 u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
382 u8 address = (pv >> 8) & 0xff;
383 u8 mask = pv & 0xff;
384
385 mutex_lock(&onyx->mutex);
386 onyx_read_register(onyx, address, &c);
387 mutex_unlock(&onyx->mutex);
388
389 ucontrol->value.integer.value[0] = !!(c & mask) ^ polarity;
390
391 return 0;
392}
393
394static int onyx_snd_single_bit_put(struct snd_kcontrol *kcontrol,
395 struct snd_ctl_elem_value *ucontrol)
396{
397 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
398 u8 v = 0, c = 0;
399 int err;
400 long int pv = kcontrol->private_value;
401 u8 polarity = (pv >> 16) & FLAG_POLARITY_INVERT;
402 u8 spdiflock = (pv >> 16) & FLAG_SPDIFLOCK;
403 u8 address = (pv >> 8) & 0xff;
404 u8 mask = pv & 0xff;
405
406 mutex_lock(&onyx->mutex);
407 if (spdiflock && onyx->spdif_locked) {
408 /* even if alsamixer doesn't care.. */
409 err = -EBUSY;
410 goto out_unlock;
411 }
412 onyx_read_register(onyx, address, &v);
413 c = v;
414 c &= ~(mask);
415 if (!!ucontrol->value.integer.value[0] ^ polarity)
416 c |= mask;
417 err = onyx_write_register(onyx, address, c);
418
419 out_unlock:
420 mutex_unlock(&onyx->mutex);
421
422 return !err ? (v != c) : err;
423}
424
425#define SINGLE_BIT(n, type, description, address, mask, flags) \
426static struct snd_kcontrol_new n##_control = { \
427 .iface = SNDRV_CTL_ELEM_IFACE_##type, \
428 .name = description, \
429 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
430 .info = onyx_snd_single_bit_info, \
431 .get = onyx_snd_single_bit_get, \
432 .put = onyx_snd_single_bit_put, \
433 .private_value = (flags << 16) | (address << 8) | mask \
434}
435
436SINGLE_BIT(spdif,
437 MIXER,
438 SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
439 ONYX_REG_DIG_INFO4,
440 ONYX_SPDIF_ENABLE,
441 FLAG_SPDIFLOCK);
442SINGLE_BIT(ovr1,
443 MIXER,
444 "Oversampling Rate",
445 ONYX_REG_DAC_CONTROL,
446 ONYX_OVR1,
447 0);
448SINGLE_BIT(flt0,
449 MIXER,
450 "Fast Digital Filter Rolloff",
451 ONYX_REG_DAC_FILTER,
452 ONYX_ROLLOFF_FAST,
453 FLAG_POLARITY_INVERT);
454SINGLE_BIT(hpf,
455 MIXER,
456 "Highpass Filter",
457 ONYX_REG_ADC_HPF_BYPASS,
458 ONYX_HPF_DISABLE,
459 FLAG_POLARITY_INVERT);
460SINGLE_BIT(dm12,
461 MIXER,
462 "Digital De-Emphasis",
463 ONYX_REG_DAC_DEEMPH,
464 ONYX_DIGDEEMPH_CTRL,
465 0);
466
467static int onyx_spdif_info(struct snd_kcontrol *kcontrol,
468 struct snd_ctl_elem_info *uinfo)
469{
470 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
471 uinfo->count = 1;
472 return 0;
473}
474
475static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol,
476 struct snd_ctl_elem_value *ucontrol)
477{
478 /* datasheet page 30, all others are 0 */
479 ucontrol->value.iec958.status[0] = 0x3e;
480 ucontrol->value.iec958.status[1] = 0xff;
481
482 ucontrol->value.iec958.status[3] = 0x3f;
483 ucontrol->value.iec958.status[4] = 0x0f;
484
485 return 0;
486}
487
488static struct snd_kcontrol_new onyx_spdif_mask = {
489 .access = SNDRV_CTL_ELEM_ACCESS_READ,
490 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
491 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
492 .info = onyx_spdif_info,
493 .get = onyx_spdif_mask_get,
494};
495
496static int onyx_spdif_get(struct snd_kcontrol *kcontrol,
497 struct snd_ctl_elem_value *ucontrol)
498{
499 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
500 u8 v;
501
502 mutex_lock(&onyx->mutex);
503 onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
504 ucontrol->value.iec958.status[0] = v & 0x3e;
505
506 onyx_read_register(onyx, ONYX_REG_DIG_INFO2, &v);
507 ucontrol->value.iec958.status[1] = v;
508
509 onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
510 ucontrol->value.iec958.status[3] = v & 0x3f;
511
512 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
513 ucontrol->value.iec958.status[4] = v & 0x0f;
514 mutex_unlock(&onyx->mutex);
515
516 return 0;
517}
518
519static int onyx_spdif_put(struct snd_kcontrol *kcontrol,
520 struct snd_ctl_elem_value *ucontrol)
521{
522 struct onyx *onyx = snd_kcontrol_chip(kcontrol);
523 u8 v;
524
525 mutex_lock(&onyx->mutex);
526 onyx_read_register(onyx, ONYX_REG_DIG_INFO1, &v);
527 v = (v & ~0x3e) | (ucontrol->value.iec958.status[0] & 0x3e);
528 onyx_write_register(onyx, ONYX_REG_DIG_INFO1, v);
529
530 v = ucontrol->value.iec958.status[1];
531 onyx_write_register(onyx, ONYX_REG_DIG_INFO2, v);
532
533 onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &v);
534 v = (v & ~0x3f) | (ucontrol->value.iec958.status[3] & 0x3f);
535 onyx_write_register(onyx, ONYX_REG_DIG_INFO3, v);
536
537 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
538 v = (v & ~0x0f) | (ucontrol->value.iec958.status[4] & 0x0f);
539 onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
540 mutex_unlock(&onyx->mutex);
541
542 return 1;
543}
544
545static struct snd_kcontrol_new onyx_spdif_ctrl = {
546 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
547 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
548 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
549 .info = onyx_spdif_info,
550 .get = onyx_spdif_get,
551 .put = onyx_spdif_put,
552};
553
554/* our registers */
555
556static u8 register_map[] = {
557 ONYX_REG_DAC_ATTEN_LEFT,
558 ONYX_REG_DAC_ATTEN_RIGHT,
559 ONYX_REG_CONTROL,
560 ONYX_REG_DAC_CONTROL,
561 ONYX_REG_DAC_DEEMPH,
562 ONYX_REG_DAC_FILTER,
563 ONYX_REG_DAC_OUTPHASE,
564 ONYX_REG_ADC_CONTROL,
565 ONYX_REG_ADC_HPF_BYPASS,
566 ONYX_REG_DIG_INFO1,
567 ONYX_REG_DIG_INFO2,
568 ONYX_REG_DIG_INFO3,
569 ONYX_REG_DIG_INFO4
570};
571
572static u8 initial_values[ARRAY_SIZE(register_map)] = {
573 0x80, 0x80, /* muted */
574 ONYX_MRST | ONYX_SRST, /* but handled specially! */
575 ONYX_MUTE_LEFT | ONYX_MUTE_RIGHT,
576 0, /* no deemphasis */
577 ONYX_DAC_FILTER_ALWAYS,
578 ONYX_OUTPHASE_INVERTED,
579 (-1 /*dB*/ + 8) & 0xF, /* line in selected, -1 dB gain*/
580 ONYX_ADC_HPF_ALWAYS,
581 (1<<2), /* pcm audio */
582 2, /* category: pcm coder */
583 0, /* sampling frequency 44.1 kHz, clock accuracy level II */
584 1 /* 24 bit depth */
585};
586
587/* reset registers of chip, either to initial or to previous values */
588static int onyx_register_init(struct onyx *onyx)
589{
590 int i;
591 u8 val;
592 u8 regs[sizeof(initial_values)];
593
594 if (!onyx->initialised) {
595 memcpy(regs, initial_values, sizeof(initial_values));
596 if (onyx_read_register(onyx, ONYX_REG_CONTROL, &val))
597 return -1;
598 val &= ~ONYX_SILICONVERSION;
599 val |= initial_values[3];
600 regs[3] = val;
601 } else {
602 for (i=0; i<sizeof(register_map); i++)
603 regs[i] = onyx->cache[register_map[i]-FIRSTREGISTER];
604 }
605
606 for (i=0; i<sizeof(register_map); i++) {
607 if (onyx_write_register(onyx, register_map[i], regs[i]))
608 return -1;
609 }
610 onyx->initialised = 1;
611 return 0;
612}
613
614static struct transfer_info onyx_transfers[] = {
615 /* this is first so we can skip it if no input is present...
616 * No hardware exists with that, but it's here as an example
617 * of what to do :) */
618 {
619 /* analog input */
620 .formats = SNDRV_PCM_FMTBIT_S8 |
621 SNDRV_PCM_FMTBIT_S16_BE |
622 SNDRV_PCM_FMTBIT_S24_BE,
623 .rates = SNDRV_PCM_RATE_8000_96000,
624 .transfer_in = 1,
625 .must_be_clock_source = 0,
626 .tag = 0,
627 },
628 {
629 /* if analog and digital are currently off, anything should go,
630 * so this entry describes everything we can do... */
631 .formats = SNDRV_PCM_FMTBIT_S8 |
632 SNDRV_PCM_FMTBIT_S16_BE |
633 SNDRV_PCM_FMTBIT_S24_BE
634#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
635 | SNDRV_PCM_FMTBIT_COMPRESSED_16BE
636#endif
637 ,
638 .rates = SNDRV_PCM_RATE_8000_96000,
639 .tag = 0,
640 },
641 {
642 /* analog output */
643 .formats = SNDRV_PCM_FMTBIT_S8 |
644 SNDRV_PCM_FMTBIT_S16_BE |
645 SNDRV_PCM_FMTBIT_S24_BE,
646 .rates = SNDRV_PCM_RATE_8000_96000,
647 .transfer_in = 0,
648 .must_be_clock_source = 0,
649 .tag = 1,
650 },
651 {
652 /* digital pcm output, also possible for analog out */
653 .formats = SNDRV_PCM_FMTBIT_S8 |
654 SNDRV_PCM_FMTBIT_S16_BE |
655 SNDRV_PCM_FMTBIT_S24_BE,
656 .rates = SNDRV_PCM_RATE_32000 |
657 SNDRV_PCM_RATE_44100 |
658 SNDRV_PCM_RATE_48000,
659 .transfer_in = 0,
660 .must_be_clock_source = 0,
661 .tag = 2,
662 },
663#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
664Once alsa gets supports for this kind of thing we can add it...
665 {
666 /* digital compressed output */
667 .formats = SNDRV_PCM_FMTBIT_COMPRESSED_16BE,
668 .rates = SNDRV_PCM_RATE_32000 |
669 SNDRV_PCM_RATE_44100 |
670 SNDRV_PCM_RATE_48000,
671 .tag = 2,
672 },
673#endif
674 {}
675};
676
677static int onyx_usable(struct codec_info_item *cii,
678 struct transfer_info *ti,
679 struct transfer_info *out)
680{
681 u8 v;
682 struct onyx *onyx = cii->codec_data;
683 int spdif_enabled, analog_enabled;
684
685 mutex_lock(&onyx->mutex);
686 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
687 spdif_enabled = !!(v & ONYX_SPDIF_ENABLE);
688 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
689 analog_enabled =
690 (v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT))
691 != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT);
692 mutex_unlock(&onyx->mutex);
693
694 switch (ti->tag) {
695 case 0: return 1;
696 case 1: return analog_enabled;
697 case 2: return spdif_enabled;
698 }
699 return 1;
700}
701
702static int onyx_prepare(struct codec_info_item *cii,
703 struct bus_info *bi,
704 struct snd_pcm_substream *substream)
705{
706 u8 v;
707 struct onyx *onyx = cii->codec_data;
708 int err = -EBUSY;
709
710 mutex_lock(&onyx->mutex);
711
712#ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE
713 if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) {
714 /* mute and lock analog output */
715 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
716 if (onyx_write_register(onyx
717 ONYX_REG_DAC_CONTROL,
718 v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT))
719 goto out_unlock;
720 onyx->analog_locked = 1;
721 err = 0;
722 goto out_unlock;
723 }
724#endif
725 switch (substream->runtime->rate) {
726 case 32000:
727 case 44100:
728 case 48000:
729 /* these rates are ok for all outputs */
730 /* FIXME: program spdif channel control bits here so that
731 * userspace doesn't have to if it only plays pcm! */
732 err = 0;
733 goto out_unlock;
734 default:
735 /* got some rate that the digital output can't do,
736 * so disable and lock it */
737 onyx_read_register(cii->codec_data, ONYX_REG_DIG_INFO4, &v);
738 if (onyx_write_register(onyx,
739 ONYX_REG_DIG_INFO4,
740 v & ~ONYX_SPDIF_ENABLE))
741 goto out_unlock;
742 onyx->spdif_locked = 1;
743 err = 0;
744 goto out_unlock;
745 }
746
747 out_unlock:
748 mutex_unlock(&onyx->mutex);
749
750 return err;
751}
752
753static int onyx_open(struct codec_info_item *cii,
754 struct snd_pcm_substream *substream)
755{
756 struct onyx *onyx = cii->codec_data;
757
758 mutex_lock(&onyx->mutex);
759 onyx->open_count++;
760 mutex_unlock(&onyx->mutex);
761
762 return 0;
763}
764
765static int onyx_close(struct codec_info_item *cii,
766 struct snd_pcm_substream *substream)
767{
768 struct onyx *onyx = cii->codec_data;
769
770 mutex_lock(&onyx->mutex);
771 onyx->open_count--;
772 if (!onyx->open_count)
773 onyx->spdif_locked = onyx->analog_locked = 0;
774 mutex_unlock(&onyx->mutex);
775
776 return 0;
777}
778
779static int onyx_switch_clock(struct codec_info_item *cii,
780 enum clock_switch what)
781{
782 struct onyx *onyx = cii->codec_data;
783
784 mutex_lock(&onyx->mutex);
785 /* this *MUST* be more elaborate later... */
786 switch (what) {
787 case CLOCK_SWITCH_PREPARE_SLAVE:
788 onyx->codec.gpio->methods->all_amps_off(onyx->codec.gpio);
789 break;
790 case CLOCK_SWITCH_SLAVE:
791 onyx->codec.gpio->methods->all_amps_restore(onyx->codec.gpio);
792 break;
793 default: /* silence warning */
794 break;
795 }
796 mutex_unlock(&onyx->mutex);
797
798 return 0;
799}
800
801#ifdef CONFIG_PM
802
803static int onyx_suspend(struct codec_info_item *cii, pm_message_t state)
804{
805 struct onyx *onyx = cii->codec_data;
806 u8 v;
807 int err = -ENXIO;
808
809 mutex_lock(&onyx->mutex);
810 if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
811 goto out_unlock;
812 onyx_write_register(onyx, ONYX_REG_CONTROL, v | ONYX_ADPSV | ONYX_DAPSV);
813 /* Apple does a sleep here but the datasheet says to do it on resume */
814 err = 0;
815 out_unlock:
816 mutex_unlock(&onyx->mutex);
817
818 return err;
819}
820
821static int onyx_resume(struct codec_info_item *cii)
822{
823 struct onyx *onyx = cii->codec_data;
824 u8 v;
825 int err = -ENXIO;
826
827 mutex_lock(&onyx->mutex);
828 /* take codec out of suspend */
829 if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v))
830 goto out_unlock;
831 onyx_write_register(onyx, ONYX_REG_CONTROL, v & ~(ONYX_ADPSV | ONYX_DAPSV));
832 /* FIXME: should divide by sample rate, but 8k is the lowest we go */
833 msleep(2205000/8000);
834 /* reset all values */
835 onyx_register_init(onyx);
836 err = 0;
837 out_unlock:
838 mutex_unlock(&onyx->mutex);
839
840 return err;
841}
842
843#endif /* CONFIG_PM */
844
845static struct codec_info onyx_codec_info = {
846 .transfers = onyx_transfers,
847 .sysclock_factor = 256,
848 .bus_factor = 64,
849 .owner = THIS_MODULE,
850 .usable = onyx_usable,
851 .prepare = onyx_prepare,
852 .open = onyx_open,
853 .close = onyx_close,
854 .switch_clock = onyx_switch_clock,
855#ifdef CONFIG_PM
856 .suspend = onyx_suspend,
857 .resume = onyx_resume,
858#endif
859};
860
861static int onyx_init_codec(struct aoa_codec *codec)
862{
863 struct onyx *onyx = codec_to_onyx(codec);
864 struct snd_kcontrol *ctl;
865 struct codec_info *ci = &onyx_codec_info;
866 u8 v;
867 int err;
868
869 if (!onyx->codec.gpio || !onyx->codec.gpio->methods) {
870 printk(KERN_ERR PFX "gpios not assigned!!\n");
871 return -EINVAL;
872 }
873
874 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
875 msleep(1);
876 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1);
877 msleep(1);
878 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
879 msleep(1);
880
881 if (onyx_register_init(onyx)) {
882 printk(KERN_ERR PFX "failed to initialise onyx registers\n");
883 return -ENODEV;
884 }
885
886 if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, onyx, &ops)) {
887 printk(KERN_ERR PFX "failed to create onyx snd device!\n");
888 return -ENODEV;
889 }
890
891 /* nothing connected? what a joke! */
892 if ((onyx->codec.connected & 0xF) == 0)
893 return -ENOTCONN;
894
895 /* if no inputs are present... */
896 if ((onyx->codec.connected & 0xC) == 0) {
897 if (!onyx->codec_info)
898 onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
899 if (!onyx->codec_info)
900 return -ENOMEM;
901 ci = onyx->codec_info;
902 *ci = onyx_codec_info;
903 ci->transfers++;
904 }
905
906 /* if no outputs are present... */
907 if ((onyx->codec.connected & 3) == 0) {
908 if (!onyx->codec_info)
909 onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL);
910 if (!onyx->codec_info)
911 return -ENOMEM;
912 ci = onyx->codec_info;
913 /* this is fine as there have to be inputs
914 * if we end up in this part of the code */
915 *ci = onyx_codec_info;
916 ci->transfers[1].formats = 0;
917 }
918
919 if (onyx->codec.soundbus_dev->attach_codec(onyx->codec.soundbus_dev,
920 aoa_get_card(),
921 ci, onyx)) {
922 printk(KERN_ERR PFX "error creating onyx pcm\n");
923 return -ENODEV;
924 }
925#define ADDCTL(n) \
926 do { \
927 ctl = snd_ctl_new1(&n, onyx); \
928 if (ctl) { \
929 ctl->id.device = \
930 onyx->codec.soundbus_dev->pcm->device; \
931 err = aoa_snd_ctl_add(ctl); \
932 if (err) \
933 goto error; \
934 } \
935 } while (0)
936
937 if (onyx->codec.soundbus_dev->pcm) {
938 /* give the user appropriate controls
939 * depending on what inputs are connected */
940 if ((onyx->codec.connected & 0xC) == 0xC)
941 ADDCTL(capture_source_control);
942 else if (onyx->codec.connected & 4)
943 onyx_set_capture_source(onyx, 0);
944 else
945 onyx_set_capture_source(onyx, 1);
946 if (onyx->codec.connected & 0xC)
947 ADDCTL(inputgain_control);
948
949 /* depending on what output is connected,
950 * give the user appropriate controls */
951 if (onyx->codec.connected & 1) {
952 ADDCTL(volume_control);
953 ADDCTL(mute_control);
954 ADDCTL(ovr1_control);
955 ADDCTL(flt0_control);
956 ADDCTL(hpf_control);
957 ADDCTL(dm12_control);
958 /* spdif control defaults to off */
959 }
960 if (onyx->codec.connected & 2) {
961 ADDCTL(onyx_spdif_mask);
962 ADDCTL(onyx_spdif_ctrl);
963 }
964 if ((onyx->codec.connected & 3) == 3)
965 ADDCTL(spdif_control);
966 /* if only S/PDIF is connected, enable it unconditionally */
967 if ((onyx->codec.connected & 3) == 2) {
968 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
969 v |= ONYX_SPDIF_ENABLE;
970 onyx_write_register(onyx, ONYX_REG_DIG_INFO4, v);
971 }
972 }
973#undef ADDCTL
974 printk(KERN_INFO PFX "attached to onyx codec via i2c\n");
975
976 return 0;
977 error:
978 onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
979 snd_device_free(aoa_get_card(), onyx);
980 return err;
981}
982
983static void onyx_exit_codec(struct aoa_codec *codec)
984{
985 struct onyx *onyx = codec_to_onyx(codec);
986
987 if (!onyx->codec.soundbus_dev) {
988 printk(KERN_ERR PFX "onyx_exit_codec called without soundbus_dev!\n");
989 return;
990 }
991 onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
992}
993
994static struct i2c_driver onyx_driver;
995
996static int onyx_create(struct i2c_adapter *adapter,
997 struct device_node *node,
998 int addr)
999{
1000 struct onyx *onyx;
1001 u8 dummy;
1002
1003 onyx = kzalloc(sizeof(struct onyx), GFP_KERNEL);
1004
1005 if (!onyx)
1006 return -ENOMEM;
1007
1008 mutex_init(&onyx->mutex);
1009 onyx->i2c.driver = &onyx_driver;
1010 onyx->i2c.adapter = adapter;
1011 onyx->i2c.addr = addr & 0x7f;
1012 strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE-1);
1013
1014 if (i2c_attach_client(&onyx->i2c)) {
1015 printk(KERN_ERR PFX "failed to attach to i2c\n");
1016 goto fail;
1017 }
1018
1019 /* we try to read from register ONYX_REG_CONTROL
1020 * to check if the codec is present */
1021 if (onyx_read_register(onyx, ONYX_REG_CONTROL, &dummy) != 0) {
1022 i2c_detach_client(&onyx->i2c);
1023 printk(KERN_ERR PFX "failed to read control register\n");
1024 goto fail;
1025 }
1026
1027 strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN-1);
1028 onyx->codec.owner = THIS_MODULE;
1029 onyx->codec.init = onyx_init_codec;
1030 onyx->codec.exit = onyx_exit_codec;
1031 onyx->codec.node = of_node_get(node);
1032
1033 if (aoa_codec_register(&onyx->codec)) {
1034 i2c_detach_client(&onyx->i2c);
1035 goto fail;
1036 }
1037 printk(KERN_DEBUG PFX "created and attached onyx instance\n");
1038 return 0;
1039 fail:
1040 kfree(onyx);
1041 return -EINVAL;
1042}
1043
1044static int onyx_i2c_attach(struct i2c_adapter *adapter)
1045{
1046 struct device_node *busnode, *dev = NULL;
1047 struct pmac_i2c_bus *bus;
1048
1049 bus = pmac_i2c_adapter_to_bus(adapter);
1050 if (bus == NULL)
1051 return -ENODEV;
1052 busnode = pmac_i2c_get_bus_node(bus);
1053
1054 while ((dev = of_get_next_child(busnode, dev)) != NULL) {
1055 if (device_is_compatible(dev, "pcm3052")) {
1056 u32 *addr;
1057 printk(KERN_DEBUG PFX "found pcm3052\n");
1058 addr = (u32 *) get_property(dev, "reg", NULL);
1059 if (!addr)
1060 return -ENODEV;
1061 return onyx_create(adapter, dev, (*addr)>>1);
1062 }
1063 }
1064
1065 /* if that didn't work, try desperate mode for older
1066 * machines that have stuff missing from the device tree */
1067
1068 if (!device_is_compatible(busnode, "k2-i2c"))
1069 return -ENODEV;
1070
1071 printk(KERN_DEBUG PFX "found k2-i2c, checking if onyx chip is on it\n");
1072 /* probe both possible addresses for the onyx chip */
1073 if (onyx_create(adapter, NULL, 0x46) == 0)
1074 return 0;
1075 return onyx_create(adapter, NULL, 0x47);
1076}
1077
1078static int onyx_i2c_detach(struct i2c_client *client)
1079{
1080 struct onyx *onyx = container_of(client, struct onyx, i2c);
1081 int err;
1082
1083 if ((err = i2c_detach_client(client)))
1084 return err;
1085 aoa_codec_unregister(&onyx->codec);
1086 of_node_put(onyx->codec.node);
1087 if (onyx->codec_info)
1088 kfree(onyx->codec_info);
1089 kfree(onyx);
1090 return 0;
1091}
1092
1093static struct i2c_driver onyx_driver = {
1094 .driver = {
1095 .name = "aoa_codec_onyx",
1096 .owner = THIS_MODULE,
1097 },
1098 .attach_adapter = onyx_i2c_attach,
1099 .detach_client = onyx_i2c_detach,
1100};
1101
1102static int __init onyx_init(void)
1103{
1104 return i2c_add_driver(&onyx_driver);
1105}
1106
1107static void __exit onyx_exit(void)
1108{
1109 i2c_del_driver(&onyx_driver);
1110}
1111
1112module_init(onyx_init);
1113module_exit(onyx_exit);
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.h b/sound/aoa/codecs/snd-aoa-codec-onyx.h
new file mode 100644
index 000000000000..aeedda773699
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-onyx.h
@@ -0,0 +1,76 @@
1/*
2 * Apple Onboard Audio driver for Onyx codec (header)
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#ifndef __SND_AOA_CODEC_ONYX_H
9#define __SND_AOA_CODEC_ONYX_H
10#include <stddef.h>
11#include <linux/i2c.h>
12#include <linux/i2c-dev.h>
13#include <asm/pmac_low_i2c.h>
14#include <asm/prom.h>
15
16/* PCM3052 register definitions */
17
18/* the attenuation registers take values from
19 * -1 (0dB) to -127 (-63.0 dB) or others (muted) */
20#define ONYX_REG_DAC_ATTEN_LEFT 65
21#define FIRSTREGISTER ONYX_REG_DAC_ATTEN_LEFT
22#define ONYX_REG_DAC_ATTEN_RIGHT 66
23
24#define ONYX_REG_CONTROL 67
25# define ONYX_MRST (1<<7)
26# define ONYX_SRST (1<<6)
27# define ONYX_ADPSV (1<<5)
28# define ONYX_DAPSV (1<<4)
29# define ONYX_SILICONVERSION (1<<0)
30/* all others reserved */
31
32#define ONYX_REG_DAC_CONTROL 68
33# define ONYX_OVR1 (1<<6)
34# define ONYX_MUTE_RIGHT (1<<1)
35# define ONYX_MUTE_LEFT (1<<0)
36
37#define ONYX_REG_DAC_DEEMPH 69
38# define ONYX_DIGDEEMPH_SHIFT 5
39# define ONYX_DIGDEEMPH_MASK (3<<ONYX_DIGDEEMPH_SHIFT)
40# define ONYX_DIGDEEMPH_CTRL (1<<4)
41
42#define ONYX_REG_DAC_FILTER 70
43# define ONYX_ROLLOFF_FAST (1<<5)
44# define ONYX_DAC_FILTER_ALWAYS (1<<2)
45
46#define ONYX_REG_DAC_OUTPHASE 71
47# define ONYX_OUTPHASE_INVERTED (1<<0)
48
49#define ONYX_REG_ADC_CONTROL 72
50# define ONYX_ADC_INPUT_MIC (1<<5)
51/* 8 + input gain in dB, valid range for input gain is -4 .. 20 dB */
52# define ONYX_ADC_PGA_GAIN_MASK 0x1f
53
54#define ONYX_REG_ADC_HPF_BYPASS 75
55# define ONYX_HPF_DISABLE (1<<3)
56# define ONYX_ADC_HPF_ALWAYS (1<<2)
57
58#define ONYX_REG_DIG_INFO1 77
59# define ONYX_MASK_DIN_TO_BPZ (1<<7)
60/* bits 1-5 control channel bits 1-5 */
61# define ONYX_DIGOUT_DISABLE (1<<0)
62
63#define ONYX_REG_DIG_INFO2 78
64/* controls channel bits 8-15 */
65
66#define ONYX_REG_DIG_INFO3 79
67/* control channel bits 24-29, high 2 bits reserved */
68
69#define ONYX_REG_DIG_INFO4 80
70# define ONYX_VALIDL (1<<7)
71# define ONYX_VALIDR (1<<6)
72# define ONYX_SPDIF_ENABLE (1<<5)
73/* lower 4 bits control bits 32-35 of channel control and word length */
74# define ONYX_WORDLEN_MASK (0xF)
75
76#endif /* __SND_AOA_CODEC_ONYX_H */
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h b/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h
new file mode 100644
index 000000000000..4cfa6757715e
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h
@@ -0,0 +1,209 @@
1/*
2 This is the program used to generate below table.
3
4#include <stdio.h>
5#include <math.h>
6int main() {
7 int dB2;
8 printf("/" "* This file is only included exactly once!\n");
9 printf(" *\n");
10 printf(" * If they'd only tell us that generating this table was\n");
11 printf(" * as easy as calculating\n");
12 printf(" * hwvalue = 1048576.0*exp(0.057564628*dB*2)\n");
13 printf(" * :) *" "/\n");
14 printf("static int tas_gaintable[] = {\n");
15 printf(" 0x000000, /" "* -infinity dB *" "/\n");
16 for (dB2=-140;dB2<=36;dB2++)
17 printf(" 0x%.6x, /" "* %-02.1f dB *" "/\n", (int)(1048576.0*exp(0.057564628*dB2)), dB2/2.0);
18 printf("};\n\n");
19}
20
21*/
22
23/* This file is only included exactly once!
24 *
25 * If they'd only tell us that generating this table was
26 * as easy as calculating
27 * hwvalue = 1048576.0*exp(0.057564628*dB*2)
28 * :) */
29static int tas_gaintable[] = {
30 0x000000, /* -infinity dB */
31 0x00014b, /* -70.0 dB */
32 0x00015f, /* -69.5 dB */
33 0x000174, /* -69.0 dB */
34 0x00018a, /* -68.5 dB */
35 0x0001a1, /* -68.0 dB */
36 0x0001ba, /* -67.5 dB */
37 0x0001d4, /* -67.0 dB */
38 0x0001f0, /* -66.5 dB */
39 0x00020d, /* -66.0 dB */
40 0x00022c, /* -65.5 dB */
41 0x00024d, /* -65.0 dB */
42 0x000270, /* -64.5 dB */
43 0x000295, /* -64.0 dB */
44 0x0002bc, /* -63.5 dB */
45 0x0002e6, /* -63.0 dB */
46 0x000312, /* -62.5 dB */
47 0x000340, /* -62.0 dB */
48 0x000372, /* -61.5 dB */
49 0x0003a6, /* -61.0 dB */
50 0x0003dd, /* -60.5 dB */
51 0x000418, /* -60.0 dB */
52 0x000456, /* -59.5 dB */
53 0x000498, /* -59.0 dB */
54 0x0004de, /* -58.5 dB */
55 0x000528, /* -58.0 dB */
56 0x000576, /* -57.5 dB */
57 0x0005c9, /* -57.0 dB */
58 0x000620, /* -56.5 dB */
59 0x00067d, /* -56.0 dB */
60 0x0006e0, /* -55.5 dB */
61 0x000748, /* -55.0 dB */
62 0x0007b7, /* -54.5 dB */
63 0x00082c, /* -54.0 dB */
64 0x0008a8, /* -53.5 dB */
65 0x00092b, /* -53.0 dB */
66 0x0009b6, /* -52.5 dB */
67 0x000a49, /* -52.0 dB */
68 0x000ae5, /* -51.5 dB */
69 0x000b8b, /* -51.0 dB */
70 0x000c3a, /* -50.5 dB */
71 0x000cf3, /* -50.0 dB */
72 0x000db8, /* -49.5 dB */
73 0x000e88, /* -49.0 dB */
74 0x000f64, /* -48.5 dB */
75 0x00104e, /* -48.0 dB */
76 0x001145, /* -47.5 dB */
77 0x00124b, /* -47.0 dB */
78 0x001361, /* -46.5 dB */
79 0x001487, /* -46.0 dB */
80 0x0015be, /* -45.5 dB */
81 0x001708, /* -45.0 dB */
82 0x001865, /* -44.5 dB */
83 0x0019d8, /* -44.0 dB */
84 0x001b60, /* -43.5 dB */
85 0x001cff, /* -43.0 dB */
86 0x001eb7, /* -42.5 dB */
87 0x002089, /* -42.0 dB */
88 0x002276, /* -41.5 dB */
89 0x002481, /* -41.0 dB */
90 0x0026ab, /* -40.5 dB */
91 0x0028f5, /* -40.0 dB */
92 0x002b63, /* -39.5 dB */
93 0x002df5, /* -39.0 dB */
94 0x0030ae, /* -38.5 dB */
95 0x003390, /* -38.0 dB */
96 0x00369e, /* -37.5 dB */
97 0x0039db, /* -37.0 dB */
98 0x003d49, /* -36.5 dB */
99 0x0040ea, /* -36.0 dB */
100 0x0044c3, /* -35.5 dB */
101 0x0048d6, /* -35.0 dB */
102 0x004d27, /* -34.5 dB */
103 0x0051b9, /* -34.0 dB */
104 0x005691, /* -33.5 dB */
105 0x005bb2, /* -33.0 dB */
106 0x006121, /* -32.5 dB */
107 0x0066e3, /* -32.0 dB */
108 0x006cfb, /* -31.5 dB */
109 0x007370, /* -31.0 dB */
110 0x007a48, /* -30.5 dB */
111 0x008186, /* -30.0 dB */
112 0x008933, /* -29.5 dB */
113 0x009154, /* -29.0 dB */
114 0x0099f1, /* -28.5 dB */
115 0x00a310, /* -28.0 dB */
116 0x00acba, /* -27.5 dB */
117 0x00b6f6, /* -27.0 dB */
118 0x00c1cd, /* -26.5 dB */
119 0x00cd49, /* -26.0 dB */
120 0x00d973, /* -25.5 dB */
121 0x00e655, /* -25.0 dB */
122 0x00f3fb, /* -24.5 dB */
123 0x010270, /* -24.0 dB */
124 0x0111c0, /* -23.5 dB */
125 0x0121f9, /* -23.0 dB */
126 0x013328, /* -22.5 dB */
127 0x01455b, /* -22.0 dB */
128 0x0158a2, /* -21.5 dB */
129 0x016d0e, /* -21.0 dB */
130 0x0182af, /* -20.5 dB */
131 0x019999, /* -20.0 dB */
132 0x01b1de, /* -19.5 dB */
133 0x01cb94, /* -19.0 dB */
134 0x01e6cf, /* -18.5 dB */
135 0x0203a7, /* -18.0 dB */
136 0x022235, /* -17.5 dB */
137 0x024293, /* -17.0 dB */
138 0x0264db, /* -16.5 dB */
139 0x02892c, /* -16.0 dB */
140 0x02afa3, /* -15.5 dB */
141 0x02d862, /* -15.0 dB */
142 0x03038a, /* -14.5 dB */
143 0x033142, /* -14.0 dB */
144 0x0361af, /* -13.5 dB */
145 0x0394fa, /* -13.0 dB */
146 0x03cb50, /* -12.5 dB */
147 0x0404de, /* -12.0 dB */
148 0x0441d5, /* -11.5 dB */
149 0x048268, /* -11.0 dB */
150 0x04c6d0, /* -10.5 dB */
151 0x050f44, /* -10.0 dB */
152 0x055c04, /* -9.5 dB */
153 0x05ad50, /* -9.0 dB */
154 0x06036e, /* -8.5 dB */
155 0x065ea5, /* -8.0 dB */
156 0x06bf44, /* -7.5 dB */
157 0x07259d, /* -7.0 dB */
158 0x079207, /* -6.5 dB */
159 0x0804dc, /* -6.0 dB */
160 0x087e80, /* -5.5 dB */
161 0x08ff59, /* -5.0 dB */
162 0x0987d5, /* -4.5 dB */
163 0x0a1866, /* -4.0 dB */
164 0x0ab189, /* -3.5 dB */
165 0x0b53be, /* -3.0 dB */
166 0x0bff91, /* -2.5 dB */
167 0x0cb591, /* -2.0 dB */
168 0x0d765a, /* -1.5 dB */
169 0x0e4290, /* -1.0 dB */
170 0x0f1adf, /* -0.5 dB */
171 0x100000, /* 0.0 dB */
172 0x10f2b4, /* 0.5 dB */
173 0x11f3c9, /* 1.0 dB */
174 0x13041a, /* 1.5 dB */
175 0x14248e, /* 2.0 dB */
176 0x15561a, /* 2.5 dB */
177 0x1699c0, /* 3.0 dB */
178 0x17f094, /* 3.5 dB */
179 0x195bb8, /* 4.0 dB */
180 0x1adc61, /* 4.5 dB */
181 0x1c73d5, /* 5.0 dB */
182 0x1e236d, /* 5.5 dB */
183 0x1fec98, /* 6.0 dB */
184 0x21d0d9, /* 6.5 dB */
185 0x23d1cd, /* 7.0 dB */
186 0x25f125, /* 7.5 dB */
187 0x2830af, /* 8.0 dB */
188 0x2a9254, /* 8.5 dB */
189 0x2d1818, /* 9.0 dB */
190 0x2fc420, /* 9.5 dB */
191 0x3298b0, /* 10.0 dB */
192 0x35982f, /* 10.5 dB */
193 0x38c528, /* 11.0 dB */
194 0x3c224c, /* 11.5 dB */
195 0x3fb278, /* 12.0 dB */
196 0x4378b0, /* 12.5 dB */
197 0x477829, /* 13.0 dB */
198 0x4bb446, /* 13.5 dB */
199 0x5030a1, /* 14.0 dB */
200 0x54f106, /* 14.5 dB */
201 0x59f980, /* 15.0 dB */
202 0x5f4e52, /* 15.5 dB */
203 0x64f403, /* 16.0 dB */
204 0x6aef5e, /* 16.5 dB */
205 0x714575, /* 17.0 dB */
206 0x77fbaa, /* 17.5 dB */
207 0x7f17af, /* 18.0 dB */
208};
209
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c
new file mode 100644
index 000000000000..2e39ff6ee349
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.c
@@ -0,0 +1,654 @@
1/*
2 * Apple Onboard Audio driver for tas codec
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 *
8 * Open questions:
9 * - How to distinguish between 3004 and versions?
10 *
11 * FIXMEs:
12 * - This codec driver doesn't honour the 'connected'
13 * property of the aoa_codec struct, hence if
14 * it is used in machines where not everything is
15 * connected it will display wrong mixer elements.
16 * - Driver assumes that the microphone is always
17 * monaureal and connected to the right channel of
18 * the input. This should also be a codec-dependent
19 * flag, maybe the codec should have 3 different
20 * bits for the three different possibilities how
21 * it can be hooked up...
22 * But as long as I don't see any hardware hooked
23 * up that way...
24 * - As Apple notes in their code, the tas3004 seems
25 * to delay the right channel by one sample. You can
26 * see this when for example recording stereo in
27 * audacity, or recording the tas output via cable
28 * on another machine (use a sinus generator or so).
29 * I tried programming the BiQuads but couldn't
30 * make the delay work, maybe someone can read the
31 * datasheet and fix it. The relevant Apple comment
32 * is in AppleTAS3004Audio.cpp lines 1637 ff. Note
33 * that their comment describing how they program
34 * the filters sucks...
35 *
36 * Other things:
37 * - this should actually register *two* aoa_codec
38 * structs since it has two inputs. Then it must
39 * use the prepare callback to forbid running the
40 * secondary output on a different clock.
41 * Also, whatever bus knows how to do this must
42 * provide two soundbus_dev devices and the fabric
43 * must be able to link them correctly.
44 *
45 * I don't even know if Apple ever uses the second
46 * port on the tas3004 though, I don't think their
47 * i2s controllers can even do it. OTOH, they all
48 * derive the clocks from common clocks, so it
49 * might just be possible. The framework allows the
50 * codec to refine the transfer_info items in the
51 * usable callback, so we can simply remove the
52 * rates the second instance is not using when it
53 * actually is in use.
54 * Maybe we'll need to make the sound busses have
55 * a 'clock group id' value so the codec can
56 * determine if the two outputs can be driven at
57 * the same time. But that is likely overkill, up
58 * to the fabric to not link them up incorrectly,
59 * and up to the hardware designer to not wire
60 * them up in some weird unusable way.
61 */
62#include <stddef.h>
63#include <linux/i2c.h>
64#include <linux/i2c-dev.h>
65#include <asm/pmac_low_i2c.h>
66#include <asm/prom.h>
67#include <linux/delay.h>
68#include <linux/module.h>
69MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
70MODULE_LICENSE("GPL");
71MODULE_DESCRIPTION("tas codec driver for snd-aoa");
72
73#include "snd-aoa-codec-tas.h"
74#include "snd-aoa-codec-tas-gain-table.h"
75#include "../aoa.h"
76#include "../soundbus/soundbus.h"
77
78
79#define PFX "snd-aoa-codec-tas: "
80
81struct tas {
82 struct aoa_codec codec;
83 struct i2c_client i2c;
84 u32 muted_l:1, muted_r:1,
85 controls_created:1;
86 u8 cached_volume_l, cached_volume_r;
87 u8 mixer_l[3], mixer_r[3];
88 u8 acr;
89};
90
91static struct tas *codec_to_tas(struct aoa_codec *codec)
92{
93 return container_of(codec, struct tas, codec);
94}
95
96static inline int tas_write_reg(struct tas *tas, u8 reg, u8 len, u8 *data)
97{
98 if (len == 1)
99 return i2c_smbus_write_byte_data(&tas->i2c, reg, *data);
100 else
101 return i2c_smbus_write_i2c_block_data(&tas->i2c, reg, len, data);
102}
103
104static void tas_set_volume(struct tas *tas)
105{
106 u8 block[6];
107 int tmp;
108 u8 left, right;
109
110 left = tas->cached_volume_l;
111 right = tas->cached_volume_r;
112
113 if (left > 177) left = 177;
114 if (right > 177) right = 177;
115
116 if (tas->muted_l) left = 0;
117 if (tas->muted_r) right = 0;
118
119 /* analysing the volume and mixer tables shows
120 * that they are similar enough when we shift
121 * the mixer table down by 4 bits. The error
122 * is miniscule, in just one item the error
123 * is 1, at a value of 0x07f17b (mixer table
124 * value is 0x07f17a) */
125 tmp = tas_gaintable[left];
126 block[0] = tmp>>20;
127 block[1] = tmp>>12;
128 block[2] = tmp>>4;
129 tmp = tas_gaintable[right];
130 block[3] = tmp>>20;
131 block[4] = tmp>>12;
132 block[5] = tmp>>4;
133 tas_write_reg(tas, TAS_REG_VOL, 6, block);
134}
135
136static void tas_set_mixer(struct tas *tas)
137{
138 u8 block[9];
139 int tmp, i;
140 u8 val;
141
142 for (i=0;i<3;i++) {
143 val = tas->mixer_l[i];
144 if (val > 177) val = 177;
145 tmp = tas_gaintable[val];
146 block[3*i+0] = tmp>>16;
147 block[3*i+1] = tmp>>8;
148 block[3*i+2] = tmp;
149 }
150 tas_write_reg(tas, TAS_REG_LMIX, 9, block);
151
152 for (i=0;i<3;i++) {
153 val = tas->mixer_r[i];
154 if (val > 177) val = 177;
155 tmp = tas_gaintable[val];
156 block[3*i+0] = tmp>>16;
157 block[3*i+1] = tmp>>8;
158 block[3*i+2] = tmp;
159 }
160 tas_write_reg(tas, TAS_REG_RMIX, 9, block);
161}
162
163/* alsa stuff */
164
165static int tas_dev_register(struct snd_device *dev)
166{
167 return 0;
168}
169
170static struct snd_device_ops ops = {
171 .dev_register = tas_dev_register,
172};
173
174static int tas_snd_vol_info(struct snd_kcontrol *kcontrol,
175 struct snd_ctl_elem_info *uinfo)
176{
177 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
178 uinfo->count = 2;
179 uinfo->value.integer.min = 0;
180 uinfo->value.integer.max = 177;
181 return 0;
182}
183
184static int tas_snd_vol_get(struct snd_kcontrol *kcontrol,
185 struct snd_ctl_elem_value *ucontrol)
186{
187 struct tas *tas = snd_kcontrol_chip(kcontrol);
188
189 ucontrol->value.integer.value[0] = tas->cached_volume_l;
190 ucontrol->value.integer.value[1] = tas->cached_volume_r;
191 return 0;
192}
193
194static int tas_snd_vol_put(struct snd_kcontrol *kcontrol,
195 struct snd_ctl_elem_value *ucontrol)
196{
197 struct tas *tas = snd_kcontrol_chip(kcontrol);
198
199 if (tas->cached_volume_l == ucontrol->value.integer.value[0]
200 && tas->cached_volume_r == ucontrol->value.integer.value[1])
201 return 0;
202
203 tas->cached_volume_l = ucontrol->value.integer.value[0];
204 tas->cached_volume_r = ucontrol->value.integer.value[1];
205 tas_set_volume(tas);
206 return 1;
207}
208
209static struct snd_kcontrol_new volume_control = {
210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
211 .name = "Master Playback Volume",
212 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
213 .info = tas_snd_vol_info,
214 .get = tas_snd_vol_get,
215 .put = tas_snd_vol_put,
216};
217
218static int tas_snd_mute_info(struct snd_kcontrol *kcontrol,
219 struct snd_ctl_elem_info *uinfo)
220{
221 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
222 uinfo->count = 2;
223 uinfo->value.integer.min = 0;
224 uinfo->value.integer.max = 1;
225 return 0;
226}
227
228static int tas_snd_mute_get(struct snd_kcontrol *kcontrol,
229 struct snd_ctl_elem_value *ucontrol)
230{
231 struct tas *tas = snd_kcontrol_chip(kcontrol);
232
233 ucontrol->value.integer.value[0] = !tas->muted_l;
234 ucontrol->value.integer.value[1] = !tas->muted_r;
235 return 0;
236}
237
238static int tas_snd_mute_put(struct snd_kcontrol *kcontrol,
239 struct snd_ctl_elem_value *ucontrol)
240{
241 struct tas *tas = snd_kcontrol_chip(kcontrol);
242
243 if (tas->muted_l == !ucontrol->value.integer.value[0]
244 && tas->muted_r == !ucontrol->value.integer.value[1])
245 return 0;
246
247 tas->muted_l = !ucontrol->value.integer.value[0];
248 tas->muted_r = !ucontrol->value.integer.value[1];
249 tas_set_volume(tas);
250 return 1;
251}
252
253static struct snd_kcontrol_new mute_control = {
254 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
255 .name = "Master Playback Switch",
256 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
257 .info = tas_snd_mute_info,
258 .get = tas_snd_mute_get,
259 .put = tas_snd_mute_put,
260};
261
262static int tas_snd_mixer_info(struct snd_kcontrol *kcontrol,
263 struct snd_ctl_elem_info *uinfo)
264{
265 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
266 uinfo->count = 2;
267 uinfo->value.integer.min = 0;
268 uinfo->value.integer.max = 177;
269 return 0;
270}
271
272static int tas_snd_mixer_get(struct snd_kcontrol *kcontrol,
273 struct snd_ctl_elem_value *ucontrol)
274{
275 struct tas *tas = snd_kcontrol_chip(kcontrol);
276 int idx = kcontrol->private_value;
277
278 ucontrol->value.integer.value[0] = tas->mixer_l[idx];
279 ucontrol->value.integer.value[1] = tas->mixer_r[idx];
280
281 return 0;
282}
283
284static int tas_snd_mixer_put(struct snd_kcontrol *kcontrol,
285 struct snd_ctl_elem_value *ucontrol)
286{
287 struct tas *tas = snd_kcontrol_chip(kcontrol);
288 int idx = kcontrol->private_value;
289
290 if (tas->mixer_l[idx] == ucontrol->value.integer.value[0]
291 && tas->mixer_r[idx] == ucontrol->value.integer.value[1])
292 return 0;
293
294 tas->mixer_l[idx] = ucontrol->value.integer.value[0];
295 tas->mixer_r[idx] = ucontrol->value.integer.value[1];
296
297 tas_set_mixer(tas);
298 return 1;
299}
300
301#define MIXER_CONTROL(n,descr,idx) \
302static struct snd_kcontrol_new n##_control = { \
303 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
304 .name = descr " Playback Volume", \
305 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
306 .info = tas_snd_mixer_info, \
307 .get = tas_snd_mixer_get, \
308 .put = tas_snd_mixer_put, \
309 .private_value = idx, \
310}
311
312MIXER_CONTROL(pcm1, "PCM1", 0);
313MIXER_CONTROL(monitor, "Monitor", 2);
314
315static int tas_snd_capture_source_info(struct snd_kcontrol *kcontrol,
316 struct snd_ctl_elem_info *uinfo)
317{
318 static char *texts[] = { "Line-In", "Microphone" };
319
320 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
321 uinfo->count = 1;
322 uinfo->value.enumerated.items = 2;
323 if (uinfo->value.enumerated.item > 1)
324 uinfo->value.enumerated.item = 1;
325 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
326 return 0;
327}
328
329static int tas_snd_capture_source_get(struct snd_kcontrol *kcontrol,
330 struct snd_ctl_elem_value *ucontrol)
331{
332 struct tas *tas = snd_kcontrol_chip(kcontrol);
333
334 ucontrol->value.enumerated.item[0] = !!(tas->acr & TAS_ACR_INPUT_B);
335 return 0;
336}
337
338static int tas_snd_capture_source_put(struct snd_kcontrol *kcontrol,
339 struct snd_ctl_elem_value *ucontrol)
340{
341 struct tas *tas = snd_kcontrol_chip(kcontrol);
342 int oldacr = tas->acr;
343
344 tas->acr &= ~TAS_ACR_INPUT_B;
345 if (ucontrol->value.enumerated.item[0])
346 tas->acr |= TAS_ACR_INPUT_B;
347 if (oldacr == tas->acr)
348 return 0;
349 tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
350 return 1;
351}
352
353static struct snd_kcontrol_new capture_source_control = {
354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
355 /* If we name this 'Input Source', it properly shows up in
356 * alsamixer as a selection, * but it's shown under the
357 * 'Playback' category.
358 * If I name it 'Capture Source', it shows up in strange
359 * ways (two bools of which one can be selected at a
360 * time) but at least it's shown in the 'Capture'
361 * category.
362 * I was told that this was due to backward compatibility,
363 * but I don't understand then why the mangling is *not*
364 * done when I name it "Input Source".....
365 */
366 .name = "Capture Source",
367 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
368 .info = tas_snd_capture_source_info,
369 .get = tas_snd_capture_source_get,
370 .put = tas_snd_capture_source_put,
371};
372
373
374static struct transfer_info tas_transfers[] = {
375 {
376 /* input */
377 .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_BE |
378 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE,
379 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
380 .transfer_in = 1,
381 },
382 {
383 /* output */
384 .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_BE |
385 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE,
386 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
387 .transfer_in = 0,
388 },
389 {}
390};
391
392static int tas_usable(struct codec_info_item *cii,
393 struct transfer_info *ti,
394 struct transfer_info *out)
395{
396 return 1;
397}
398
399static int tas_reset_init(struct tas *tas)
400{
401 u8 tmp;
402 tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
403 msleep(1);
404 tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 1);
405 msleep(1);
406 tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0);
407 msleep(1);
408
409 tas->acr &= ~TAS_ACR_ANALOG_PDOWN;
410 tas->acr |= TAS_ACR_B_MONAUREAL | TAS_ACR_B_MON_SEL_RIGHT;
411 if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr))
412 return -ENODEV;
413
414 tmp = TAS_MCS_SCLK64 | TAS_MCS_SPORT_MODE_I2S | TAS_MCS_SPORT_WL_24BIT;
415 if (tas_write_reg(tas, TAS_REG_MCS, 1, &tmp))
416 return -ENODEV;
417
418 tmp = 0;
419 if (tas_write_reg(tas, TAS_REG_MCS2, 1, &tmp))
420 return -ENODEV;
421
422 return 0;
423}
424
425/* we are controlled via i2c and assume that is always up
426 * If that wasn't the case, we'd have to suspend once
427 * our i2c device is suspended, and then take note of that! */
428static int tas_suspend(struct tas *tas)
429{
430 tas->acr |= TAS_ACR_ANALOG_PDOWN;
431 tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr);
432 return 0;
433}
434
435static int tas_resume(struct tas *tas)
436{
437 /* reset codec */
438 tas_reset_init(tas);
439 tas_set_volume(tas);
440 tas_set_mixer(tas);
441 return 0;
442}
443
444#ifdef CONFIG_PM
445static int _tas_suspend(struct codec_info_item *cii, pm_message_t state)
446{
447 return tas_suspend(cii->codec_data);
448}
449
450static int _tas_resume(struct codec_info_item *cii)
451{
452 return tas_resume(cii->codec_data);
453}
454#endif
455
456static struct codec_info tas_codec_info = {
457 .transfers = tas_transfers,
458 /* in theory, we can drive it at 512 too...
459 * but so far the framework doesn't allow
460 * for that and I don't see much point in it. */
461 .sysclock_factor = 256,
462 /* same here, could be 32 for just one 16 bit format */
463 .bus_factor = 64,
464 .owner = THIS_MODULE,
465 .usable = tas_usable,
466#ifdef CONFIG_PM
467 .suspend = _tas_suspend,
468 .resume = _tas_resume,
469#endif
470};
471
472static int tas_init_codec(struct aoa_codec *codec)
473{
474 struct tas *tas = codec_to_tas(codec);
475 int err;
476
477 if (!tas->codec.gpio || !tas->codec.gpio->methods) {
478 printk(KERN_ERR PFX "gpios not assigned!!\n");
479 return -EINVAL;
480 }
481
482 if (tas_reset_init(tas)) {
483 printk(KERN_ERR PFX "tas failed to initialise\n");
484 return -ENXIO;
485 }
486
487 if (tas->codec.soundbus_dev->attach_codec(tas->codec.soundbus_dev,
488 aoa_get_card(),
489 &tas_codec_info, tas)) {
490 printk(KERN_ERR PFX "error attaching tas to soundbus\n");
491 return -ENODEV;
492 }
493
494 if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, tas, &ops)) {
495 printk(KERN_ERR PFX "failed to create tas snd device!\n");
496 return -ENODEV;
497 }
498 err = aoa_snd_ctl_add(snd_ctl_new1(&volume_control, tas));
499 if (err)
500 goto error;
501
502 err = aoa_snd_ctl_add(snd_ctl_new1(&mute_control, tas));
503 if (err)
504 goto error;
505
506 err = aoa_snd_ctl_add(snd_ctl_new1(&pcm1_control, tas));
507 if (err)
508 goto error;
509
510 err = aoa_snd_ctl_add(snd_ctl_new1(&monitor_control, tas));
511 if (err)
512 goto error;
513
514 err = aoa_snd_ctl_add(snd_ctl_new1(&capture_source_control, tas));
515 if (err)
516 goto error;
517
518 return 0;
519 error:
520 tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas);
521 snd_device_free(aoa_get_card(), tas);
522 return err;
523}
524
525static void tas_exit_codec(struct aoa_codec *codec)
526{
527 struct tas *tas = codec_to_tas(codec);
528
529 if (!tas->codec.soundbus_dev)
530 return;
531 tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas);
532}
533
534
535static struct i2c_driver tas_driver;
536
537static int tas_create(struct i2c_adapter *adapter,
538 struct device_node *node,
539 int addr)
540{
541 struct tas *tas;
542
543 tas = kzalloc(sizeof(struct tas), GFP_KERNEL);
544
545 if (!tas)
546 return -ENOMEM;
547
548 tas->i2c.driver = &tas_driver;
549 tas->i2c.adapter = adapter;
550 tas->i2c.addr = addr;
551 strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1);
552
553 if (i2c_attach_client(&tas->i2c)) {
554 printk(KERN_ERR PFX "failed to attach to i2c\n");
555 goto fail;
556 }
557
558 strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN-1);
559 tas->codec.owner = THIS_MODULE;
560 tas->codec.init = tas_init_codec;
561 tas->codec.exit = tas_exit_codec;
562 tas->codec.node = of_node_get(node);
563
564 if (aoa_codec_register(&tas->codec)) {
565 goto detach;
566 }
567 printk(KERN_DEBUG "snd-aoa-codec-tas: created and attached tas instance\n");
568 return 0;
569 detach:
570 i2c_detach_client(&tas->i2c);
571 fail:
572 kfree(tas);
573 return -EINVAL;
574}
575
576static int tas_i2c_attach(struct i2c_adapter *adapter)
577{
578 struct device_node *busnode, *dev = NULL;
579 struct pmac_i2c_bus *bus;
580
581 bus = pmac_i2c_adapter_to_bus(adapter);
582 if (bus == NULL)
583 return -ENODEV;
584 busnode = pmac_i2c_get_bus_node(bus);
585
586 while ((dev = of_get_next_child(busnode, dev)) != NULL) {
587 if (device_is_compatible(dev, "tas3004")) {
588 u32 *addr;
589 printk(KERN_DEBUG PFX "found tas3004\n");
590 addr = (u32 *) get_property(dev, "reg", NULL);
591 if (!addr)
592 continue;
593 return tas_create(adapter, dev, ((*addr) >> 1) & 0x7f);
594 }
595 /* older machines have no 'codec' node with a 'compatible'
596 * property that says 'tas3004', they just have a 'deq'
597 * node without any such property... */
598 if (strcmp(dev->name, "deq") == 0) {
599 u32 *_addr, addr;
600 printk(KERN_DEBUG PFX "found 'deq' node\n");
601 _addr = (u32 *) get_property(dev, "i2c-address", NULL);
602 if (!_addr)
603 continue;
604 addr = ((*_addr) >> 1) & 0x7f;
605 /* now, if the address doesn't match any of the two
606 * that a tas3004 can have, we cannot handle this.
607 * I doubt it ever happens but hey. */
608 if (addr != 0x34 && addr != 0x35)
609 continue;
610 return tas_create(adapter, dev, addr);
611 }
612 }
613 return -ENODEV;
614}
615
616static int tas_i2c_detach(struct i2c_client *client)
617{
618 struct tas *tas = container_of(client, struct tas, i2c);
619 int err;
620 u8 tmp = TAS_ACR_ANALOG_PDOWN;
621
622 if ((err = i2c_detach_client(client)))
623 return err;
624 aoa_codec_unregister(&tas->codec);
625 of_node_put(tas->codec.node);
626
627 /* power down codec chip */
628 tas_write_reg(tas, TAS_REG_ACR, 1, &tmp);
629
630 kfree(tas);
631 return 0;
632}
633
634static struct i2c_driver tas_driver = {
635 .driver = {
636 .name = "aoa_codec_tas",
637 .owner = THIS_MODULE,
638 },
639 .attach_adapter = tas_i2c_attach,
640 .detach_client = tas_i2c_detach,
641};
642
643static int __init tas_init(void)
644{
645 return i2c_add_driver(&tas_driver);
646}
647
648static void __exit tas_exit(void)
649{
650 i2c_del_driver(&tas_driver);
651}
652
653module_init(tas_init);
654module_exit(tas_exit);
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.h b/sound/aoa/codecs/snd-aoa-codec-tas.h
new file mode 100644
index 000000000000..daf81f45d83a
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.h
@@ -0,0 +1,47 @@
1/*
2 * Apple Onboard Audio driver for tas codec (header)
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#ifndef __SND_AOA_CODECTASH
9#define __SND_AOA_CODECTASH
10
11#define TAS_REG_MCS 0x01 /* main control */
12# define TAS_MCS_FASTLOAD (1<<7)
13# define TAS_MCS_SCLK64 (1<<6)
14# define TAS_MCS_SPORT_MODE_MASK (3<<4)
15# define TAS_MCS_SPORT_MODE_I2S (2<<4)
16# define TAS_MCS_SPORT_MODE_RJ (1<<4)
17# define TAS_MCS_SPORT_MODE_LJ (0<<4)
18# define TAS_MCS_SPORT_WL_MASK (3<<0)
19# define TAS_MCS_SPORT_WL_16BIT (0<<0)
20# define TAS_MCS_SPORT_WL_18BIT (1<<0)
21# define TAS_MCS_SPORT_WL_20BIT (2<<0)
22# define TAS_MCS_SPORT_WL_24BIT (3<<0)
23
24#define TAS_REG_DRC 0x02
25#define TAS_REG_VOL 0x04
26#define TAS_REG_TREBLE 0x05
27#define TAS_REG_BASS 0x06
28#define TAS_REG_LMIX 0x07
29#define TAS_REG_RMIX 0x08
30
31#define TAS_REG_ACR 0x40 /* analog control */
32# define TAS_ACR_B_MONAUREAL (1<<7)
33# define TAS_ACR_B_MON_SEL_RIGHT (1<<6)
34# define TAS_ACR_DEEMPH_MASK (3<<2)
35# define TAS_ACR_DEEMPH_OFF (0<<2)
36# define TAS_ACR_DEEMPH_48KHz (1<<2)
37# define TAS_ACR_DEEMPH_44KHz (2<<2)
38# define TAS_ACR_INPUT_B (1<<1)
39# define TAS_ACR_ANALOG_PDOWN (1<<0)
40
41#define TAS_REG_MCS2 0x43 /* main control 2 */
42# define TAS_MCS2_ALLPASS (1<<1)
43
44#define TAS_REG_LEFT_BIQUAD6 0x10
45#define TAS_REG_RIGHT_BIQUAD6 0x19
46
47#endif /* __SND_AOA_CODECTASH */
diff --git a/sound/aoa/codecs/snd-aoa-codec-toonie.c b/sound/aoa/codecs/snd-aoa-codec-toonie.c
new file mode 100644
index 000000000000..bcc555647e79
--- /dev/null
+++ b/sound/aoa/codecs/snd-aoa-codec-toonie.c
@@ -0,0 +1,141 @@
1/*
2 * Apple Onboard Audio driver for Toonie codec
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 *
8 *
9 * This is a driver for the toonie codec chip. This chip is present
10 * on the Mac Mini and is nothing but a DAC.
11 */
12#include <linux/delay.h>
13#include <linux/module.h>
14MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
15MODULE_LICENSE("GPL");
16MODULE_DESCRIPTION("toonie codec driver for snd-aoa");
17
18#include "../aoa.h"
19#include "../soundbus/soundbus.h"
20
21
22#define PFX "snd-aoa-codec-toonie: "
23
24struct toonie {
25 struct aoa_codec codec;
26};
27#define codec_to_toonie(c) container_of(c, struct toonie, codec)
28
29static int toonie_dev_register(struct snd_device *dev)
30{
31 return 0;
32}
33
34static struct snd_device_ops ops = {
35 .dev_register = toonie_dev_register,
36};
37
38static struct transfer_info toonie_transfers[] = {
39 /* This thing *only* has analog output,
40 * the rates are taken from Info.plist
41 * from Darwin. */
42 {
43 .formats = SNDRV_PCM_FMTBIT_S16_BE |
44 SNDRV_PCM_FMTBIT_S24_BE,
45 .rates = SNDRV_PCM_RATE_32000 |
46 SNDRV_PCM_RATE_44100 |
47 SNDRV_PCM_RATE_48000 |
48 SNDRV_PCM_RATE_88200 |
49 SNDRV_PCM_RATE_96000,
50 },
51 {}
52};
53
54#ifdef CONFIG_PM
55static int toonie_suspend(struct codec_info_item *cii, pm_message_t state)
56{
57 /* can we turn it off somehow? */
58 return 0;
59}
60
61static int toonie_resume(struct codec_info_item *cii)
62{
63 return 0;
64}
65#endif /* CONFIG_PM */
66
67static struct codec_info toonie_codec_info = {
68 .transfers = toonie_transfers,
69 .sysclock_factor = 256,
70 .bus_factor = 64,
71 .owner = THIS_MODULE,
72#ifdef CONFIG_PM
73 .suspend = toonie_suspend,
74 .resume = toonie_resume,
75#endif
76};
77
78static int toonie_init_codec(struct aoa_codec *codec)
79{
80 struct toonie *toonie = codec_to_toonie(codec);
81
82 if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, toonie, &ops)) {
83 printk(KERN_ERR PFX "failed to create toonie snd device!\n");
84 return -ENODEV;
85 }
86
87 /* nothing connected? what a joke! */
88 if (toonie->codec.connected != 1)
89 return -ENOTCONN;
90
91 if (toonie->codec.soundbus_dev->attach_codec(toonie->codec.soundbus_dev,
92 aoa_get_card(),
93 &toonie_codec_info, toonie)) {
94 printk(KERN_ERR PFX "error creating toonie pcm\n");
95 return -ENODEV;
96 }
97
98 return 0;
99}
100
101static void toonie_exit_codec(struct aoa_codec *codec)
102{
103 struct toonie *toonie = codec_to_toonie(codec);
104
105 if (!toonie->codec.soundbus_dev) {
106 printk(KERN_ERR PFX "toonie_exit_codec called without soundbus_dev!\n");
107 return;
108 }
109 toonie->codec.soundbus_dev->detach_codec(toonie->codec.soundbus_dev, toonie);
110}
111
112static struct toonie *toonie;
113
114static int __init toonie_init(void)
115{
116 toonie = kzalloc(sizeof(struct toonie), GFP_KERNEL);
117
118 if (!toonie)
119 return -ENOMEM;
120
121 strlcpy(toonie->codec.name, "toonie", sizeof(toonie->codec.name));
122 toonie->codec.owner = THIS_MODULE;
123 toonie->codec.init = toonie_init_codec;
124 toonie->codec.exit = toonie_exit_codec;
125
126 if (aoa_codec_register(&toonie->codec)) {
127 kfree(toonie);
128 return -EINVAL;
129 }
130
131 return 0;
132}
133
134static void __exit toonie_exit(void)
135{
136 aoa_codec_unregister(&toonie->codec);
137 kfree(toonie);
138}
139
140module_init(toonie_init);
141module_exit(toonie_exit);
diff --git a/sound/aoa/core/Makefile b/sound/aoa/core/Makefile
new file mode 100644
index 000000000000..62dc7287f663
--- /dev/null
+++ b/sound/aoa/core/Makefile
@@ -0,0 +1,5 @@
1obj-$(CONFIG_SND_AOA) += snd-aoa.o
2snd-aoa-objs := snd-aoa-core.o \
3 snd-aoa-alsa.o \
4 snd-aoa-gpio-pmf.o \
5 snd-aoa-gpio-feature.o
diff --git a/sound/aoa/core/snd-aoa-alsa.c b/sound/aoa/core/snd-aoa-alsa.c
new file mode 100644
index 000000000000..b42fdea77ed0
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-alsa.c
@@ -0,0 +1,98 @@
1/*
2 * Apple Onboard Audio Alsa helpers
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#include <linux/module.h>
9#include "snd-aoa-alsa.h"
10
11static int index = -1;
12module_param(index, int, 0444);
13MODULE_PARM_DESC(index, "index for AOA sound card.");
14
15static struct aoa_card *aoa_card;
16
17int aoa_alsa_init(char *name, struct module *mod)
18{
19 struct snd_card *alsa_card;
20 int err;
21
22 if (aoa_card)
23 /* cannot be EEXIST due to usage in aoa_fabric_register */
24 return -EBUSY;
25
26 alsa_card = snd_card_new(index, name, mod, sizeof(struct aoa_card));
27 if (!alsa_card)
28 return -ENOMEM;
29 aoa_card = alsa_card->private_data;
30 aoa_card->alsa_card = alsa_card;
31 strlcpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
32 strlcpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
33 strlcpy(alsa_card->longname, name, sizeof(alsa_card->longname));
34 strlcpy(alsa_card->mixername, name, sizeof(alsa_card->mixername));
35 err = snd_card_register(aoa_card->alsa_card);
36 if (err < 0) {
37 printk(KERN_ERR "snd-aoa: couldn't register alsa card\n");
38 snd_card_free(aoa_card->alsa_card);
39 aoa_card = NULL;
40 return err;
41 }
42 return 0;
43}
44
45struct snd_card *aoa_get_card(void)
46{
47 if (aoa_card)
48 return aoa_card->alsa_card;
49 return NULL;
50}
51EXPORT_SYMBOL_GPL(aoa_get_card);
52
53void aoa_alsa_cleanup(void)
54{
55 if (aoa_card) {
56 snd_card_free(aoa_card->alsa_card);
57 aoa_card = NULL;
58 }
59}
60
61int aoa_snd_device_new(snd_device_type_t type,
62 void * device_data, struct snd_device_ops * ops)
63{
64 struct snd_card *card = aoa_get_card();
65 int err;
66
67 if (!card) return -ENOMEM;
68
69 err = snd_device_new(card, type, device_data, ops);
70 if (err) {
71 printk(KERN_ERR "snd-aoa: failed to create snd device (%d)\n", err);
72 return err;
73 }
74 err = snd_device_register(card, device_data);
75 if (err) {
76 printk(KERN_ERR "snd-aoa: failed to register "
77 "snd device (%d)\n", err);
78 printk(KERN_ERR "snd-aoa: have you forgotten the "
79 "dev_register callback?\n");
80 snd_device_free(card, device_data);
81 }
82 return err;
83}
84EXPORT_SYMBOL_GPL(aoa_snd_device_new);
85
86int aoa_snd_ctl_add(struct snd_kcontrol* control)
87{
88 int err;
89
90 if (!aoa_card) return -ENODEV;
91
92 err = snd_ctl_add(aoa_card->alsa_card, control);
93 if (err)
94 printk(KERN_ERR "snd-aoa: failed to add alsa control (%d)\n",
95 err);
96 return err;
97}
98EXPORT_SYMBOL_GPL(aoa_snd_ctl_add);
diff --git a/sound/aoa/core/snd-aoa-alsa.h b/sound/aoa/core/snd-aoa-alsa.h
new file mode 100644
index 000000000000..660d2f1793bb
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-alsa.h
@@ -0,0 +1,16 @@
1/*
2 * Apple Onboard Audio Alsa private helpers
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#ifndef __SND_AOA_ALSA_H
10#define __SND_AOA_ALSA_H
11#include "../aoa.h"
12
13extern int aoa_alsa_init(char *name, struct module *mod);
14extern void aoa_alsa_cleanup(void);
15
16#endif /* __SND_AOA_ALSA_H */
diff --git a/sound/aoa/core/snd-aoa-core.c b/sound/aoa/core/snd-aoa-core.c
new file mode 100644
index 000000000000..ecd2d8263f2d
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-core.c
@@ -0,0 +1,162 @@
1/*
2 * Apple Onboard Audio driver core
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/list.h>
12#include "../aoa.h"
13#include "snd-aoa-alsa.h"
14
15MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver");
16MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
17MODULE_LICENSE("GPL");
18
19/* We allow only one fabric. This simplifies things,
20 * and more don't really make that much sense */
21static struct aoa_fabric *fabric;
22static LIST_HEAD(codec_list);
23
24static int attach_codec_to_fabric(struct aoa_codec *c)
25{
26 int err;
27
28 if (!try_module_get(c->owner))
29 return -EBUSY;
30 /* found_codec has to be assigned */
31 err = -ENOENT;
32 if (fabric->found_codec)
33 err = fabric->found_codec(c);
34 if (err) {
35 module_put(c->owner);
36 printk(KERN_ERR "snd-aoa: fabric didn't like codec %s\n",
37 c->name);
38 return err;
39 }
40 c->fabric = fabric;
41
42 err = 0;
43 if (c->init)
44 err = c->init(c);
45 if (err) {
46 printk(KERN_ERR "snd-aoa: codec %s didn't init\n", c->name);
47 c->fabric = NULL;
48 if (fabric->remove_codec)
49 fabric->remove_codec(c);
50 module_put(c->owner);
51 return err;
52 }
53 if (fabric->attached_codec)
54 fabric->attached_codec(c);
55 return 0;
56}
57
58int aoa_codec_register(struct aoa_codec *codec)
59{
60 int err = 0;
61
62 /* if there's a fabric already, we can tell if we
63 * will want to have this codec, so propagate error
64 * through. Otherwise, this will happen later... */
65 if (fabric)
66 err = attach_codec_to_fabric(codec);
67 if (!err)
68 list_add(&codec->list, &codec_list);
69 return err;
70}
71EXPORT_SYMBOL_GPL(aoa_codec_register);
72
73void aoa_codec_unregister(struct aoa_codec *codec)
74{
75 list_del(&codec->list);
76 if (codec->fabric && codec->exit)
77 codec->exit(codec);
78 if (fabric && fabric->remove_codec)
79 fabric->remove_codec(codec);
80 codec->fabric = NULL;
81 module_put(codec->owner);
82}
83EXPORT_SYMBOL_GPL(aoa_codec_unregister);
84
85int aoa_fabric_register(struct aoa_fabric *new_fabric)
86{
87 struct aoa_codec *c;
88 int err;
89
90 /* allow querying for presence of fabric
91 * (i.e. do this test first!) */
92 if (new_fabric == fabric) {
93 err = -EALREADY;
94 goto attach;
95 }
96 if (fabric)
97 return -EEXIST;
98 if (!new_fabric)
99 return -EINVAL;
100
101 err = aoa_alsa_init(new_fabric->name, new_fabric->owner);
102 if (err)
103 return err;
104
105 fabric = new_fabric;
106
107 attach:
108 list_for_each_entry(c, &codec_list, list) {
109 if (c->fabric != fabric)
110 attach_codec_to_fabric(c);
111 }
112 return err;
113}
114EXPORT_SYMBOL_GPL(aoa_fabric_register);
115
116void aoa_fabric_unregister(struct aoa_fabric *old_fabric)
117{
118 struct aoa_codec *c;
119
120 if (fabric != old_fabric)
121 return;
122
123 list_for_each_entry(c, &codec_list, list) {
124 if (c->fabric)
125 aoa_fabric_unlink_codec(c);
126 }
127
128 aoa_alsa_cleanup();
129
130 fabric = NULL;
131}
132EXPORT_SYMBOL_GPL(aoa_fabric_unregister);
133
134void aoa_fabric_unlink_codec(struct aoa_codec *codec)
135{
136 if (!codec->fabric) {
137 printk(KERN_ERR "snd-aoa: fabric unassigned "
138 "in aoa_fabric_unlink_codec\n");
139 dump_stack();
140 return;
141 }
142 if (codec->exit)
143 codec->exit(codec);
144 if (codec->fabric->remove_codec)
145 codec->fabric->remove_codec(codec);
146 codec->fabric = NULL;
147 module_put(codec->owner);
148}
149EXPORT_SYMBOL_GPL(aoa_fabric_unlink_codec);
150
151static int __init aoa_init(void)
152{
153 return 0;
154}
155
156static void __exit aoa_exit(void)
157{
158 aoa_alsa_cleanup();
159}
160
161module_init(aoa_init);
162module_exit(aoa_exit);
diff --git a/sound/aoa/core/snd-aoa-gpio-feature.c b/sound/aoa/core/snd-aoa-gpio-feature.c
new file mode 100644
index 000000000000..2c6eb7784cc9
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-gpio-feature.c
@@ -0,0 +1,399 @@
1/*
2 * Apple Onboard Audio feature call GPIO control
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 *
8 * This file contains the GPIO control routines for
9 * direct (through feature calls) access to the GPIO
10 * registers.
11 */
12
13#include <asm/pmac_feature.h>
14#include <linux/interrupt.h>
15#include "../aoa.h"
16
17/* TODO: these are 20 global variables
18 * that aren't used on most machines...
19 * Move them into a dynamically allocated
20 * structure and use that.
21 */
22
23/* these are the GPIO numbers (register addresses as offsets into
24 * the GPIO space) */
25static int headphone_mute_gpio;
26static int amp_mute_gpio;
27static int lineout_mute_gpio;
28static int hw_reset_gpio;
29static int lineout_detect_gpio;
30static int headphone_detect_gpio;
31static int linein_detect_gpio;
32
33/* see the SWITCH_GPIO macro */
34static int headphone_mute_gpio_activestate;
35static int amp_mute_gpio_activestate;
36static int lineout_mute_gpio_activestate;
37static int hw_reset_gpio_activestate;
38static int lineout_detect_gpio_activestate;
39static int headphone_detect_gpio_activestate;
40static int linein_detect_gpio_activestate;
41
42/* node pointers that we save when getting the GPIO number
43 * to get the interrupt later */
44static struct device_node *lineout_detect_node;
45static struct device_node *linein_detect_node;
46static struct device_node *headphone_detect_node;
47
48static int lineout_detect_irq;
49static int linein_detect_irq;
50static int headphone_detect_irq;
51
52static struct device_node *get_gpio(char *name,
53 char *altname,
54 int *gpioptr,
55 int *gpioactiveptr)
56{
57 struct device_node *np, *gpio;
58 u32 *reg;
59 char *audio_gpio;
60
61 *gpioptr = -1;
62
63 /* check if we can get it the easy way ... */
64 np = of_find_node_by_name(NULL, name);
65 if (!np) {
66 /* some machines have only gpioX/extint-gpioX nodes,
67 * and an audio-gpio property saying what it is ...
68 * So what we have to do is enumerate all children
69 * of the gpio node and check them all. */
70 gpio = of_find_node_by_name(NULL, "gpio");
71 if (!gpio)
72 return NULL;
73 while ((np = of_get_next_child(gpio, np))) {
74 audio_gpio = get_property(np, "audio-gpio", NULL);
75 if (!audio_gpio)
76 continue;
77 if (strcmp(audio_gpio, name) == 0)
78 break;
79 if (altname && (strcmp(audio_gpio, altname) == 0))
80 break;
81 }
82 /* still not found, assume not there */
83 if (!np)
84 return NULL;
85 }
86
87 reg = (u32 *)get_property(np, "reg", NULL);
88 if (!reg)
89 return NULL;
90
91 *gpioptr = *reg;
92
93 /* this is a hack, usually the GPIOs 'reg' property
94 * should have the offset based from the GPIO space
95 * which is at 0x50, but apparently not always... */
96 if (*gpioptr < 0x50)
97 *gpioptr += 0x50;
98
99 reg = (u32 *)get_property(np, "audio-gpio-active-state", NULL);
100 if (!reg)
101 /* Apple seems to default to 1, but
102 * that doesn't seem right at least on most
103 * machines. So until proven that the opposite
104 * is necessary, we default to 0
105 * (which, incidentally, snd-powermac also does...) */
106 *gpioactiveptr = 0;
107 else
108 *gpioactiveptr = *reg;
109
110 return np;
111}
112
113static void get_irq(struct device_node * np, int *irqptr)
114{
115 *irqptr = -1;
116 if (!np)
117 return;
118 if (np->n_intrs != 1)
119 return;
120 *irqptr = np->intrs[0].line;
121}
122
123/* 0x4 is outenable, 0x1 is out, thus 4 or 5 */
124#define SWITCH_GPIO(name, v, on) \
125 (((v)&~1) | ((on)? \
126 (name##_gpio_activestate==0?4:5): \
127 (name##_gpio_activestate==0?5:4)))
128
129#define FTR_GPIO(name, bit) \
130static void ftr_gpio_set_##name(struct gpio_runtime *rt, int on)\
131{ \
132 int v; \
133 \
134 if (unlikely(!rt)) return; \
135 \
136 if (name##_mute_gpio < 0) \
137 return; \
138 \
139 v = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, \
140 name##_mute_gpio, \
141 0); \
142 \
143 /* muted = !on... */ \
144 v = SWITCH_GPIO(name##_mute, v, !on); \
145 \
146 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, \
147 name##_mute_gpio, v); \
148 \
149 rt->implementation_private &= ~(1<<bit); \
150 rt->implementation_private |= (!!on << bit); \
151} \
152static int ftr_gpio_get_##name(struct gpio_runtime *rt) \
153{ \
154 if (unlikely(!rt)) return 0; \
155 return (rt->implementation_private>>bit)&1; \
156}
157
158FTR_GPIO(headphone, 0);
159FTR_GPIO(amp, 1);
160FTR_GPIO(lineout, 2);
161
162static void ftr_gpio_set_hw_reset(struct gpio_runtime *rt, int on)
163{
164 int v;
165
166 if (unlikely(!rt)) return;
167 if (hw_reset_gpio < 0)
168 return;
169
170 v = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL,
171 hw_reset_gpio, 0);
172 v = SWITCH_GPIO(hw_reset, v, on);
173 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL,
174 hw_reset_gpio, v);
175}
176
177static void ftr_gpio_all_amps_off(struct gpio_runtime *rt)
178{
179 int saved;
180
181 if (unlikely(!rt)) return;
182 saved = rt->implementation_private;
183 ftr_gpio_set_headphone(rt, 0);
184 ftr_gpio_set_amp(rt, 0);
185 ftr_gpio_set_lineout(rt, 0);
186 rt->implementation_private = saved;
187}
188
189static void ftr_gpio_all_amps_restore(struct gpio_runtime *rt)
190{
191 int s;
192
193 if (unlikely(!rt)) return;
194 s = rt->implementation_private;
195 ftr_gpio_set_headphone(rt, (s>>0)&1);
196 ftr_gpio_set_amp(rt, (s>>1)&1);
197 ftr_gpio_set_lineout(rt, (s>>2)&1);
198}
199
200static void ftr_handle_notify(void *data)
201{
202 struct gpio_notification *notif = data;
203
204 mutex_lock(&notif->mutex);
205 if (notif->notify)
206 notif->notify(notif->data);
207 mutex_unlock(&notif->mutex);
208}
209
210static void ftr_gpio_init(struct gpio_runtime *rt)
211{
212 get_gpio("headphone-mute", NULL,
213 &headphone_mute_gpio,
214 &headphone_mute_gpio_activestate);
215 get_gpio("amp-mute", NULL,
216 &amp_mute_gpio,
217 &amp_mute_gpio_activestate);
218 get_gpio("lineout-mute", NULL,
219 &lineout_mute_gpio,
220 &lineout_mute_gpio_activestate);
221 get_gpio("hw-reset", "audio-hw-reset",
222 &hw_reset_gpio,
223 &hw_reset_gpio_activestate);
224
225 headphone_detect_node = get_gpio("headphone-detect", NULL,
226 &headphone_detect_gpio,
227 &headphone_detect_gpio_activestate);
228 /* go Apple, and thanks for giving these different names
229 * across the board... */
230 lineout_detect_node = get_gpio("lineout-detect", "line-output-detect",
231 &lineout_detect_gpio,
232 &lineout_detect_gpio_activestate);
233 linein_detect_node = get_gpio("linein-detect", "line-input-detect",
234 &linein_detect_gpio,
235 &linein_detect_gpio_activestate);
236
237 get_irq(headphone_detect_node, &headphone_detect_irq);
238 get_irq(lineout_detect_node, &lineout_detect_irq);
239 get_irq(linein_detect_node, &linein_detect_irq);
240
241 ftr_gpio_all_amps_off(rt);
242 rt->implementation_private = 0;
243 INIT_WORK(&rt->headphone_notify.work, ftr_handle_notify,
244 &rt->headphone_notify);
245 INIT_WORK(&rt->line_in_notify.work, ftr_handle_notify,
246 &rt->line_in_notify);
247 INIT_WORK(&rt->line_out_notify.work, ftr_handle_notify,
248 &rt->line_out_notify);
249 mutex_init(&rt->headphone_notify.mutex);
250 mutex_init(&rt->line_in_notify.mutex);
251 mutex_init(&rt->line_out_notify.mutex);
252}
253
254static void ftr_gpio_exit(struct gpio_runtime *rt)
255{
256 ftr_gpio_all_amps_off(rt);
257 rt->implementation_private = 0;
258 if (rt->headphone_notify.notify)
259 free_irq(headphone_detect_irq, &rt->headphone_notify);
260 if (rt->line_in_notify.gpio_private)
261 free_irq(linein_detect_irq, &rt->line_in_notify);
262 if (rt->line_out_notify.gpio_private)
263 free_irq(lineout_detect_irq, &rt->line_out_notify);
264 cancel_delayed_work(&rt->headphone_notify.work);
265 cancel_delayed_work(&rt->line_in_notify.work);
266 cancel_delayed_work(&rt->line_out_notify.work);
267 flush_scheduled_work();
268 mutex_destroy(&rt->headphone_notify.mutex);
269 mutex_destroy(&rt->line_in_notify.mutex);
270 mutex_destroy(&rt->line_out_notify.mutex);
271}
272
273static irqreturn_t ftr_handle_notify_irq(int xx,
274 void *data,
275 struct pt_regs *regs)
276{
277 struct gpio_notification *notif = data;
278
279 schedule_work(&notif->work);
280
281 return IRQ_HANDLED;
282}
283
284static int ftr_set_notify(struct gpio_runtime *rt,
285 enum notify_type type,
286 notify_func_t notify,
287 void *data)
288{
289 struct gpio_notification *notif;
290 notify_func_t old;
291 int irq;
292 char *name;
293 int err = -EBUSY;
294
295 switch (type) {
296 case AOA_NOTIFY_HEADPHONE:
297 notif = &rt->headphone_notify;
298 name = "headphone-detect";
299 irq = headphone_detect_irq;
300 break;
301 case AOA_NOTIFY_LINE_IN:
302 notif = &rt->line_in_notify;
303 name = "linein-detect";
304 irq = linein_detect_irq;
305 break;
306 case AOA_NOTIFY_LINE_OUT:
307 notif = &rt->line_out_notify;
308 name = "lineout-detect";
309 irq = lineout_detect_irq;
310 break;
311 default:
312 return -EINVAL;
313 }
314
315 if (irq == -1)
316 return -ENODEV;
317
318 mutex_lock(&notif->mutex);
319
320 old = notif->notify;
321
322 if (!old && !notify) {
323 err = 0;
324 goto out_unlock;
325 }
326
327 if (old && notify) {
328 if (old == notify && notif->data == data)
329 err = 0;
330 goto out_unlock;
331 }
332
333 if (old && !notify)
334 free_irq(irq, notif);
335
336 if (!old && notify) {
337 err = request_irq(irq, ftr_handle_notify_irq, 0, name, notif);
338 if (err)
339 goto out_unlock;
340 }
341
342 notif->notify = notify;
343 notif->data = data;
344
345 err = 0;
346 out_unlock:
347 mutex_unlock(&notif->mutex);
348 return err;
349}
350
351static int ftr_get_detect(struct gpio_runtime *rt,
352 enum notify_type type)
353{
354 int gpio, ret, active;
355
356 switch (type) {
357 case AOA_NOTIFY_HEADPHONE:
358 gpio = headphone_detect_gpio;
359 active = headphone_detect_gpio_activestate;
360 break;
361 case AOA_NOTIFY_LINE_IN:
362 gpio = linein_detect_gpio;
363 active = linein_detect_gpio_activestate;
364 break;
365 case AOA_NOTIFY_LINE_OUT:
366 gpio = lineout_detect_gpio;
367 active = lineout_detect_gpio_activestate;
368 break;
369 default:
370 return -EINVAL;
371 }
372
373 if (gpio == -1)
374 return -ENODEV;
375
376 ret = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio, 0);
377 if (ret < 0)
378 return ret;
379 return ((ret >> 1) & 1) == active;
380}
381
382static struct gpio_methods methods = {
383 .init = ftr_gpio_init,
384 .exit = ftr_gpio_exit,
385 .all_amps_off = ftr_gpio_all_amps_off,
386 .all_amps_restore = ftr_gpio_all_amps_restore,
387 .set_headphone = ftr_gpio_set_headphone,
388 .set_speakers = ftr_gpio_set_amp,
389 .set_lineout = ftr_gpio_set_lineout,
390 .set_hw_reset = ftr_gpio_set_hw_reset,
391 .get_headphone = ftr_gpio_get_headphone,
392 .get_speakers = ftr_gpio_get_amp,
393 .get_lineout = ftr_gpio_get_lineout,
394 .set_notify = ftr_set_notify,
395 .get_detect = ftr_get_detect,
396};
397
398struct gpio_methods *ftr_gpio_methods = &methods;
399EXPORT_SYMBOL_GPL(ftr_gpio_methods);
diff --git a/sound/aoa/core/snd-aoa-gpio-pmf.c b/sound/aoa/core/snd-aoa-gpio-pmf.c
new file mode 100644
index 000000000000..0e9b9bb2a6de
--- /dev/null
+++ b/sound/aoa/core/snd-aoa-gpio-pmf.c
@@ -0,0 +1,246 @@
1/*
2 * Apple Onboard Audio pmf GPIOs
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#include <asm/pmac_feature.h>
10#include <asm/pmac_pfunc.h>
11#include "../aoa.h"
12
13#define PMF_GPIO(name, bit) \
14static void pmf_gpio_set_##name(struct gpio_runtime *rt, int on)\
15{ \
16 struct pmf_args args = { .count = 1, .u[0].v = !on }; \
17 \
18 if (unlikely(!rt)) return; \
19 pmf_call_function(rt->node, #name "-mute", &args); \
20 rt->implementation_private &= ~(1<<bit); \
21 rt->implementation_private |= (!!on << bit); \
22} \
23static int pmf_gpio_get_##name(struct gpio_runtime *rt) \
24{ \
25 if (unlikely(!rt)) return 0; \
26 return (rt->implementation_private>>bit)&1; \
27}
28
29PMF_GPIO(headphone, 0);
30PMF_GPIO(amp, 1);
31PMF_GPIO(lineout, 2);
32
33static void pmf_gpio_set_hw_reset(struct gpio_runtime *rt, int on)
34{
35 struct pmf_args args = { .count = 1, .u[0].v = !!on };
36
37 if (unlikely(!rt)) return;
38 pmf_call_function(rt->node, "hw-reset", &args);
39}
40
41static void pmf_gpio_all_amps_off(struct gpio_runtime *rt)
42{
43 int saved;
44
45 if (unlikely(!rt)) return;
46 saved = rt->implementation_private;
47 pmf_gpio_set_headphone(rt, 0);
48 pmf_gpio_set_amp(rt, 0);
49 pmf_gpio_set_lineout(rt, 0);
50 rt->implementation_private = saved;
51}
52
53static void pmf_gpio_all_amps_restore(struct gpio_runtime *rt)
54{
55 int s;
56
57 if (unlikely(!rt)) return;
58 s = rt->implementation_private;
59 pmf_gpio_set_headphone(rt, (s>>0)&1);
60 pmf_gpio_set_amp(rt, (s>>1)&1);
61 pmf_gpio_set_lineout(rt, (s>>2)&1);
62}
63
64static void pmf_handle_notify(void *data)
65{
66 struct gpio_notification *notif = data;
67
68 mutex_lock(&notif->mutex);
69 if (notif->notify)
70 notif->notify(notif->data);
71 mutex_unlock(&notif->mutex);
72}
73
74static void pmf_gpio_init(struct gpio_runtime *rt)
75{
76 pmf_gpio_all_amps_off(rt);
77 rt->implementation_private = 0;
78 INIT_WORK(&rt->headphone_notify.work, pmf_handle_notify,
79 &rt->headphone_notify);
80 INIT_WORK(&rt->line_in_notify.work, pmf_handle_notify,
81 &rt->line_in_notify);
82 INIT_WORK(&rt->line_out_notify.work, pmf_handle_notify,
83 &rt->line_out_notify);
84 mutex_init(&rt->headphone_notify.mutex);
85 mutex_init(&rt->line_in_notify.mutex);
86 mutex_init(&rt->line_out_notify.mutex);
87}
88
89static void pmf_gpio_exit(struct gpio_runtime *rt)
90{
91 pmf_gpio_all_amps_off(rt);
92 rt->implementation_private = 0;
93
94 if (rt->headphone_notify.gpio_private)
95 pmf_unregister_irq_client(rt->headphone_notify.gpio_private);
96 if (rt->line_in_notify.gpio_private)
97 pmf_unregister_irq_client(rt->line_in_notify.gpio_private);
98 if (rt->line_out_notify.gpio_private)
99 pmf_unregister_irq_client(rt->line_out_notify.gpio_private);
100
101 /* make sure no work is pending before freeing
102 * all things */
103 cancel_delayed_work(&rt->headphone_notify.work);
104 cancel_delayed_work(&rt->line_in_notify.work);
105 cancel_delayed_work(&rt->line_out_notify.work);
106 flush_scheduled_work();
107
108 mutex_destroy(&rt->headphone_notify.mutex);
109 mutex_destroy(&rt->line_in_notify.mutex);
110 mutex_destroy(&rt->line_out_notify.mutex);
111
112 if (rt->headphone_notify.gpio_private)
113 kfree(rt->headphone_notify.gpio_private);
114 if (rt->line_in_notify.gpio_private)
115 kfree(rt->line_in_notify.gpio_private);
116 if (rt->line_out_notify.gpio_private)
117 kfree(rt->line_out_notify.gpio_private);
118}
119
120static void pmf_handle_notify_irq(void *data)
121{
122 struct gpio_notification *notif = data;
123
124 schedule_work(&notif->work);
125}
126
127static int pmf_set_notify(struct gpio_runtime *rt,
128 enum notify_type type,
129 notify_func_t notify,
130 void *data)
131{
132 struct gpio_notification *notif;
133 notify_func_t old;
134 struct pmf_irq_client *irq_client;
135 char *name;
136 int err = -EBUSY;
137
138 switch (type) {
139 case AOA_NOTIFY_HEADPHONE:
140 notif = &rt->headphone_notify;
141 name = "headphone-detect";
142 break;
143 case AOA_NOTIFY_LINE_IN:
144 notif = &rt->line_in_notify;
145 name = "linein-detect";
146 break;
147 case AOA_NOTIFY_LINE_OUT:
148 notif = &rt->line_out_notify;
149 name = "lineout-detect";
150 break;
151 default:
152 return -EINVAL;
153 }
154
155 mutex_lock(&notif->mutex);
156
157 old = notif->notify;
158
159 if (!old && !notify) {
160 err = 0;
161 goto out_unlock;
162 }
163
164 if (old && notify) {
165 if (old == notify && notif->data == data)
166 err = 0;
167 goto out_unlock;
168 }
169
170 if (old && !notify) {
171 irq_client = notif->gpio_private;
172 pmf_unregister_irq_client(irq_client);
173 kfree(irq_client);
174 notif->gpio_private = NULL;
175 }
176 if (!old && notify) {
177 irq_client = kzalloc(sizeof(struct pmf_irq_client),
178 GFP_KERNEL);
179 irq_client->data = notif;
180 irq_client->handler = pmf_handle_notify_irq;
181 irq_client->owner = THIS_MODULE;
182 err = pmf_register_irq_client(rt->node,
183 name,
184 irq_client);
185 if (err) {
186 printk(KERN_ERR "snd-aoa: gpio layer failed to"
187 " register %s irq (%d)\n", name, err);
188 kfree(irq_client);
189 goto out_unlock;
190 }
191 notif->gpio_private = irq_client;
192 }
193 notif->notify = notify;
194 notif->data = data;
195
196 err = 0;
197 out_unlock:
198 mutex_unlock(&notif->mutex);
199 return err;
200}
201
202static int pmf_get_detect(struct gpio_runtime *rt,
203 enum notify_type type)
204{
205 char *name;
206 int err = -EBUSY, ret;
207 struct pmf_args args = { .count = 1, .u[0].p = &ret };
208
209 switch (type) {
210 case AOA_NOTIFY_HEADPHONE:
211 name = "headphone-detect";
212 break;
213 case AOA_NOTIFY_LINE_IN:
214 name = "linein-detect";
215 break;
216 case AOA_NOTIFY_LINE_OUT:
217 name = "lineout-detect";
218 break;
219 default:
220 return -EINVAL;
221 }
222
223 err = pmf_call_function(rt->node, name, &args);
224 if (err)
225 return err;
226 return ret;
227}
228
229static struct gpio_methods methods = {
230 .init = pmf_gpio_init,
231 .exit = pmf_gpio_exit,
232 .all_amps_off = pmf_gpio_all_amps_off,
233 .all_amps_restore = pmf_gpio_all_amps_restore,
234 .set_headphone = pmf_gpio_set_headphone,
235 .set_speakers = pmf_gpio_set_amp,
236 .set_lineout = pmf_gpio_set_lineout,
237 .set_hw_reset = pmf_gpio_set_hw_reset,
238 .get_headphone = pmf_gpio_get_headphone,
239 .get_speakers = pmf_gpio_get_amp,
240 .get_lineout = pmf_gpio_get_lineout,
241 .set_notify = pmf_set_notify,
242 .get_detect = pmf_get_detect,
243};
244
245struct gpio_methods *pmf_gpio_methods = &methods;
246EXPORT_SYMBOL_GPL(pmf_gpio_methods);
diff --git a/sound/aoa/fabrics/Kconfig b/sound/aoa/fabrics/Kconfig
new file mode 100644
index 000000000000..c3bc7705c86a
--- /dev/null
+++ b/sound/aoa/fabrics/Kconfig
@@ -0,0 +1,12 @@
1config SND_AOA_FABRIC_LAYOUT
2 tristate "layout-id fabric"
3 depends SND_AOA
4 select SND_AOA_SOUNDBUS
5 select SND_AOA_SOUNDBUS_I2S
6 ---help---
7 This enables the layout-id fabric for the Apple Onboard
8 Audio driver, the module holding it all together
9 based on the device-tree's layout-id property.
10
11 If you are unsure and have a later Apple machine,
12 compile it as a module.
diff --git a/sound/aoa/fabrics/Makefile b/sound/aoa/fabrics/Makefile
new file mode 100644
index 000000000000..55fc5e7e52cf
--- /dev/null
+++ b/sound/aoa/fabrics/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_SND_AOA_FABRIC_LAYOUT) += snd-aoa-fabric-layout.o
diff --git a/sound/aoa/fabrics/snd-aoa-fabric-layout.c b/sound/aoa/fabrics/snd-aoa-fabric-layout.c
new file mode 100644
index 000000000000..04a7238e9494
--- /dev/null
+++ b/sound/aoa/fabrics/snd-aoa-fabric-layout.c
@@ -0,0 +1,1109 @@
1/*
2 * Apple Onboard Audio driver -- layout fabric
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 *
8 *
9 * This fabric module looks for sound codecs
10 * based on the layout-id property in the device tree.
11 *
12 */
13
14#include <asm/prom.h>
15#include <linux/list.h>
16#include <linux/module.h>
17#include "../aoa.h"
18#include "../soundbus/soundbus.h"
19
20MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
21MODULE_LICENSE("GPL");
22MODULE_DESCRIPTION("Layout-ID fabric for snd-aoa");
23
24#define MAX_CODECS_PER_BUS 2
25
26/* These are the connections the layout fabric
27 * knows about. It doesn't really care about the
28 * input ones, but I thought I'd separate them
29 * to give them proper names. The thing is that
30 * Apple usually will distinguish the active output
31 * by GPIOs, while the active input is set directly
32 * on the codec. Hence we here tell the codec what
33 * we think is connected. This information is hard-
34 * coded below ... */
35#define CC_SPEAKERS (1<<0)
36#define CC_HEADPHONE (1<<1)
37#define CC_LINEOUT (1<<2)
38#define CC_DIGITALOUT (1<<3)
39#define CC_LINEIN (1<<4)
40#define CC_MICROPHONE (1<<5)
41#define CC_DIGITALIN (1<<6)
42/* pretty bogus but users complain...
43 * This is a flag saying that the LINEOUT
44 * should be renamed to HEADPHONE.
45 * be careful with input detection! */
46#define CC_LINEOUT_LABELLED_HEADPHONE (1<<7)
47
48struct codec_connection {
49 /* CC_ flags from above */
50 int connected;
51 /* codec dependent bit to be set in the aoa_codec.connected field.
52 * This intentionally doesn't have any generic flags because the
53 * fabric has to know the codec anyway and all codecs might have
54 * different connectors */
55 int codec_bit;
56};
57
58struct codec_connect_info {
59 char *name;
60 struct codec_connection *connections;
61};
62
63#define LAYOUT_FLAG_COMBO_LINEOUT_SPDIF (1<<0)
64
65struct layout {
66 unsigned int layout_id;
67 struct codec_connect_info codecs[MAX_CODECS_PER_BUS];
68 int flags;
69
70 /* if busname is not assigned, we use 'Master' below,
71 * so that our layout table doesn't need to be filled
72 * too much.
73 * We only assign these two if we expect to find more
74 * than one soundbus, i.e. on those machines with
75 * multiple layout-ids */
76 char *busname;
77 int pcmid;
78};
79
80MODULE_ALIAS("sound-layout-41");
81MODULE_ALIAS("sound-layout-45");
82MODULE_ALIAS("sound-layout-51");
83MODULE_ALIAS("sound-layout-58");
84MODULE_ALIAS("sound-layout-60");
85MODULE_ALIAS("sound-layout-61");
86MODULE_ALIAS("sound-layout-64");
87MODULE_ALIAS("sound-layout-65");
88MODULE_ALIAS("sound-layout-68");
89MODULE_ALIAS("sound-layout-69");
90MODULE_ALIAS("sound-layout-70");
91MODULE_ALIAS("sound-layout-72");
92MODULE_ALIAS("sound-layout-80");
93MODULE_ALIAS("sound-layout-82");
94MODULE_ALIAS("sound-layout-84");
95MODULE_ALIAS("sound-layout-86");
96MODULE_ALIAS("sound-layout-92");
97
98/* onyx with all but microphone connected */
99static struct codec_connection onyx_connections_nomic[] = {
100 {
101 .connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
102 .codec_bit = 0,
103 },
104 {
105 .connected = CC_DIGITALOUT,
106 .codec_bit = 1,
107 },
108 {
109 .connected = CC_LINEIN,
110 .codec_bit = 2,
111 },
112 {} /* terminate array by .connected == 0 */
113};
114
115/* onyx on machines without headphone */
116static struct codec_connection onyx_connections_noheadphones[] = {
117 {
118 .connected = CC_SPEAKERS | CC_LINEOUT |
119 CC_LINEOUT_LABELLED_HEADPHONE,
120 .codec_bit = 0,
121 },
122 {
123 .connected = CC_DIGITALOUT,
124 .codec_bit = 1,
125 },
126 /* FIXME: are these correct? probably not for all the machines
127 * below ... If not this will need separating. */
128 {
129 .connected = CC_LINEIN,
130 .codec_bit = 2,
131 },
132 {
133 .connected = CC_MICROPHONE,
134 .codec_bit = 3,
135 },
136 {} /* terminate array by .connected == 0 */
137};
138
139/* onyx on machines with real line-out */
140static struct codec_connection onyx_connections_reallineout[] = {
141 {
142 .connected = CC_SPEAKERS | CC_LINEOUT | CC_HEADPHONE,
143 .codec_bit = 0,
144 },
145 {
146 .connected = CC_DIGITALOUT,
147 .codec_bit = 1,
148 },
149 {
150 .connected = CC_LINEIN,
151 .codec_bit = 2,
152 },
153 {} /* terminate array by .connected == 0 */
154};
155
156/* tas on machines without line out */
157static struct codec_connection tas_connections_nolineout[] = {
158 {
159 .connected = CC_SPEAKERS | CC_HEADPHONE,
160 .codec_bit = 0,
161 },
162 {
163 .connected = CC_LINEIN,
164 .codec_bit = 2,
165 },
166 {
167 .connected = CC_MICROPHONE,
168 .codec_bit = 3,
169 },
170 {} /* terminate array by .connected == 0 */
171};
172
173/* tas on machines with neither line out nor line in */
174static struct codec_connection tas_connections_noline[] = {
175 {
176 .connected = CC_SPEAKERS | CC_HEADPHONE,
177 .codec_bit = 0,
178 },
179 {
180 .connected = CC_MICROPHONE,
181 .codec_bit = 3,
182 },
183 {} /* terminate array by .connected == 0 */
184};
185
186/* tas on machines without microphone */
187static struct codec_connection tas_connections_nomic[] = {
188 {
189 .connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
190 .codec_bit = 0,
191 },
192 {
193 .connected = CC_LINEIN,
194 .codec_bit = 2,
195 },
196 {} /* terminate array by .connected == 0 */
197};
198
199/* tas on machines with everything connected */
200static struct codec_connection tas_connections_all[] = {
201 {
202 .connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
203 .codec_bit = 0,
204 },
205 {
206 .connected = CC_LINEIN,
207 .codec_bit = 2,
208 },
209 {
210 .connected = CC_MICROPHONE,
211 .codec_bit = 3,
212 },
213 {} /* terminate array by .connected == 0 */
214};
215
216static struct codec_connection toonie_connections[] = {
217 {
218 .connected = CC_SPEAKERS | CC_HEADPHONE,
219 .codec_bit = 0,
220 },
221 {} /* terminate array by .connected == 0 */
222};
223
224static struct codec_connection topaz_input[] = {
225 {
226 .connected = CC_DIGITALIN,
227 .codec_bit = 0,
228 },
229 {} /* terminate array by .connected == 0 */
230};
231
232static struct codec_connection topaz_output[] = {
233 {
234 .connected = CC_DIGITALOUT,
235 .codec_bit = 1,
236 },
237 {} /* terminate array by .connected == 0 */
238};
239
240static struct codec_connection topaz_inout[] = {
241 {
242 .connected = CC_DIGITALIN,
243 .codec_bit = 0,
244 },
245 {
246 .connected = CC_DIGITALOUT,
247 .codec_bit = 1,
248 },
249 {} /* terminate array by .connected == 0 */
250};
251
252static struct layout layouts[] = {
253 /* last PowerBooks (15" Oct 2005) */
254 { .layout_id = 82,
255 .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
256 .codecs[0] = {
257 .name = "onyx",
258 .connections = onyx_connections_noheadphones,
259 },
260 .codecs[1] = {
261 .name = "topaz",
262 .connections = topaz_input,
263 },
264 },
265 /* PowerMac9,1 */
266 { .layout_id = 60,
267 .codecs[0] = {
268 .name = "onyx",
269 .connections = onyx_connections_reallineout,
270 },
271 },
272 /* PowerMac9,1 */
273 { .layout_id = 61,
274 .codecs[0] = {
275 .name = "topaz",
276 .connections = topaz_input,
277 },
278 },
279 /* PowerBook5,7 */
280 { .layout_id = 64,
281 .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
282 .codecs[0] = {
283 .name = "onyx",
284 .connections = onyx_connections_noheadphones,
285 },
286 },
287 /* PowerBook5,7 */
288 { .layout_id = 65,
289 .codecs[0] = {
290 .name = "topaz",
291 .connections = topaz_input,
292 },
293 },
294 /* PowerBook5,9 [17" Oct 2005] */
295 { .layout_id = 84,
296 .flags = LAYOUT_FLAG_COMBO_LINEOUT_SPDIF,
297 .codecs[0] = {
298 .name = "onyx",
299 .connections = onyx_connections_noheadphones,
300 },
301 .codecs[1] = {
302 .name = "topaz",
303 .connections = topaz_input,
304 },
305 },
306 /* PowerMac8,1 */
307 { .layout_id = 45,
308 .codecs[0] = {
309 .name = "onyx",
310 .connections = onyx_connections_noheadphones,
311 },
312 .codecs[1] = {
313 .name = "topaz",
314 .connections = topaz_input,
315 },
316 },
317 /* Quad PowerMac (analog in, analog/digital out) */
318 { .layout_id = 68,
319 .codecs[0] = {
320 .name = "onyx",
321 .connections = onyx_connections_nomic,
322 },
323 },
324 /* Quad PowerMac (digital in) */
325 { .layout_id = 69,
326 .codecs[0] = {
327 .name = "topaz",
328 .connections = topaz_input,
329 },
330 .busname = "digital in", .pcmid = 1 },
331 /* Early 2005 PowerBook (PowerBook 5,6) */
332 { .layout_id = 70,
333 .codecs[0] = {
334 .name = "tas",
335 .connections = tas_connections_nolineout,
336 },
337 },
338 /* PowerBook 5,4 */
339 { .layout_id = 51,
340 .codecs[0] = {
341 .name = "tas",
342 .connections = tas_connections_nolineout,
343 },
344 },
345 /* PowerBook6,7 */
346 { .layout_id = 80,
347 .codecs[0] = {
348 .name = "tas",
349 .connections = tas_connections_noline,
350 },
351 },
352 /* PowerBook6,8 */
353 { .layout_id = 72,
354 .codecs[0] = {
355 .name = "tas",
356 .connections = tas_connections_nolineout,
357 },
358 },
359 /* PowerMac8,2 */
360 { .layout_id = 86,
361 .codecs[0] = {
362 .name = "onyx",
363 .connections = onyx_connections_nomic,
364 },
365 .codecs[1] = {
366 .name = "topaz",
367 .connections = topaz_input,
368 },
369 },
370 /* PowerBook6,7 */
371 { .layout_id = 92,
372 .codecs[0] = {
373 .name = "tas",
374 .connections = tas_connections_nolineout,
375 },
376 },
377 /* PowerMac10,1 (Mac Mini) */
378 { .layout_id = 58,
379 .codecs[0] = {
380 .name = "toonie",
381 .connections = toonie_connections,
382 },
383 },
384 /* unknown, untested, but this comes from Apple */
385 { .layout_id = 41,
386 .codecs[0] = {
387 .name = "tas",
388 .connections = tas_connections_all,
389 },
390 },
391 { .layout_id = 36,
392 .codecs[0] = {
393 .name = "tas",
394 .connections = tas_connections_nomic,
395 },
396 .codecs[1] = {
397 .name = "topaz",
398 .connections = topaz_inout,
399 },
400 },
401 { .layout_id = 47,
402 .codecs[0] = {
403 .name = "onyx",
404 .connections = onyx_connections_noheadphones,
405 },
406 },
407 { .layout_id = 48,
408 .codecs[0] = {
409 .name = "topaz",
410 .connections = topaz_input,
411 },
412 },
413 { .layout_id = 49,
414 .codecs[0] = {
415 .name = "onyx",
416 .connections = onyx_connections_nomic,
417 },
418 },
419 { .layout_id = 50,
420 .codecs[0] = {
421 .name = "topaz",
422 .connections = topaz_input,
423 },
424 },
425 { .layout_id = 56,
426 .codecs[0] = {
427 .name = "onyx",
428 .connections = onyx_connections_noheadphones,
429 },
430 },
431 { .layout_id = 57,
432 .codecs[0] = {
433 .name = "topaz",
434 .connections = topaz_input,
435 },
436 },
437 { .layout_id = 62,
438 .codecs[0] = {
439 .name = "onyx",
440 .connections = onyx_connections_noheadphones,
441 },
442 .codecs[1] = {
443 .name = "topaz",
444 .connections = topaz_output,
445 },
446 },
447 { .layout_id = 66,
448 .codecs[0] = {
449 .name = "onyx",
450 .connections = onyx_connections_noheadphones,
451 },
452 },
453 { .layout_id = 67,
454 .codecs[0] = {
455 .name = "topaz",
456 .connections = topaz_input,
457 },
458 },
459 { .layout_id = 76,
460 .codecs[0] = {
461 .name = "tas",
462 .connections = tas_connections_nomic,
463 },
464 .codecs[1] = {
465 .name = "topaz",
466 .connections = topaz_inout,
467 },
468 },
469 { .layout_id = 90,
470 .codecs[0] = {
471 .name = "tas",
472 .connections = tas_connections_noline,
473 },
474 },
475 { .layout_id = 94,
476 .codecs[0] = {
477 .name = "onyx",
478 /* but it has an external mic?? how to select? */
479 .connections = onyx_connections_noheadphones,
480 },
481 },
482 { .layout_id = 96,
483 .codecs[0] = {
484 .name = "onyx",
485 .connections = onyx_connections_noheadphones,
486 },
487 },
488 { .layout_id = 98,
489 .codecs[0] = {
490 .name = "toonie",
491 .connections = toonie_connections,
492 },
493 },
494 { .layout_id = 100,
495 .codecs[0] = {
496 .name = "topaz",
497 .connections = topaz_input,
498 },
499 .codecs[1] = {
500 .name = "onyx",
501 .connections = onyx_connections_noheadphones,
502 },
503 },
504 {}
505};
506
507static struct layout *find_layout_by_id(unsigned int id)
508{
509 struct layout *l;
510
511 l = layouts;
512 while (l->layout_id) {
513 if (l->layout_id == id)
514 return l;
515 l++;
516 }
517 return NULL;
518}
519
520static void use_layout(struct layout *l)
521{
522 int i;
523
524 for (i=0; i<MAX_CODECS_PER_BUS; i++) {
525 if (l->codecs[i].name) {
526 request_module("snd-aoa-codec-%s", l->codecs[i].name);
527 }
528 }
529 /* now we wait for the codecs to call us back */
530}
531
532struct layout_dev;
533
534struct layout_dev_ptr {
535 struct layout_dev *ptr;
536};
537
538struct layout_dev {
539 struct list_head list;
540 struct soundbus_dev *sdev;
541 struct device_node *sound;
542 struct aoa_codec *codecs[MAX_CODECS_PER_BUS];
543 struct layout *layout;
544 struct gpio_runtime gpio;
545
546 /* we need these for headphone/lineout detection */
547 struct snd_kcontrol *headphone_ctrl;
548 struct snd_kcontrol *lineout_ctrl;
549 struct snd_kcontrol *speaker_ctrl;
550 struct snd_kcontrol *headphone_detected_ctrl;
551 struct snd_kcontrol *lineout_detected_ctrl;
552
553 struct layout_dev_ptr selfptr_headphone;
554 struct layout_dev_ptr selfptr_lineout;
555
556 u32 have_lineout_detect:1,
557 have_headphone_detect:1,
558 switch_on_headphone:1,
559 switch_on_lineout:1;
560};
561
562static LIST_HEAD(layouts_list);
563static int layouts_list_items;
564/* this can go away but only if we allow multiple cards,
565 * make the fabric handle all the card stuff, etc... */
566static struct layout_dev *layout_device;
567
568static int control_info(struct snd_kcontrol *kcontrol,
569 struct snd_ctl_elem_info *uinfo)
570{
571 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
572 uinfo->count = 1;
573 uinfo->value.integer.min = 0;
574 uinfo->value.integer.max = 1;
575 return 0;
576}
577
578#define AMP_CONTROL(n, description) \
579static int n##_control_get(struct snd_kcontrol *kcontrol, \
580 struct snd_ctl_elem_value *ucontrol) \
581{ \
582 struct gpio_runtime *gpio = snd_kcontrol_chip(kcontrol); \
583 if (gpio->methods && gpio->methods->get_##n) \
584 ucontrol->value.integer.value[0] = \
585 gpio->methods->get_##n(gpio); \
586 return 0; \
587} \
588static int n##_control_put(struct snd_kcontrol *kcontrol, \
589 struct snd_ctl_elem_value *ucontrol) \
590{ \
591 struct gpio_runtime *gpio = snd_kcontrol_chip(kcontrol); \
592 if (gpio->methods && gpio->methods->get_##n) \
593 gpio->methods->set_##n(gpio, \
594 ucontrol->value.integer.value[0]); \
595 return 1; \
596} \
597static struct snd_kcontrol_new n##_ctl = { \
598 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
599 .name = description, \
600 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
601 .info = control_info, \
602 .get = n##_control_get, \
603 .put = n##_control_put, \
604}
605
606AMP_CONTROL(headphone, "Headphone Switch");
607AMP_CONTROL(speakers, "Speakers Switch");
608AMP_CONTROL(lineout, "Line-Out Switch");
609
610static int detect_choice_get(struct snd_kcontrol *kcontrol,
611 struct snd_ctl_elem_value *ucontrol)
612{
613 struct layout_dev *ldev = snd_kcontrol_chip(kcontrol);
614
615 switch (kcontrol->private_value) {
616 case 0:
617 ucontrol->value.integer.value[0] = ldev->switch_on_headphone;
618 break;
619 case 1:
620 ucontrol->value.integer.value[0] = ldev->switch_on_lineout;
621 break;
622 default:
623 return -ENODEV;
624 }
625 return 0;
626}
627
628static int detect_choice_put(struct snd_kcontrol *kcontrol,
629 struct snd_ctl_elem_value *ucontrol)
630{
631 struct layout_dev *ldev = snd_kcontrol_chip(kcontrol);
632
633 switch (kcontrol->private_value) {
634 case 0:
635 ldev->switch_on_headphone = !!ucontrol->value.integer.value[0];
636 break;
637 case 1:
638 ldev->switch_on_lineout = !!ucontrol->value.integer.value[0];
639 break;
640 default:
641 return -ENODEV;
642 }
643 return 1;
644}
645
646static struct snd_kcontrol_new headphone_detect_choice = {
647 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
648 .name = "Headphone Detect Autoswitch",
649 .info = control_info,
650 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
651 .get = detect_choice_get,
652 .put = detect_choice_put,
653 .private_value = 0,
654};
655
656static struct snd_kcontrol_new lineout_detect_choice = {
657 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
658 .name = "Line-Out Detect Autoswitch",
659 .info = control_info,
660 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
661 .get = detect_choice_get,
662 .put = detect_choice_put,
663 .private_value = 1,
664};
665
666static int detected_get(struct snd_kcontrol *kcontrol,
667 struct snd_ctl_elem_value *ucontrol)
668{
669 struct layout_dev *ldev = snd_kcontrol_chip(kcontrol);
670 int v;
671
672 switch (kcontrol->private_value) {
673 case 0:
674 v = ldev->gpio.methods->get_detect(&ldev->gpio,
675 AOA_NOTIFY_HEADPHONE);
676 break;
677 case 1:
678 v = ldev->gpio.methods->get_detect(&ldev->gpio,
679 AOA_NOTIFY_LINE_OUT);
680 break;
681 default:
682 return -ENODEV;
683 }
684 ucontrol->value.integer.value[0] = v;
685 return 0;
686}
687
688static struct snd_kcontrol_new headphone_detected = {
689 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
690 .name = "Headphone Detected",
691 .info = control_info,
692 .access = SNDRV_CTL_ELEM_ACCESS_READ,
693 .get = detected_get,
694 .private_value = 0,
695};
696
697static struct snd_kcontrol_new lineout_detected = {
698 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
699 .name = "Line-Out Detected",
700 .info = control_info,
701 .access = SNDRV_CTL_ELEM_ACCESS_READ,
702 .get = detected_get,
703 .private_value = 1,
704};
705
706static int check_codec(struct aoa_codec *codec,
707 struct layout_dev *ldev,
708 struct codec_connect_info *cci)
709{
710 u32 *ref;
711 char propname[32];
712 struct codec_connection *cc;
713
714 /* if the codec has a 'codec' node, we require a reference */
715 if (codec->node && (strcmp(codec->node->name, "codec") == 0)) {
716 snprintf(propname, sizeof(propname),
717 "platform-%s-codec-ref", codec->name);
718 ref = (u32*)get_property(ldev->sound, propname, NULL);
719 if (!ref) {
720 printk(KERN_INFO "snd-aoa-fabric-layout: "
721 "required property %s not present\n", propname);
722 return -ENODEV;
723 }
724 if (*ref != codec->node->linux_phandle) {
725 printk(KERN_INFO "snd-aoa-fabric-layout: "
726 "%s doesn't match!\n", propname);
727 return -ENODEV;
728 }
729 } else {
730 if (layouts_list_items != 1) {
731 printk(KERN_INFO "snd-aoa-fabric-layout: "
732 "more than one soundbus, but no references.\n");
733 return -ENODEV;
734 }
735 }
736 codec->soundbus_dev = ldev->sdev;
737 codec->gpio = &ldev->gpio;
738
739 cc = cci->connections;
740 if (!cc)
741 return -EINVAL;
742
743 printk(KERN_INFO "snd-aoa-fabric-layout: can use this codec\n");
744
745 codec->connected = 0;
746 codec->fabric_data = cc;
747
748 while (cc->connected) {
749 codec->connected |= 1<<cc->codec_bit;
750 cc++;
751 }
752
753 return 0;
754}
755
756static int layout_found_codec(struct aoa_codec *codec)
757{
758 struct layout_dev *ldev;
759 int i;
760
761 list_for_each_entry(ldev, &layouts_list, list) {
762 for (i=0; i<MAX_CODECS_PER_BUS; i++) {
763 if (!ldev->layout->codecs[i].name)
764 continue;
765 if (strcmp(ldev->layout->codecs[i].name, codec->name) == 0) {
766 if (check_codec(codec,
767 ldev,
768 &ldev->layout->codecs[i]) == 0)
769 return 0;
770 }
771 }
772 }
773 return -ENODEV;
774}
775
776static void layout_remove_codec(struct aoa_codec *codec)
777{
778 int i;
779 /* here remove the codec from the layout dev's
780 * codec reference */
781
782 codec->soundbus_dev = NULL;
783 codec->gpio = NULL;
784 for (i=0; i<MAX_CODECS_PER_BUS; i++) {
785 }
786}
787
788static void layout_notify(void *data)
789{
790 struct layout_dev_ptr *dptr = data;
791 struct layout_dev *ldev;
792 int v, update;
793 struct snd_kcontrol *detected, *c;
794 struct snd_card *card = aoa_get_card();
795
796 ldev = dptr->ptr;
797 if (data == &ldev->selfptr_headphone) {
798 v = ldev->gpio.methods->get_detect(&ldev->gpio, AOA_NOTIFY_HEADPHONE);
799 detected = ldev->headphone_detected_ctrl;
800 update = ldev->switch_on_headphone;
801 if (update) {
802 ldev->gpio.methods->set_speakers(&ldev->gpio, !v);
803 ldev->gpio.methods->set_headphone(&ldev->gpio, v);
804 ldev->gpio.methods->set_lineout(&ldev->gpio, 0);
805 }
806 } else if (data == &ldev->selfptr_lineout) {
807 v = ldev->gpio.methods->get_detect(&ldev->gpio, AOA_NOTIFY_LINE_OUT);
808 detected = ldev->lineout_detected_ctrl;
809 update = ldev->switch_on_lineout;
810 if (update) {
811 ldev->gpio.methods->set_speakers(&ldev->gpio, !v);
812 ldev->gpio.methods->set_headphone(&ldev->gpio, 0);
813 ldev->gpio.methods->set_lineout(&ldev->gpio, v);
814 }
815 } else
816 return;
817
818 if (detected)
819 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &detected->id);
820 if (update) {
821 c = ldev->headphone_ctrl;
822 if (c)
823 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &c->id);
824 c = ldev->speaker_ctrl;
825 if (c)
826 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &c->id);
827 c = ldev->lineout_ctrl;
828 if (c)
829 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &c->id);
830 }
831}
832
833static void layout_attached_codec(struct aoa_codec *codec)
834{
835 struct codec_connection *cc;
836 struct snd_kcontrol *ctl;
837 int headphones, lineout;
838 struct layout_dev *ldev = layout_device;
839
840 /* need to add this codec to our codec array! */
841
842 cc = codec->fabric_data;
843
844 headphones = codec->gpio->methods->get_detect(codec->gpio,
845 AOA_NOTIFY_HEADPHONE);
846 lineout = codec->gpio->methods->get_detect(codec->gpio,
847 AOA_NOTIFY_LINE_OUT);
848
849 while (cc->connected) {
850 if (cc->connected & CC_SPEAKERS) {
851 if (headphones <= 0 && lineout <= 0)
852 ldev->gpio.methods->set_speakers(codec->gpio, 1);
853 ctl = snd_ctl_new1(&speakers_ctl, codec->gpio);
854 ldev->speaker_ctrl = ctl;
855 aoa_snd_ctl_add(ctl);
856 }
857 if (cc->connected & CC_HEADPHONE) {
858 if (headphones == 1)
859 ldev->gpio.methods->set_headphone(codec->gpio, 1);
860 ctl = snd_ctl_new1(&headphone_ctl, codec->gpio);
861 ldev->headphone_ctrl = ctl;
862 aoa_snd_ctl_add(ctl);
863 ldev->have_headphone_detect =
864 !ldev->gpio.methods
865 ->set_notify(&ldev->gpio,
866 AOA_NOTIFY_HEADPHONE,
867 layout_notify,
868 &ldev->selfptr_headphone);
869 if (ldev->have_headphone_detect) {
870 ctl = snd_ctl_new1(&headphone_detect_choice,
871 ldev);
872 aoa_snd_ctl_add(ctl);
873 ctl = snd_ctl_new1(&headphone_detected,
874 ldev);
875 ldev->headphone_detected_ctrl = ctl;
876 aoa_snd_ctl_add(ctl);
877 }
878 }
879 if (cc->connected & CC_LINEOUT) {
880 if (lineout == 1)
881 ldev->gpio.methods->set_lineout(codec->gpio, 1);
882 ctl = snd_ctl_new1(&lineout_ctl, codec->gpio);
883 if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
884 strlcpy(ctl->id.name,
885 "Headphone Switch", sizeof(ctl->id.name));
886 ldev->lineout_ctrl = ctl;
887 aoa_snd_ctl_add(ctl);
888 ldev->have_lineout_detect =
889 !ldev->gpio.methods
890 ->set_notify(&ldev->gpio,
891 AOA_NOTIFY_LINE_OUT,
892 layout_notify,
893 &ldev->selfptr_lineout);
894 if (ldev->have_lineout_detect) {
895 ctl = snd_ctl_new1(&lineout_detect_choice,
896 ldev);
897 if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
898 strlcpy(ctl->id.name,
899 "Headphone Detect Autoswitch",
900 sizeof(ctl->id.name));
901 aoa_snd_ctl_add(ctl);
902 ctl = snd_ctl_new1(&lineout_detected,
903 ldev);
904 if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
905 strlcpy(ctl->id.name,
906 "Headphone Detected",
907 sizeof(ctl->id.name));
908 ldev->lineout_detected_ctrl = ctl;
909 aoa_snd_ctl_add(ctl);
910 }
911 }
912 cc++;
913 }
914 /* now update initial state */
915 if (ldev->have_headphone_detect)
916 layout_notify(&ldev->selfptr_headphone);
917 if (ldev->have_lineout_detect)
918 layout_notify(&ldev->selfptr_lineout);
919}
920
921static struct aoa_fabric layout_fabric = {
922 .name = "SoundByLayout",
923 .owner = THIS_MODULE,
924 .found_codec = layout_found_codec,
925 .remove_codec = layout_remove_codec,
926 .attached_codec = layout_attached_codec,
927};
928
929static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
930{
931 struct device_node *sound = NULL;
932 unsigned int *layout_id;
933 struct layout *layout;
934 struct layout_dev *ldev = NULL;
935 int err;
936
937 /* hm, currently we can only have one ... */
938 if (layout_device)
939 return -ENODEV;
940
941 /* by breaking out we keep a reference */
942 while ((sound = of_get_next_child(sdev->ofdev.node, sound))) {
943 if (sound->type && strcasecmp(sound->type, "soundchip") == 0)
944 break;
945 }
946 if (!sound) return -ENODEV;
947
948 layout_id = (unsigned int *) get_property(sound, "layout-id", NULL);
949 if (!layout_id)
950 goto outnodev;
951 printk(KERN_INFO "snd-aoa-fabric-layout: found bus with layout %d ", *layout_id);
952
953 layout = find_layout_by_id(*layout_id);
954 if (!layout) {
955 printk("(no idea how to handle)\n");
956 goto outnodev;
957 }
958
959 ldev = kzalloc(sizeof(struct layout_dev), GFP_KERNEL);
960 if (!ldev)
961 goto outnodev;
962
963 layout_device = ldev;
964 ldev->sdev = sdev;
965 ldev->sound = sound;
966 ldev->layout = layout;
967 ldev->gpio.node = sound->parent;
968 switch (layout->layout_id) {
969 case 41: /* that unknown machine no one seems to have */
970 case 51: /* PowerBook5,4 */
971 case 58: /* Mac Mini */
972 ldev->gpio.methods = ftr_gpio_methods;
973 break;
974 default:
975 ldev->gpio.methods = pmf_gpio_methods;
976 }
977 ldev->selfptr_headphone.ptr = ldev;
978 ldev->selfptr_lineout.ptr = ldev;
979 sdev->ofdev.dev.driver_data = ldev;
980
981 printk("(using)\n");
982 list_add(&ldev->list, &layouts_list);
983 layouts_list_items++;
984
985 /* assign these before registering ourselves, so
986 * callbacks that are done during registration
987 * already have the values */
988 sdev->pcmid = ldev->layout->pcmid;
989 if (ldev->layout->busname) {
990 sdev->pcmname = ldev->layout->busname;
991 } else {
992 sdev->pcmname = "Master";
993 }
994
995 ldev->gpio.methods->init(&ldev->gpio);
996
997 err = aoa_fabric_register(&layout_fabric);
998 if (err && err != -EALREADY) {
999 printk(KERN_INFO "snd-aoa-fabric-layout: can't use,"
1000 " another fabric is active!\n");
1001 goto outlistdel;
1002 }
1003
1004 use_layout(layout);
1005 ldev->switch_on_headphone = 1;
1006 ldev->switch_on_lineout = 1;
1007 return 0;
1008 outlistdel:
1009 /* we won't be using these then... */
1010 ldev->gpio.methods->exit(&ldev->gpio);
1011 /* reset if we didn't use it */
1012 sdev->pcmname = NULL;
1013 sdev->pcmid = -1;
1014 list_del(&ldev->list);
1015 layouts_list_items--;
1016 outnodev:
1017 if (sound) of_node_put(sound);
1018 layout_device = NULL;
1019 if (ldev) kfree(ldev);
1020 return -ENODEV;
1021}
1022
1023static int aoa_fabric_layout_remove(struct soundbus_dev *sdev)
1024{
1025 struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
1026 int i;
1027
1028 for (i=0; i<MAX_CODECS_PER_BUS; i++) {
1029 if (ldev->codecs[i]) {
1030 aoa_fabric_unlink_codec(ldev->codecs[i]);
1031 }
1032 ldev->codecs[i] = NULL;
1033 }
1034 list_del(&ldev->list);
1035 layouts_list_items--;
1036 of_node_put(ldev->sound);
1037
1038 ldev->gpio.methods->set_notify(&ldev->gpio,
1039 AOA_NOTIFY_HEADPHONE,
1040 NULL,
1041 NULL);
1042 ldev->gpio.methods->set_notify(&ldev->gpio,
1043 AOA_NOTIFY_LINE_OUT,
1044 NULL,
1045 NULL);
1046
1047 ldev->gpio.methods->exit(&ldev->gpio);
1048 layout_device = NULL;
1049 kfree(ldev);
1050 sdev->pcmid = -1;
1051 sdev->pcmname = NULL;
1052 return 0;
1053}
1054
1055#ifdef CONFIG_PM
1056static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t state)
1057{
1058 struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
1059
1060 printk("aoa_fabric_layout_suspend()\n");
1061
1062 if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
1063 ldev->gpio.methods->all_amps_off(&ldev->gpio);
1064
1065 return 0;
1066}
1067
1068static int aoa_fabric_layout_resume(struct soundbus_dev *sdev)
1069{
1070 struct layout_dev *ldev = sdev->ofdev.dev.driver_data;
1071
1072 printk("aoa_fabric_layout_resume()\n");
1073
1074 if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off)
1075 ldev->gpio.methods->all_amps_restore(&ldev->gpio);
1076
1077 return 0;
1078}
1079#endif
1080
1081static struct soundbus_driver aoa_soundbus_driver = {
1082 .name = "snd_aoa_soundbus_drv",
1083 .owner = THIS_MODULE,
1084 .probe = aoa_fabric_layout_probe,
1085 .remove = aoa_fabric_layout_remove,
1086#ifdef CONFIG_PM
1087 .suspend = aoa_fabric_layout_suspend,
1088 .resume = aoa_fabric_layout_resume,
1089#endif
1090};
1091
1092static int __init aoa_fabric_layout_init(void)
1093{
1094 int err;
1095
1096 err = soundbus_register_driver(&aoa_soundbus_driver);
1097 if (err)
1098 return err;
1099 return 0;
1100}
1101
1102static void __exit aoa_fabric_layout_exit(void)
1103{
1104 soundbus_unregister_driver(&aoa_soundbus_driver);
1105 aoa_fabric_unregister(&layout_fabric);
1106}
1107
1108module_init(aoa_fabric_layout_init);
1109module_exit(aoa_fabric_layout_exit);
diff --git a/sound/aoa/soundbus/Kconfig b/sound/aoa/soundbus/Kconfig
new file mode 100644
index 000000000000..d532d27a9f54
--- /dev/null
+++ b/sound/aoa/soundbus/Kconfig
@@ -0,0 +1,14 @@
1config SND_AOA_SOUNDBUS
2 tristate "Apple Soundbus support"
3 depends on SOUND && SND_PCM && EXPERIMENTAL
4 ---help---
5 This option enables the generic driver for the soundbus
6 support on Apple machines.
7
8 It is required for the sound bus implementations.
9
10config SND_AOA_SOUNDBUS_I2S
11 tristate "I2S bus support"
12 depends on SND_AOA_SOUNDBUS && PCI
13 ---help---
14 This option enables support for Apple I2S busses.
diff --git a/sound/aoa/soundbus/Makefile b/sound/aoa/soundbus/Makefile
new file mode 100644
index 000000000000..0e61f5aa06b5
--- /dev/null
+++ b/sound/aoa/soundbus/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_SND_AOA_SOUNDBUS) += snd-aoa-soundbus.o
2snd-aoa-soundbus-objs := core.o sysfs.o
3obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += i2sbus/
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c
new file mode 100644
index 000000000000..abe84a76c835
--- /dev/null
+++ b/sound/aoa/soundbus/core.c
@@ -0,0 +1,250 @@
1/*
2 * soundbus
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#include <linux/module.h>
10#include "soundbus.h"
11
12MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
13MODULE_LICENSE("GPL");
14MODULE_DESCRIPTION("Apple Soundbus");
15
16struct soundbus_dev *soundbus_dev_get(struct soundbus_dev *dev)
17{
18 struct device *tmp;
19
20 if (!dev)
21 return NULL;
22 tmp = get_device(&dev->ofdev.dev);
23 if (tmp)
24 return to_soundbus_device(tmp);
25 else
26 return NULL;
27}
28EXPORT_SYMBOL_GPL(soundbus_dev_get);
29
30void soundbus_dev_put(struct soundbus_dev *dev)
31{
32 if (dev)
33 put_device(&dev->ofdev.dev);
34}
35EXPORT_SYMBOL_GPL(soundbus_dev_put);
36
37static int soundbus_probe(struct device *dev)
38{
39 int error = -ENODEV;
40 struct soundbus_driver *drv;
41 struct soundbus_dev *soundbus_dev;
42
43 drv = to_soundbus_driver(dev->driver);
44 soundbus_dev = to_soundbus_device(dev);
45
46 if (!drv->probe)
47 return error;
48
49 soundbus_dev_get(soundbus_dev);
50
51 error = drv->probe(soundbus_dev);
52 if (error)
53 soundbus_dev_put(soundbus_dev);
54
55 return error;
56}
57
58
59static int soundbus_uevent(struct device *dev, char **envp, int num_envp,
60 char *buffer, int buffer_size)
61{
62 struct soundbus_dev * soundbus_dev;
63 struct of_device * of;
64 char *scratch, *compat, *compat2;
65 int i = 0;
66 int length, cplen, cplen2, seen = 0;
67
68 if (!dev)
69 return -ENODEV;
70
71 soundbus_dev = to_soundbus_device(dev);
72 if (!soundbus_dev)
73 return -ENODEV;
74
75 of = &soundbus_dev->ofdev;
76
77 /* stuff we want to pass to /sbin/hotplug */
78 envp[i++] = scratch = buffer;
79 length = scnprintf (scratch, buffer_size, "OF_NAME=%s", of->node->name);
80 ++length;
81 buffer_size -= length;
82 if ((buffer_size <= 0) || (i >= num_envp))
83 return -ENOMEM;
84 scratch += length;
85
86 envp[i++] = scratch;
87 length = scnprintf (scratch, buffer_size, "OF_TYPE=%s", of->node->type);
88 ++length;
89 buffer_size -= length;
90 if ((buffer_size <= 0) || (i >= num_envp))
91 return -ENOMEM;
92 scratch += length;
93
94 /* Since the compatible field can contain pretty much anything
95 * it's not really legal to split it out with commas. We split it
96 * up using a number of environment variables instead. */
97
98 compat = (char *) get_property(of->node, "compatible", &cplen);
99 compat2 = compat;
100 cplen2= cplen;
101 while (compat && cplen > 0) {
102 envp[i++] = scratch;
103 length = scnprintf (scratch, buffer_size,
104 "OF_COMPATIBLE_%d=%s", seen, compat);
105 ++length;
106 buffer_size -= length;
107 if ((buffer_size <= 0) || (i >= num_envp))
108 return -ENOMEM;
109 scratch += length;
110 length = strlen (compat) + 1;
111 compat += length;
112 cplen -= length;
113 seen++;
114 }
115
116 envp[i++] = scratch;
117 length = scnprintf (scratch, buffer_size, "OF_COMPATIBLE_N=%d", seen);
118 ++length;
119 buffer_size -= length;
120 if ((buffer_size <= 0) || (i >= num_envp))
121 return -ENOMEM;
122 scratch += length;
123
124 envp[i++] = scratch;
125 length = scnprintf (scratch, buffer_size, "MODALIAS=%s",
126 soundbus_dev->modalias);
127
128 buffer_size -= length;
129 if ((buffer_size <= 0) || (i >= num_envp))
130 return -ENOMEM;
131
132 envp[i] = NULL;
133
134 return 0;
135}
136
137static int soundbus_device_remove(struct device *dev)
138{
139 struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
140 struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
141
142 if (dev->driver && drv->remove)
143 drv->remove(soundbus_dev);
144 soundbus_dev_put(soundbus_dev);
145
146 return 0;
147}
148
149static void soundbus_device_shutdown(struct device *dev)
150{
151 struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
152 struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
153
154 if (dev->driver && drv->shutdown)
155 drv->shutdown(soundbus_dev);
156}
157
158#ifdef CONFIG_PM
159
160static int soundbus_device_suspend(struct device *dev, pm_message_t state)
161{
162 struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
163 struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
164
165 if (dev->driver && drv->suspend)
166 return drv->suspend(soundbus_dev, state);
167 return 0;
168}
169
170static int soundbus_device_resume(struct device * dev)
171{
172 struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
173 struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
174
175 if (dev->driver && drv->resume)
176 return drv->resume(soundbus_dev);
177 return 0;
178}
179
180#endif /* CONFIG_PM */
181
182extern struct device_attribute soundbus_dev_attrs[];
183
184static struct bus_type soundbus_bus_type = {
185 .name = "aoa-soundbus",
186 .probe = soundbus_probe,
187 .uevent = soundbus_uevent,
188 .remove = soundbus_device_remove,
189 .shutdown = soundbus_device_shutdown,
190#ifdef CONFIG_PM
191 .suspend = soundbus_device_suspend,
192 .resume = soundbus_device_resume,
193#endif
194 .dev_attrs = soundbus_dev_attrs,
195};
196
197static int __init soundbus_init(void)
198{
199 return bus_register(&soundbus_bus_type);
200}
201
202static void __exit soundbus_exit(void)
203{
204 bus_unregister(&soundbus_bus_type);
205}
206
207int soundbus_add_one(struct soundbus_dev *dev)
208{
209 static int devcount;
210
211 /* sanity checks */
212 if (!dev->attach_codec ||
213 !dev->ofdev.node ||
214 dev->pcmname ||
215 dev->pcmid != -1) {
216 printk(KERN_ERR "soundbus: adding device failed sanity check!\n");
217 return -EINVAL;
218 }
219
220 snprintf(dev->ofdev.dev.bus_id, BUS_ID_SIZE, "soundbus:%x", ++devcount);
221 dev->ofdev.dev.bus = &soundbus_bus_type;
222 return of_device_register(&dev->ofdev);
223}
224EXPORT_SYMBOL_GPL(soundbus_add_one);
225
226void soundbus_remove_one(struct soundbus_dev *dev)
227{
228 of_device_unregister(&dev->ofdev);
229}
230EXPORT_SYMBOL_GPL(soundbus_remove_one);
231
232int soundbus_register_driver(struct soundbus_driver *drv)
233{
234 /* initialize common driver fields */
235 drv->driver.name = drv->name;
236 drv->driver.bus = &soundbus_bus_type;
237
238 /* register with core */
239 return driver_register(&drv->driver);
240}
241EXPORT_SYMBOL_GPL(soundbus_register_driver);
242
243void soundbus_unregister_driver(struct soundbus_driver *drv)
244{
245 driver_unregister(&drv->driver);
246}
247EXPORT_SYMBOL_GPL(soundbus_unregister_driver);
248
249module_init(soundbus_init);
250module_exit(soundbus_exit);
diff --git a/sound/aoa/soundbus/i2sbus/Makefile b/sound/aoa/soundbus/i2sbus/Makefile
new file mode 100644
index 000000000000..e57a5cf65655
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/Makefile
@@ -0,0 +1,2 @@
1obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += snd-aoa-i2sbus.o
2snd-aoa-i2sbus-objs := i2sbus-core.o i2sbus-pcm.o i2sbus-control.o
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-control.c b/sound/aoa/soundbus/i2sbus/i2sbus-control.c
new file mode 100644
index 000000000000..f50407952d3c
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-control.c
@@ -0,0 +1,192 @@
1/*
2 * i2sbus driver -- bus control routines
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#include <asm/io.h>
10#include <linux/delay.h>
11#include <asm/prom.h>
12#include <asm/macio.h>
13#include <asm/pmac_feature.h>
14#include <asm/pmac_pfunc.h>
15#include "i2sbus.h"
16
17int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c)
18{
19 *c = kzalloc(sizeof(struct i2sbus_control), GFP_KERNEL);
20 if (!*c)
21 return -ENOMEM;
22
23 INIT_LIST_HEAD(&(*c)->list);
24
25 if (of_address_to_resource(dev->ofdev.node, 0, &(*c)->rsrc))
26 goto err;
27 /* we really should be using feature calls instead of mapping
28 * these registers. It's safe for now since no one else is
29 * touching them... */
30 (*c)->controlregs = ioremap((*c)->rsrc.start,
31 sizeof(struct i2s_control_regs));
32 if (!(*c)->controlregs)
33 goto err;
34
35 return 0;
36 err:
37 kfree(*c);
38 *c = NULL;
39 return -ENODEV;
40}
41
42void i2sbus_control_destroy(struct i2sbus_control *c)
43{
44 iounmap(c->controlregs);
45 kfree(c);
46}
47
48/* this is serialised externally */
49int i2sbus_control_add_dev(struct i2sbus_control *c,
50 struct i2sbus_dev *i2sdev)
51{
52 struct device_node *np;
53
54 np = i2sdev->sound.ofdev.node;
55 i2sdev->enable = pmf_find_function(np, "enable");
56 i2sdev->cell_enable = pmf_find_function(np, "cell-enable");
57 i2sdev->clock_enable = pmf_find_function(np, "clock-enable");
58 i2sdev->cell_disable = pmf_find_function(np, "cell-disable");
59 i2sdev->clock_disable = pmf_find_function(np, "clock-disable");
60
61 /* if the bus number is not 0 or 1 we absolutely need to use
62 * the platform functions -- there's nothing in Darwin that
63 * would allow seeing a system behind what the FCRs are then,
64 * and I don't want to go parsing a bunch of platform functions
65 * by hand to try finding a system... */
66 if (i2sdev->bus_number != 0 && i2sdev->bus_number != 1 &&
67 (!i2sdev->enable ||
68 !i2sdev->cell_enable || !i2sdev->clock_enable ||
69 !i2sdev->cell_disable || !i2sdev->clock_disable)) {
70 pmf_put_function(i2sdev->enable);
71 pmf_put_function(i2sdev->cell_enable);
72 pmf_put_function(i2sdev->clock_enable);
73 pmf_put_function(i2sdev->cell_disable);
74 pmf_put_function(i2sdev->clock_disable);
75 return -ENODEV;
76 }
77
78 list_add(&i2sdev->item, &c->list);
79
80 return 0;
81}
82
83void i2sbus_control_remove_dev(struct i2sbus_control *c,
84 struct i2sbus_dev *i2sdev)
85{
86 /* this is serialised externally */
87 list_del(&i2sdev->item);
88 if (list_empty(&c->list))
89 i2sbus_control_destroy(c);
90}
91
92int i2sbus_control_enable(struct i2sbus_control *c,
93 struct i2sbus_dev *i2sdev)
94{
95 struct pmf_args args = { .count = 0 };
96 int cc;
97
98 if (i2sdev->enable)
99 return pmf_call_one(i2sdev->enable, &args);
100
101 switch (i2sdev->bus_number) {
102 case 0:
103 cc = in_le32(&c->controlregs->cell_control);
104 out_le32(&c->controlregs->cell_control, cc | CTRL_CLOCK_INTF_0_ENABLE);
105 break;
106 case 1:
107 cc = in_le32(&c->controlregs->cell_control);
108 out_le32(&c->controlregs->cell_control, cc | CTRL_CLOCK_INTF_1_ENABLE);
109 break;
110 default:
111 return -ENODEV;
112 }
113 return 0;
114}
115
116int i2sbus_control_cell(struct i2sbus_control *c,
117 struct i2sbus_dev *i2sdev,
118 int enable)
119{
120 struct pmf_args args = { .count = 0 };
121 int cc;
122
123 switch (enable) {
124 case 0:
125 if (i2sdev->cell_disable)
126 return pmf_call_one(i2sdev->cell_disable, &args);
127 break;
128 case 1:
129 if (i2sdev->cell_enable)
130 return pmf_call_one(i2sdev->cell_enable, &args);
131 break;
132 default:
133 printk(KERN_ERR "i2sbus: INVALID CELL ENABLE VALUE\n");
134 return -ENODEV;
135 }
136 switch (i2sdev->bus_number) {
137 case 0:
138 cc = in_le32(&c->controlregs->cell_control);
139 cc &= ~CTRL_CLOCK_CELL_0_ENABLE;
140 cc |= enable * CTRL_CLOCK_CELL_0_ENABLE;
141 out_le32(&c->controlregs->cell_control, cc);
142 break;
143 case 1:
144 cc = in_le32(&c->controlregs->cell_control);
145 cc &= ~CTRL_CLOCK_CELL_1_ENABLE;
146 cc |= enable * CTRL_CLOCK_CELL_1_ENABLE;
147 out_le32(&c->controlregs->cell_control, cc);
148 break;
149 default:
150 return -ENODEV;
151 }
152 return 0;
153}
154
155int i2sbus_control_clock(struct i2sbus_control *c,
156 struct i2sbus_dev *i2sdev,
157 int enable)
158{
159 struct pmf_args args = { .count = 0 };
160 int cc;
161
162 switch (enable) {
163 case 0:
164 if (i2sdev->clock_disable)
165 return pmf_call_one(i2sdev->clock_disable, &args);
166 break;
167 case 1:
168 if (i2sdev->clock_enable)
169 return pmf_call_one(i2sdev->clock_enable, &args);
170 break;
171 default:
172 printk(KERN_ERR "i2sbus: INVALID CLOCK ENABLE VALUE\n");
173 return -ENODEV;
174 }
175 switch (i2sdev->bus_number) {
176 case 0:
177 cc = in_le32(&c->controlregs->cell_control);
178 cc &= ~CTRL_CLOCK_CLOCK_0_ENABLE;
179 cc |= enable * CTRL_CLOCK_CLOCK_0_ENABLE;
180 out_le32(&c->controlregs->cell_control, cc);
181 break;
182 case 1:
183 cc = in_le32(&c->controlregs->cell_control);
184 cc &= ~CTRL_CLOCK_CLOCK_1_ENABLE;
185 cc |= enable * CTRL_CLOCK_CLOCK_1_ENABLE;
186 out_le32(&c->controlregs->cell_control, cc);
187 break;
188 default:
189 return -ENODEV;
190 }
191 return 0;
192}
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-control.h b/sound/aoa/soundbus/i2sbus/i2sbus-control.h
new file mode 100644
index 000000000000..bb05550f730b
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-control.h
@@ -0,0 +1,37 @@
1/*
2 * i2sbus driver -- bus register definitions
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#ifndef __I2SBUS_CONTROLREGS_H
9#define __I2SBUS_CONTROLREGS_H
10
11/* i2s control registers, at least what we know about them */
12
13#define __PAD(m,n) u8 __pad##m[n]
14#define _PAD(line, n) __PAD(line, n)
15#define PAD(n) _PAD(__LINE__, (n))
16struct i2s_control_regs {
17 PAD(0x38);
18 __le32 fcr0; /* 0x38 (unknown) */
19 __le32 cell_control; /* 0x3c (fcr1) */
20 __le32 fcr2; /* 0x40 (unknown) */
21 __le32 fcr3; /* 0x44 (fcr3) */
22 __le32 clock_control; /* 0x48 (unknown) */
23 PAD(4);
24 /* total size: 0x50 bytes */
25} __attribute__((__packed__));
26
27#define CTRL_CLOCK_CELL_0_ENABLE (1<<10)
28#define CTRL_CLOCK_CLOCK_0_ENABLE (1<<12)
29#define CTRL_CLOCK_SWRESET_0 (1<<11)
30#define CTRL_CLOCK_INTF_0_ENABLE (1<<13)
31
32#define CTRL_CLOCK_CELL_1_ENABLE (1<<17)
33#define CTRL_CLOCK_CLOCK_1_ENABLE (1<<18)
34#define CTRL_CLOCK_SWRESET_1 (1<<19)
35#define CTRL_CLOCK_INTF_1_ENABLE (1<<20)
36
37#endif /* __I2SBUS_CONTROLREGS_H */
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
new file mode 100644
index 000000000000..f268dacdaa00
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
@@ -0,0 +1,387 @@
1/*
2 * i2sbus driver
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#include <linux/module.h>
10#include <asm/macio.h>
11#include <asm/dbdma.h>
12#include <linux/pci.h>
13#include <linux/interrupt.h>
14#include <sound/driver.h>
15#include <sound/core.h>
16#include <linux/dma-mapping.h>
17#include "../soundbus.h"
18#include "i2sbus.h"
19
20MODULE_LICENSE("GPL");
21MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
22MODULE_DESCRIPTION("Apple Soundbus: I2S support");
23/* for auto-loading, declare that we handle this weird
24 * string that macio puts into the relevant device */
25MODULE_ALIAS("of:Ni2sTi2sC");
26
27static struct of_device_id i2sbus_match[] = {
28 { .name = "i2s" },
29 { }
30};
31
32static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
33 struct dbdma_command_mem *r,
34 int numcmds)
35{
36 /* one more for rounding */
37 r->size = (numcmds+1) * sizeof(struct dbdma_cmd);
38 /* We use the PCI APIs for now until the generic one gets fixed
39 * enough or until we get some macio-specific versions
40 */
41 r->space = dma_alloc_coherent(
42 &macio_get_pci_dev(i2sdev->macio)->dev,
43 r->size,
44 &r->bus_addr,
45 GFP_KERNEL);
46
47 if (!r->space) return -ENOMEM;
48
49 memset(r->space, 0, r->size);
50 r->cmds = (void*)DBDMA_ALIGN(r->space);
51 r->bus_cmd_start = r->bus_addr +
52 (dma_addr_t)((char*)r->cmds - (char*)r->space);
53
54 return 0;
55}
56
57static void free_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
58 struct dbdma_command_mem *r)
59{
60 if (!r->space) return;
61
62 dma_free_coherent(&macio_get_pci_dev(i2sdev->macio)->dev,
63 r->size, r->space, r->bus_addr);
64}
65
66static void i2sbus_release_dev(struct device *dev)
67{
68 struct i2sbus_dev *i2sdev;
69 int i;
70
71 i2sdev = container_of(dev, struct i2sbus_dev, sound.ofdev.dev);
72
73 if (i2sdev->intfregs) iounmap(i2sdev->intfregs);
74 if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma);
75 if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma);
76 for (i=0;i<3;i++)
77 if (i2sdev->allocated_resource[i])
78 release_and_free_resource(i2sdev->allocated_resource[i]);
79 free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring);
80 free_dbdma_descriptor_ring(i2sdev, &i2sdev->in.dbdma_ring);
81 for (i=0;i<3;i++)
82 free_irq(i2sdev->interrupts[i], i2sdev);
83 i2sbus_control_remove_dev(i2sdev->control, i2sdev);
84 mutex_destroy(&i2sdev->lock);
85 kfree(i2sdev);
86}
87
88static irqreturn_t i2sbus_bus_intr(int irq, void *devid, struct pt_regs *regs)
89{
90 struct i2sbus_dev *dev = devid;
91 u32 intreg;
92
93 spin_lock(&dev->low_lock);
94 intreg = in_le32(&dev->intfregs->intr_ctl);
95
96 /* acknowledge interrupt reasons */
97 out_le32(&dev->intfregs->intr_ctl, intreg);
98
99 spin_unlock(&dev->low_lock);
100
101 return IRQ_HANDLED;
102}
103
104static int force;
105module_param(force, int, 0444);
106MODULE_PARM_DESC(force, "Force loading i2sbus even when"
107 " no layout-id property is present");
108
109/* FIXME: look at device node refcounting */
110static int i2sbus_add_dev(struct macio_dev *macio,
111 struct i2sbus_control *control,
112 struct device_node *np)
113{
114 struct i2sbus_dev *dev;
115 struct device_node *child = NULL, *sound = NULL;
116 int i;
117 static const char *rnames[] = { "i2sbus: %s (control)",
118 "i2sbus: %s (tx)",
119 "i2sbus: %s (rx)" };
120 static irqreturn_t (*ints[])(int irq, void *devid,
121 struct pt_regs *regs) = {
122 i2sbus_bus_intr,
123 i2sbus_tx_intr,
124 i2sbus_rx_intr
125 };
126
127 if (strlen(np->name) != 5)
128 return 0;
129 if (strncmp(np->name, "i2s-", 4))
130 return 0;
131
132 if (np->n_intrs != 3)
133 return 0;
134
135 dev = kzalloc(sizeof(struct i2sbus_dev), GFP_KERNEL);
136 if (!dev)
137 return 0;
138
139 i = 0;
140 while ((child = of_get_next_child(np, child))) {
141 if (strcmp(child->name, "sound") == 0) {
142 i++;
143 sound = child;
144 }
145 }
146 if (i == 1) {
147 u32 *layout_id;
148 layout_id = (u32*) get_property(sound, "layout-id", NULL);
149 if (layout_id) {
150 snprintf(dev->sound.modalias, 32,
151 "sound-layout-%d", *layout_id);
152 force = 1;
153 }
154 }
155 /* for the time being, until we can handle non-layout-id
156 * things in some fabric, refuse to attach if there is no
157 * layout-id property or we haven't been forced to attach.
158 * When there are two i2s busses and only one has a layout-id,
159 * then this depends on the order, but that isn't important
160 * either as the second one in that case is just a modem. */
161 if (!force) {
162 kfree(dev);
163 return -ENODEV;
164 }
165
166 mutex_init(&dev->lock);
167 spin_lock_init(&dev->low_lock);
168 dev->sound.ofdev.node = np;
169 dev->sound.ofdev.dma_mask = macio->ofdev.dma_mask;
170 dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.dma_mask;
171 dev->sound.ofdev.dev.parent = &macio->ofdev.dev;
172 dev->sound.ofdev.dev.release = i2sbus_release_dev;
173 dev->sound.attach_codec = i2sbus_attach_codec;
174 dev->sound.detach_codec = i2sbus_detach_codec;
175 dev->sound.pcmid = -1;
176 dev->macio = macio;
177 dev->control = control;
178 dev->bus_number = np->name[4] - 'a';
179 INIT_LIST_HEAD(&dev->sound.codec_list);
180
181 for (i=0;i<3;i++) {
182 dev->interrupts[i] = -1;
183 snprintf(dev->rnames[i], sizeof(dev->rnames[i]), rnames[i], np->name);
184 }
185 for (i=0;i<3;i++) {
186 if (request_irq(np->intrs[i].line, ints[i], 0, dev->rnames[i], dev))
187 goto err;
188 dev->interrupts[i] = np->intrs[i].line;
189 }
190
191 for (i=0;i<3;i++) {
192 if (of_address_to_resource(np, i, &dev->resources[i]))
193 goto err;
194 /* if only we could use our resource dev->resources[i]...
195 * but request_resource doesn't know about parents and
196 * contained resources... */
197 dev->allocated_resource[i] =
198 request_mem_region(dev->resources[i].start,
199 dev->resources[i].end -
200 dev->resources[i].start + 1,
201 dev->rnames[i]);
202 if (!dev->allocated_resource[i]) {
203 printk(KERN_ERR "i2sbus: failed to claim resource %d!\n", i);
204 goto err;
205 }
206 }
207 /* should do sanity checking here about length of them */
208 dev->intfregs = ioremap(dev->resources[0].start,
209 dev->resources[0].end-dev->resources[0].start+1);
210 dev->out.dbdma = ioremap(dev->resources[1].start,
211 dev->resources[1].end-dev->resources[1].start+1);
212 dev->in.dbdma = ioremap(dev->resources[2].start,
213 dev->resources[2].end-dev->resources[2].start+1);
214 if (!dev->intfregs || !dev->out.dbdma || !dev->in.dbdma)
215 goto err;
216
217 if (alloc_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring,
218 MAX_DBDMA_COMMANDS))
219 goto err;
220 if (alloc_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring,
221 MAX_DBDMA_COMMANDS))
222 goto err;
223
224 if (i2sbus_control_add_dev(dev->control, dev)) {
225 printk(KERN_ERR "i2sbus: control layer didn't like bus\n");
226 goto err;
227 }
228
229 if (soundbus_add_one(&dev->sound)) {
230 printk(KERN_DEBUG "i2sbus: device registration error!\n");
231 goto err;
232 }
233
234 /* enable this cell */
235 i2sbus_control_cell(dev->control, dev, 1);
236 i2sbus_control_enable(dev->control, dev);
237 i2sbus_control_clock(dev->control, dev, 1);
238
239 return 1;
240 err:
241 for (i=0;i<3;i++)
242 if (dev->interrupts[i] != -1)
243 free_irq(dev->interrupts[i], dev);
244 free_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring);
245 free_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring);
246 if (dev->intfregs) iounmap(dev->intfregs);
247 if (dev->out.dbdma) iounmap(dev->out.dbdma);
248 if (dev->in.dbdma) iounmap(dev->in.dbdma);
249 for (i=0;i<3;i++)
250 if (dev->allocated_resource[i])
251 release_and_free_resource(dev->allocated_resource[i]);
252 mutex_destroy(&dev->lock);
253 kfree(dev);
254 return 0;
255}
256
257static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match)
258{
259 struct device_node *np = NULL;
260 int got = 0, err;
261 struct i2sbus_control *control = NULL;
262
263 err = i2sbus_control_init(dev, &control);
264 if (err)
265 return err;
266 if (!control) {
267 printk(KERN_ERR "i2sbus_control_init API breakage\n");
268 return -ENODEV;
269 }
270
271 while ((np = of_get_next_child(dev->ofdev.node, np))) {
272 if (device_is_compatible(np, "i2sbus") ||
273 device_is_compatible(np, "i2s-modem")) {
274 got += i2sbus_add_dev(dev, control, np);
275 }
276 }
277
278 if (!got) {
279 /* found none, clean up */
280 i2sbus_control_destroy(control);
281 return -ENODEV;
282 }
283
284 dev->ofdev.dev.driver_data = control;
285
286 return 0;
287}
288
289static int i2sbus_remove(struct macio_dev* dev)
290{
291 struct i2sbus_control *control = dev->ofdev.dev.driver_data;
292 struct i2sbus_dev *i2sdev, *tmp;
293
294 list_for_each_entry_safe(i2sdev, tmp, &control->list, item)
295 soundbus_remove_one(&i2sdev->sound);
296
297 return 0;
298}
299
300#ifdef CONFIG_PM
301static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
302{
303 struct i2sbus_control *control = dev->ofdev.dev.driver_data;
304 struct codec_info_item *cii;
305 struct i2sbus_dev* i2sdev;
306 int err, ret = 0;
307
308 list_for_each_entry(i2sdev, &control->list, item) {
309 /* Notify Alsa */
310 if (i2sdev->sound.pcm) {
311 /* Suspend PCM streams */
312 snd_pcm_suspend_all(i2sdev->sound.pcm);
313 /* Probably useless as we handle
314 * power transitions ourselves */
315 snd_power_change_state(i2sdev->sound.pcm->card,
316 SNDRV_CTL_POWER_D3hot);
317 }
318 /* Notify codecs */
319 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
320 err = 0;
321 if (cii->codec->suspend)
322 err = cii->codec->suspend(cii, state);
323 if (err)
324 ret = err;
325 }
326 }
327 return ret;
328}
329
330static int i2sbus_resume(struct macio_dev* dev)
331{
332 struct i2sbus_control *control = dev->ofdev.dev.driver_data;
333 struct codec_info_item *cii;
334 struct i2sbus_dev* i2sdev;
335 int err, ret = 0;
336
337 list_for_each_entry(i2sdev, &control->list, item) {
338 /* Notify codecs so they can re-initialize */
339 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
340 err = 0;
341 if (cii->codec->resume)
342 err = cii->codec->resume(cii);
343 if (err)
344 ret = err;
345 }
346 /* Notify Alsa */
347 if (i2sdev->sound.pcm) {
348 /* Same comment as above, probably useless */
349 snd_power_change_state(i2sdev->sound.pcm->card,
350 SNDRV_CTL_POWER_D0);
351 }
352 }
353
354 return ret;
355}
356#endif /* CONFIG_PM */
357
358static int i2sbus_shutdown(struct macio_dev* dev)
359{
360 return 0;
361}
362
363static struct macio_driver i2sbus_drv = {
364 .name = "soundbus-i2s",
365 .owner = THIS_MODULE,
366 .match_table = i2sbus_match,
367 .probe = i2sbus_probe,
368 .remove = i2sbus_remove,
369#ifdef CONFIG_PM
370 .suspend = i2sbus_suspend,
371 .resume = i2sbus_resume,
372#endif
373 .shutdown = i2sbus_shutdown,
374};
375
376static int __init soundbus_i2sbus_init(void)
377{
378 return macio_register_driver(&i2sbus_drv);
379}
380
381static void __exit soundbus_i2sbus_exit(void)
382{
383 macio_unregister_driver(&i2sbus_drv);
384}
385
386module_init(soundbus_i2sbus_init);
387module_exit(soundbus_i2sbus_exit);
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-interface.h b/sound/aoa/soundbus/i2sbus/i2sbus-interface.h
new file mode 100644
index 000000000000..c6b5f5452d20
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-interface.h
@@ -0,0 +1,187 @@
1/*
2 * i2sbus driver -- interface register definitions
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#ifndef __I2SBUS_INTERFACE_H
9#define __I2SBUS_INTERFACE_H
10
11/* i2s bus control registers, at least what we know about them */
12
13#define __PAD(m,n) u8 __pad##m[n]
14#define _PAD(line, n) __PAD(line, n)
15#define PAD(n) _PAD(__LINE__, (n))
16struct i2s_interface_regs {
17 __le32 intr_ctl; /* 0x00 */
18 PAD(12);
19 __le32 serial_format; /* 0x10 */
20 PAD(12);
21 __le32 codec_msg_out; /* 0x20 */
22 PAD(12);
23 __le32 codec_msg_in; /* 0x30 */
24 PAD(12);
25 __le32 frame_count; /* 0x40 */
26 PAD(12);
27 __le32 frame_match; /* 0x50 */
28 PAD(12);
29 __le32 data_word_sizes; /* 0x60 */
30 PAD(12);
31 __le32 peak_level_sel; /* 0x70 */
32 PAD(12);
33 __le32 peak_level_in0; /* 0x80 */
34 PAD(12);
35 __le32 peak_level_in1; /* 0x90 */
36 PAD(12);
37 /* total size: 0x100 bytes */
38} __attribute__((__packed__));
39
40/* interrupt register is just a bitfield with
41 * interrupt enable and pending bits */
42#define I2S_REG_INTR_CTL 0x00
43# define I2S_INT_FRAME_COUNT (1<<31)
44# define I2S_PENDING_FRAME_COUNT (1<<30)
45# define I2S_INT_MESSAGE_FLAG (1<<29)
46# define I2S_PENDING_MESSAGE_FLAG (1<<28)
47# define I2S_INT_NEW_PEAK (1<<27)
48# define I2S_PENDING_NEW_PEAK (1<<26)
49# define I2S_INT_CLOCKS_STOPPED (1<<25)
50# define I2S_PENDING_CLOCKS_STOPPED (1<<24)
51# define I2S_INT_EXTERNAL_SYNC_ERROR (1<<23)
52# define I2S_PENDING_EXTERNAL_SYNC_ERROR (1<<22)
53# define I2S_INT_EXTERNAL_SYNC_OK (1<<21)
54# define I2S_PENDING_EXTERNAL_SYNC_OK (1<<20)
55# define I2S_INT_NEW_SAMPLE_RATE (1<<19)
56# define I2S_PENDING_NEW_SAMPLE_RATE (1<<18)
57# define I2S_INT_STATUS_FLAG (1<<17)
58# define I2S_PENDING_STATUS_FLAG (1<<16)
59
60/* serial format register is more interesting :)
61 * It contains:
62 * - clock source
63 * - MClk divisor
64 * - SClk divisor
65 * - SClk master flag
66 * - serial format (sony, i2s 64x, i2s 32x, dav, silabs)
67 * - external sample frequency interrupt (don't understand)
68 * - external sample frequency
69 */
70#define I2S_REG_SERIAL_FORMAT 0x10
71/* clock source. You get either 18.432, 45.1584 or 49.1520 MHz */
72# define I2S_SF_CLOCK_SOURCE_SHIFT 30
73# define I2S_SF_CLOCK_SOURCE_MASK (3<<I2S_SF_CLOCK_SOURCE_SHIFT)
74# define I2S_SF_CLOCK_SOURCE_18MHz (0<<I2S_SF_CLOCK_SOURCE_SHIFT)
75# define I2S_SF_CLOCK_SOURCE_45MHz (1<<I2S_SF_CLOCK_SOURCE_SHIFT)
76# define I2S_SF_CLOCK_SOURCE_49MHz (2<<I2S_SF_CLOCK_SOURCE_SHIFT)
77/* also, let's define the exact clock speeds here, in Hz */
78#define I2S_CLOCK_SPEED_18MHz 18432000
79#define I2S_CLOCK_SPEED_45MHz 45158400
80#define I2S_CLOCK_SPEED_49MHz 49152000
81/* MClk is the clock that drives the codec, usually called its 'system clock'.
82 * It is derived by taking only every 'divisor' tick of the clock.
83 */
84# define I2S_SF_MCLKDIV_SHIFT 24
85# define I2S_SF_MCLKDIV_MASK (0x1F<<I2S_SF_MCLKDIV_SHIFT)
86# define I2S_SF_MCLKDIV_1 (0x14<<I2S_SF_MCLKDIV_SHIFT)
87# define I2S_SF_MCLKDIV_3 (0x13<<I2S_SF_MCLKDIV_SHIFT)
88# define I2S_SF_MCLKDIV_5 (0x12<<I2S_SF_MCLKDIV_SHIFT)
89# define I2S_SF_MCLKDIV_14 (0x0E<<I2S_SF_MCLKDIV_SHIFT)
90# define I2S_SF_MCLKDIV_OTHER(div) (((div/2-1)<<I2S_SF_MCLKDIV_SHIFT)&I2S_SF_MCLKDIV_MASK)
91static inline int i2s_sf_mclkdiv(int div, int *out)
92{
93 int d;
94
95 switch(div) {
96 case 1: *out |= I2S_SF_MCLKDIV_1; return 0;
97 case 3: *out |= I2S_SF_MCLKDIV_3; return 0;
98 case 5: *out |= I2S_SF_MCLKDIV_5; return 0;
99 case 14: *out |= I2S_SF_MCLKDIV_14; return 0;
100 default:
101 if (div%2) return -1;
102 d = div/2-1;
103 if (d == 0x14 || d == 0x13 || d == 0x12 || d == 0x0E)
104 return -1;
105 *out |= I2S_SF_MCLKDIV_OTHER(div);
106 return 0;
107 }
108}
109/* SClk is the clock that drives the i2s wire bus. Note that it is
110 * derived from the MClk above by taking only every 'divisor' tick
111 * of MClk.
112 */
113# define I2S_SF_SCLKDIV_SHIFT 20
114# define I2S_SF_SCLKDIV_MASK (0xF<<I2S_SF_SCLKDIV_SHIFT)
115# define I2S_SF_SCLKDIV_1 (8<<I2S_SF_SCLKDIV_SHIFT)
116# define I2S_SF_SCLKDIV_3 (9<<I2S_SF_SCLKDIV_SHIFT)
117# define I2S_SF_SCLKDIV_OTHER(div) (((div/2-1)<<I2S_SF_SCLKDIV_SHIFT)&I2S_SF_SCLKDIV_MASK)
118static inline int i2s_sf_sclkdiv(int div, int *out)
119{
120 int d;
121
122 switch(div) {
123 case 1: *out |= I2S_SF_SCLKDIV_1; return 0;
124 case 3: *out |= I2S_SF_SCLKDIV_3; return 0;
125 default:
126 if (div%2) return -1;
127 d = div/2-1;
128 if (d == 8 || d == 9) return -1;
129 *out |= I2S_SF_SCLKDIV_OTHER(div);
130 return 0;
131 }
132}
133# define I2S_SF_SCLK_MASTER (1<<19)
134/* serial format is the way the data is put to the i2s wire bus */
135# define I2S_SF_SERIAL_FORMAT_SHIFT 16
136# define I2S_SF_SERIAL_FORMAT_MASK (7<<I2S_SF_SERIAL_FORMAT_SHIFT)
137# define I2S_SF_SERIAL_FORMAT_SONY (0<<I2S_SF_SERIAL_FORMAT_SHIFT)
138# define I2S_SF_SERIAL_FORMAT_I2S_64X (1<<I2S_SF_SERIAL_FORMAT_SHIFT)
139# define I2S_SF_SERIAL_FORMAT_I2S_32X (2<<I2S_SF_SERIAL_FORMAT_SHIFT)
140# define I2S_SF_SERIAL_FORMAT_I2S_DAV (4<<I2S_SF_SERIAL_FORMAT_SHIFT)
141# define I2S_SF_SERIAL_FORMAT_I2S_SILABS (5<<I2S_SF_SERIAL_FORMAT_SHIFT)
142/* unknown */
143# define I2S_SF_EXT_SAMPLE_FREQ_INT_SHIFT 12
144# define I2S_SF_EXT_SAMPLE_FREQ_INT_MASK (0xF<<I2S_SF_SAMPLE_FREQ_INT_SHIFT)
145/* probably gives external frequency? */
146# define I2S_SF_EXT_SAMPLE_FREQ_MASK 0xFFF
147
148/* used to send codec messages, but how isn't clear */
149#define I2S_REG_CODEC_MSG_OUT 0x20
150
151/* used to receive codec messages, but how isn't clear */
152#define I2S_REG_CODEC_MSG_IN 0x30
153
154/* frame count reg isn't clear to me yet, but probably useful */
155#define I2S_REG_FRAME_COUNT 0x40
156
157/* program to some value, and get interrupt if frame count reaches it */
158#define I2S_REG_FRAME_MATCH 0x50
159
160/* this register describes how the bus transfers data */
161#define I2S_REG_DATA_WORD_SIZES 0x60
162/* number of interleaved input channels */
163# define I2S_DWS_NUM_CHANNELS_IN_SHIFT 24
164# define I2S_DWS_NUM_CHANNELS_IN_MASK (0x1F<<I2S_DWS_NUM_CHANNELS_IN_SHIFT)
165/* word size of input data */
166# define I2S_DWS_DATA_IN_SIZE_SHIFT 16
167# define I2S_DWS_DATA_IN_16BIT (0<<I2S_DWS_DATA_IN_SIZE_SHIFT)
168# define I2S_DWS_DATA_IN_24BIT (3<<I2S_DWS_DATA_IN_SIZE_SHIFT)
169/* number of interleaved output channels */
170# define I2S_DWS_NUM_CHANNELS_OUT_SHIFT 8
171# define I2S_DWS_NUM_CHANNELS_OUT_MASK (0x1F<<I2S_DWS_NUM_CHANNELS_OUT_SHIFT)
172/* word size of output data */
173# define I2S_DWS_DATA_OUT_SIZE_SHIFT 0
174# define I2S_DWS_DATA_OUT_16BIT (0<<I2S_DWS_DATA_OUT_SIZE_SHIFT)
175# define I2S_DWS_DATA_OUT_24BIT (3<<I2S_DWS_DATA_OUT_SIZE_SHIFT)
176
177
178/* unknown */
179#define I2S_REG_PEAK_LEVEL_SEL 0x70
180
181/* unknown */
182#define I2S_REG_PEAK_LEVEL_IN0 0x80
183
184/* unknown */
185#define I2S_REG_PEAK_LEVEL_IN1 0x90
186
187#endif /* __I2SBUS_INTERFACE_H */
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c b/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c
new file mode 100644
index 000000000000..3049015a04f1
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c
@@ -0,0 +1,1021 @@
1/*
2 * i2sbus driver -- pcm routines
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8
9#include <asm/io.h>
10#include <linux/delay.h>
11/* So apparently there's a reason for requiring driver.h
12 * to be included first, even if I don't know it... */
13#include <sound/driver.h>
14#include <sound/core.h>
15#include <asm/macio.h>
16#include <linux/pci.h>
17#include "../soundbus.h"
18#include "i2sbus.h"
19
20static inline void get_pcm_info(struct i2sbus_dev *i2sdev, int in,
21 struct pcm_info **pi, struct pcm_info **other)
22{
23 if (in) {
24 if (pi)
25 *pi = &i2sdev->in;
26 if (other)
27 *other = &i2sdev->out;
28 } else {
29 if (pi)
30 *pi = &i2sdev->out;
31 if (other)
32 *other = &i2sdev->in;
33 }
34}
35
36static int clock_and_divisors(int mclk, int sclk, int rate, int *out)
37{
38 /* sclk must be derived from mclk! */
39 if (mclk % sclk)
40 return -1;
41 /* derive sclk register value */
42 if (i2s_sf_sclkdiv(mclk / sclk, out))
43 return -1;
44
45 if (I2S_CLOCK_SPEED_18MHz % (rate * mclk) == 0) {
46 if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_18MHz / (rate * mclk), out)) {
47 *out |= I2S_SF_CLOCK_SOURCE_18MHz;
48 return 0;
49 }
50 }
51 if (I2S_CLOCK_SPEED_45MHz % (rate * mclk) == 0) {
52 if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_45MHz / (rate * mclk), out)) {
53 *out |= I2S_SF_CLOCK_SOURCE_45MHz;
54 return 0;
55 }
56 }
57 if (I2S_CLOCK_SPEED_49MHz % (rate * mclk) == 0) {
58 if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_49MHz / (rate * mclk), out)) {
59 *out |= I2S_SF_CLOCK_SOURCE_49MHz;
60 return 0;
61 }
62 }
63 return -1;
64}
65
66#define CHECK_RATE(rate) \
67 do { if (rates & SNDRV_PCM_RATE_ ##rate) { \
68 int dummy; \
69 if (clock_and_divisors(sysclock_factor, \
70 bus_factor, rate, &dummy)) \
71 rates &= ~SNDRV_PCM_RATE_ ##rate; \
72 } } while (0)
73
74static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
75{
76 struct pcm_info *pi, *other;
77 struct soundbus_dev *sdev;
78 int masks_inited = 0, err;
79 struct codec_info_item *cii, *rev;
80 struct snd_pcm_hardware *hw;
81 u64 formats = 0;
82 unsigned int rates = 0;
83 struct transfer_info v;
84 int result = 0;
85 int bus_factor = 0, sysclock_factor = 0;
86 int found_this;
87
88 mutex_lock(&i2sdev->lock);
89
90 get_pcm_info(i2sdev, in, &pi, &other);
91
92 hw = &pi->substream->runtime->hw;
93 sdev = &i2sdev->sound;
94
95 if (pi->active) {
96 /* alsa messed up */
97 result = -EBUSY;
98 goto out_unlock;
99 }
100
101 /* we now need to assign the hw */
102 list_for_each_entry(cii, &sdev->codec_list, list) {
103 struct transfer_info *ti = cii->codec->transfers;
104 bus_factor = cii->codec->bus_factor;
105 sysclock_factor = cii->codec->sysclock_factor;
106 while (ti->formats && ti->rates) {
107 v = *ti;
108 if (ti->transfer_in == in
109 && cii->codec->usable(cii, ti, &v)) {
110 if (masks_inited) {
111 formats &= v.formats;
112 rates &= v.rates;
113 } else {
114 formats = v.formats;
115 rates = v.rates;
116 masks_inited = 1;
117 }
118 }
119 ti++;
120 }
121 }
122 if (!masks_inited || !bus_factor || !sysclock_factor) {
123 result = -ENODEV;
124 goto out_unlock;
125 }
126 /* bus dependent stuff */
127 hw->info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
128 SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME;
129
130 CHECK_RATE(5512);
131 CHECK_RATE(8000);
132 CHECK_RATE(11025);
133 CHECK_RATE(16000);
134 CHECK_RATE(22050);
135 CHECK_RATE(32000);
136 CHECK_RATE(44100);
137 CHECK_RATE(48000);
138 CHECK_RATE(64000);
139 CHECK_RATE(88200);
140 CHECK_RATE(96000);
141 CHECK_RATE(176400);
142 CHECK_RATE(192000);
143 hw->rates = rates;
144
145 /* well. the codec might want 24 bits only, and we'll
146 * ever only transfer 24 bits, but they are top-aligned!
147 * So for alsa, we claim that we're doing full 32 bit
148 * while in reality we'll ignore the lower 8 bits of
149 * that when doing playback (they're transferred as 0
150 * as far as I know, no codecs we have are 32-bit capable
151 * so I can't really test) and when doing recording we'll
152 * always have those lower 8 bits recorded as 0 */
153 if (formats & SNDRV_PCM_FMTBIT_S24_BE)
154 formats |= SNDRV_PCM_FMTBIT_S32_BE;
155 if (formats & SNDRV_PCM_FMTBIT_U24_BE)
156 formats |= SNDRV_PCM_FMTBIT_U32_BE;
157 /* now mask off what we can support. I suppose we could
158 * also support S24_3LE and some similar formats, but I
159 * doubt there's a codec that would be able to use that,
160 * so we don't support it here. */
161 hw->formats = formats & (SNDRV_PCM_FMTBIT_S16_BE |
162 SNDRV_PCM_FMTBIT_U16_BE |
163 SNDRV_PCM_FMTBIT_S32_BE |
164 SNDRV_PCM_FMTBIT_U32_BE);
165
166 /* we need to set the highest and lowest rate possible.
167 * These are the highest and lowest rates alsa can
168 * support properly in its bitfield.
169 * Below, we'll use that to restrict to the rate
170 * currently in use (if any). */
171 hw->rate_min = 5512;
172 hw->rate_max = 192000;
173 /* if the other stream is active, then we can only
174 * support what it is currently using.
175 * FIXME: I lied. This comment is wrong. We can support
176 * anything that works with the same serial format, ie.
177 * when recording 24 bit sound we can well play 16 bit
178 * sound at the same time iff using the same transfer mode.
179 */
180 if (other->active) {
181 /* FIXME: is this guaranteed by the alsa api? */
182 hw->formats &= (1ULL << i2sdev->format);
183 /* see above, restrict rates to the one we already have */
184 hw->rate_min = i2sdev->rate;
185 hw->rate_max = i2sdev->rate;
186 }
187
188 hw->channels_min = 2;
189 hw->channels_max = 2;
190 /* these are somewhat arbitrary */
191 hw->buffer_bytes_max = 131072;
192 hw->period_bytes_min = 256;
193 hw->period_bytes_max = 16384;
194 hw->periods_min = 3;
195 hw->periods_max = MAX_DBDMA_COMMANDS;
196 list_for_each_entry(cii, &sdev->codec_list, list) {
197 if (cii->codec->open) {
198 err = cii->codec->open(cii, pi->substream);
199 if (err) {
200 result = err;
201 /* unwind */
202 found_this = 0;
203 list_for_each_entry_reverse(rev,
204 &sdev->codec_list, list) {
205 if (found_this && rev->codec->close) {
206 rev->codec->close(rev,
207 pi->substream);
208 }
209 if (rev == cii)
210 found_this = 1;
211 }
212 goto out_unlock;
213 }
214 }
215 }
216
217 out_unlock:
218 mutex_unlock(&i2sdev->lock);
219 return result;
220}
221
222#undef CHECK_RATE
223
224static int i2sbus_pcm_close(struct i2sbus_dev *i2sdev, int in)
225{
226 struct codec_info_item *cii;
227 struct pcm_info *pi;
228 int err = 0, tmp;
229
230 mutex_lock(&i2sdev->lock);
231
232 get_pcm_info(i2sdev, in, &pi, NULL);
233
234 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
235 if (cii->codec->close) {
236 tmp = cii->codec->close(cii, pi->substream);
237 if (tmp)
238 err = tmp;
239 }
240 }
241
242 pi->substream = NULL;
243 pi->active = 0;
244 mutex_unlock(&i2sdev->lock);
245 return err;
246}
247
248static int i2sbus_hw_params(struct snd_pcm_substream *substream,
249 struct snd_pcm_hw_params *params)
250{
251 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
252}
253
254static int i2sbus_hw_free(struct snd_pcm_substream *substream)
255{
256 snd_pcm_lib_free_pages(substream);
257 return 0;
258}
259
260static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
261{
262 /* whee. Hard work now. The user has selected a bitrate
263 * and bit format, so now we have to program our
264 * I2S controller appropriately. */
265 struct snd_pcm_runtime *runtime;
266 struct dbdma_cmd *command;
267 int i, periodsize;
268 dma_addr_t offset;
269 struct bus_info bi;
270 struct codec_info_item *cii;
271 int sfr = 0; /* serial format register */
272 int dws = 0; /* data word sizes reg */
273 int input_16bit;
274 struct pcm_info *pi, *other;
275 int cnt;
276 int result = 0;
277
278 mutex_lock(&i2sdev->lock);
279
280 get_pcm_info(i2sdev, in, &pi, &other);
281
282 if (pi->dbdma_ring.running) {
283 result = -EBUSY;
284 goto out_unlock;
285 }
286
287 runtime = pi->substream->runtime;
288 pi->active = 1;
289 if (other->active &&
290 ((i2sdev->format != runtime->format)
291 || (i2sdev->rate != runtime->rate))) {
292 result = -EINVAL;
293 goto out_unlock;
294 }
295
296 i2sdev->format = runtime->format;
297 i2sdev->rate = runtime->rate;
298
299 periodsize = snd_pcm_lib_period_bytes(pi->substream);
300 pi->current_period = 0;
301
302 /* generate dbdma command ring first */
303 command = pi->dbdma_ring.cmds;
304 offset = runtime->dma_addr;
305 for (i = 0; i < pi->substream->runtime->periods;
306 i++, command++, offset += periodsize) {
307 memset(command, 0, sizeof(struct dbdma_cmd));
308 command->command =
309 cpu_to_le16((in ? INPUT_MORE : OUTPUT_MORE) | INTR_ALWAYS);
310 command->phy_addr = cpu_to_le32(offset);
311 command->req_count = cpu_to_le16(periodsize);
312 command->xfer_status = cpu_to_le16(0);
313 }
314 /* last one branches back to first */
315 command--;
316 command->command |= cpu_to_le16(BR_ALWAYS);
317 command->cmd_dep = cpu_to_le32(pi->dbdma_ring.bus_cmd_start);
318
319 /* ok, let's set the serial format and stuff */
320 switch (runtime->format) {
321 /* 16 bit formats */
322 case SNDRV_PCM_FORMAT_S16_BE:
323 case SNDRV_PCM_FORMAT_U16_BE:
324 /* FIXME: if we add different bus factors we need to
325 * do more here!! */
326 bi.bus_factor = 0;
327 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
328 bi.bus_factor = cii->codec->bus_factor;
329 break;
330 }
331 if (!bi.bus_factor) {
332 result = -ENODEV;
333 goto out_unlock;
334 }
335 input_16bit = 1;
336 break;
337 case SNDRV_PCM_FORMAT_S32_BE:
338 case SNDRV_PCM_FORMAT_U32_BE:
339 /* force 64x bus speed, otherwise the data cannot be
340 * transferred quickly enough! */
341 bi.bus_factor = 64;
342 input_16bit = 0;
343 break;
344 default:
345 result = -EINVAL;
346 goto out_unlock;
347 }
348 /* we assume all sysclocks are the same! */
349 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
350 bi.sysclock_factor = cii->codec->sysclock_factor;
351 break;
352 }
353
354 if (clock_and_divisors(bi.sysclock_factor,
355 bi.bus_factor,
356 runtime->rate,
357 &sfr) < 0) {
358 result = -EINVAL;
359 goto out_unlock;
360 }
361 switch (bi.bus_factor) {
362 case 32:
363 sfr |= I2S_SF_SERIAL_FORMAT_I2S_32X;
364 break;
365 case 64:
366 sfr |= I2S_SF_SERIAL_FORMAT_I2S_64X;
367 break;
368 }
369 /* FIXME: THIS ASSUMES MASTER ALL THE TIME */
370 sfr |= I2S_SF_SCLK_MASTER;
371
372 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
373 int err = 0;
374 if (cii->codec->prepare)
375 err = cii->codec->prepare(cii, &bi, pi->substream);
376 if (err) {
377 result = err;
378 goto out_unlock;
379 }
380 }
381 /* codecs are fine with it, so set our clocks */
382 if (input_16bit)
383 dws = (2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
384 (2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
385 I2S_DWS_DATA_IN_16BIT | I2S_DWS_DATA_OUT_16BIT;
386 else
387 dws = (2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
388 (2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
389 I2S_DWS_DATA_IN_24BIT | I2S_DWS_DATA_OUT_24BIT;
390
391 /* early exit if already programmed correctly */
392 /* not locking these is fine since we touch them only in this function */
393 if (in_le32(&i2sdev->intfregs->serial_format) == sfr
394 && in_le32(&i2sdev->intfregs->data_word_sizes) == dws)
395 goto out_unlock;
396
397 /* let's notify the codecs about clocks going away.
398 * For now we only do mastering on the i2s cell... */
399 list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
400 if (cii->codec->switch_clock)
401 cii->codec->switch_clock(cii, CLOCK_SWITCH_PREPARE_SLAVE);
402
403 i2sbus_control_enable(i2sdev->control, i2sdev);
404 i2sbus_control_cell(i2sdev->control, i2sdev, 1);
405
406 out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);
407
408 i2sbus_control_clock(i2sdev->control, i2sdev, 0);
409
410 msleep(1);
411
412 /* wait for clock stopped. This can apparently take a while... */
413 cnt = 100;
414 while (cnt-- &&
415 !(in_le32(&i2sdev->intfregs->intr_ctl) & I2S_PENDING_CLOCKS_STOPPED)) {
416 msleep(5);
417 }
418 out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);
419
420 /* not locking these is fine since we touch them only in this function */
421 out_le32(&i2sdev->intfregs->serial_format, sfr);
422 out_le32(&i2sdev->intfregs->data_word_sizes, dws);
423
424 i2sbus_control_enable(i2sdev->control, i2sdev);
425 i2sbus_control_cell(i2sdev->control, i2sdev, 1);
426 i2sbus_control_clock(i2sdev->control, i2sdev, 1);
427 msleep(1);
428
429 list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
430 if (cii->codec->switch_clock)
431 cii->codec->switch_clock(cii, CLOCK_SWITCH_SLAVE);
432
433 out_unlock:
434 mutex_unlock(&i2sdev->lock);
435 return result;
436}
437
438static struct dbdma_cmd STOP_CMD = {
439 .command = __constant_cpu_to_le16(DBDMA_STOP),
440};
441
442static int i2sbus_pcm_trigger(struct i2sbus_dev *i2sdev, int in, int cmd)
443{
444 struct codec_info_item *cii;
445 struct pcm_info *pi;
446 int timeout;
447 struct dbdma_cmd tmp;
448 int result = 0;
449 unsigned long flags;
450
451 spin_lock_irqsave(&i2sdev->low_lock, flags);
452
453 get_pcm_info(i2sdev, in, &pi, NULL);
454
455 switch (cmd) {
456 case SNDRV_PCM_TRIGGER_START:
457 case SNDRV_PCM_TRIGGER_RESUME:
458 if (pi->dbdma_ring.running) {
459 result = -EALREADY;
460 goto out_unlock;
461 }
462 list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
463 if (cii->codec->start)
464 cii->codec->start(cii, pi->substream);
465 pi->dbdma_ring.running = 1;
466
467 /* reset dma engine */
468 out_le32(&pi->dbdma->control,
469 0 | (RUN | PAUSE | FLUSH | WAKE) << 16);
470 timeout = 100;
471 while (in_le32(&pi->dbdma->status) & RUN && timeout--)
472 udelay(1);
473 if (timeout <= 0) {
474 printk(KERN_ERR
475 "i2sbus: error waiting for dma reset\n");
476 result = -ENXIO;
477 goto out_unlock;
478 }
479
480 /* write dma command buffer address to the dbdma chip */
481 out_le32(&pi->dbdma->cmdptr, pi->dbdma_ring.bus_cmd_start);
482 /* post PCI write */
483 mb();
484 (void)in_le32(&pi->dbdma->status);
485
486 /* change first command to STOP */
487 tmp = *pi->dbdma_ring.cmds;
488 *pi->dbdma_ring.cmds = STOP_CMD;
489
490 /* set running state, remember that the first command is STOP */
491 out_le32(&pi->dbdma->control, RUN | (RUN << 16));
492 timeout = 100;
493 /* wait for STOP to be executed */
494 while (in_le32(&pi->dbdma->status) & ACTIVE && timeout--)
495 udelay(1);
496 if (timeout <= 0) {
497 printk(KERN_ERR "i2sbus: error waiting for dma stop\n");
498 result = -ENXIO;
499 goto out_unlock;
500 }
501 /* again, write dma command buffer address to the dbdma chip,
502 * this time of the first real command */
503 *pi->dbdma_ring.cmds = tmp;
504 out_le32(&pi->dbdma->cmdptr, pi->dbdma_ring.bus_cmd_start);
505 /* post write */
506 mb();
507 (void)in_le32(&pi->dbdma->status);
508
509 /* reset dma engine again */
510 out_le32(&pi->dbdma->control,
511 0 | (RUN | PAUSE | FLUSH | WAKE) << 16);
512 timeout = 100;
513 while (in_le32(&pi->dbdma->status) & RUN && timeout--)
514 udelay(1);
515 if (timeout <= 0) {
516 printk(KERN_ERR
517 "i2sbus: error waiting for dma reset\n");
518 result = -ENXIO;
519 goto out_unlock;
520 }
521
522 /* wake up the chip with the next descriptor */
523 out_le32(&pi->dbdma->control,
524 (RUN | WAKE) | ((RUN | WAKE) << 16));
525 /* get the frame count */
526 pi->frame_count = in_le32(&i2sdev->intfregs->frame_count);
527
528 /* off you go! */
529 break;
530 case SNDRV_PCM_TRIGGER_STOP:
531 case SNDRV_PCM_TRIGGER_SUSPEND:
532 if (!pi->dbdma_ring.running) {
533 result = -EALREADY;
534 goto out_unlock;
535 }
536
537 /* turn off all relevant bits */
538 out_le32(&pi->dbdma->control,
539 (RUN | WAKE | FLUSH | PAUSE) << 16);
540 {
541 /* FIXME: move to own function */
542 int timeout = 5000;
543 while ((in_le32(&pi->dbdma->status) & RUN)
544 && --timeout > 0)
545 udelay(1);
546 if (!timeout)
547 printk(KERN_ERR
548 "i2sbus: timed out turning "
549 "off dbdma engine!\n");
550 }
551
552 pi->dbdma_ring.running = 0;
553 list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
554 if (cii->codec->stop)
555 cii->codec->stop(cii, pi->substream);
556 break;
557 default:
558 result = -EINVAL;
559 goto out_unlock;
560 }
561
562 out_unlock:
563 spin_unlock_irqrestore(&i2sdev->low_lock, flags);
564 return result;
565}
566
567static snd_pcm_uframes_t i2sbus_pcm_pointer(struct i2sbus_dev *i2sdev, int in)
568{
569 struct pcm_info *pi;
570 u32 fc;
571
572 get_pcm_info(i2sdev, in, &pi, NULL);
573
574 fc = in_le32(&i2sdev->intfregs->frame_count);
575 fc = fc - pi->frame_count;
576
577 return (bytes_to_frames(pi->substream->runtime,
578 pi->current_period *
579 snd_pcm_lib_period_bytes(pi->substream))
580 + fc) % pi->substream->runtime->buffer_size;
581}
582
583static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in)
584{
585 struct pcm_info *pi;
586 u32 fc;
587 u32 delta;
588
589 spin_lock(&i2sdev->low_lock);
590 get_pcm_info(i2sdev, in, &pi, NULL);
591
592 if (!pi->dbdma_ring.running) {
593 /* there was still an interrupt pending
594 * while we stopped. or maybe another
595 * processor (not the one that was stopping
596 * the DMA engine) was spinning above
597 * waiting for the lock. */
598 goto out_unlock;
599 }
600
601 fc = in_le32(&i2sdev->intfregs->frame_count);
602 /* a counter overflow does not change the calculation. */
603 delta = fc - pi->frame_count;
604
605 /* update current_period */
606 while (delta >= pi->substream->runtime->period_size) {
607 pi->current_period++;
608 delta = delta - pi->substream->runtime->period_size;
609 }
610
611 if (unlikely(delta)) {
612 /* Some interrupt came late, so check the dbdma.
613 * This special case exists to syncronize the frame_count with
614 * the dbdma transfer, but is hit every once in a while. */
615 int period;
616
617 period = (in_le32(&pi->dbdma->cmdptr)
618 - pi->dbdma_ring.bus_cmd_start)
619 / sizeof(struct dbdma_cmd);
620 pi->current_period = pi->current_period
621 % pi->substream->runtime->periods;
622
623 while (pi->current_period != period) {
624 pi->current_period++;
625 pi->current_period %= pi->substream->runtime->periods;
626 /* Set delta to zero, as the frame_count value is too
627 * high (otherwise the code path will not be executed).
628 * This corrects the fact that the frame_count is too
629 * low at the beginning due to buffering. */
630 delta = 0;
631 }
632 }
633
634 pi->frame_count = fc - delta;
635 pi->current_period %= pi->substream->runtime->periods;
636
637 spin_unlock(&i2sdev->low_lock);
638 /* may call _trigger again, hence needs to be unlocked */
639 snd_pcm_period_elapsed(pi->substream);
640 return;
641 out_unlock:
642 spin_unlock(&i2sdev->low_lock);
643}
644
645irqreturn_t i2sbus_tx_intr(int irq, void *devid, struct pt_regs *regs)
646{
647 handle_interrupt((struct i2sbus_dev *)devid, 0);
648 return IRQ_HANDLED;
649}
650
651irqreturn_t i2sbus_rx_intr(int irq, void *devid, struct pt_regs * regs)
652{
653 handle_interrupt((struct i2sbus_dev *)devid, 1);
654 return IRQ_HANDLED;
655}
656
657static int i2sbus_playback_open(struct snd_pcm_substream *substream)
658{
659 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
660
661 if (!i2sdev)
662 return -EINVAL;
663 i2sdev->out.substream = substream;
664 return i2sbus_pcm_open(i2sdev, 0);
665}
666
667static int i2sbus_playback_close(struct snd_pcm_substream *substream)
668{
669 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
670 int err;
671
672 if (!i2sdev)
673 return -EINVAL;
674 if (i2sdev->out.substream != substream)
675 return -EINVAL;
676 err = i2sbus_pcm_close(i2sdev, 0);
677 if (!err)
678 i2sdev->out.substream = NULL;
679 return err;
680}
681
682static int i2sbus_playback_prepare(struct snd_pcm_substream *substream)
683{
684 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
685
686 if (!i2sdev)
687 return -EINVAL;
688 if (i2sdev->out.substream != substream)
689 return -EINVAL;
690 return i2sbus_pcm_prepare(i2sdev, 0);
691}
692
693static int i2sbus_playback_trigger(struct snd_pcm_substream *substream, int cmd)
694{
695 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
696
697 if (!i2sdev)
698 return -EINVAL;
699 if (i2sdev->out.substream != substream)
700 return -EINVAL;
701 return i2sbus_pcm_trigger(i2sdev, 0, cmd);
702}
703
704static snd_pcm_uframes_t i2sbus_playback_pointer(struct snd_pcm_substream
705 *substream)
706{
707 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
708
709 if (!i2sdev)
710 return -EINVAL;
711 if (i2sdev->out.substream != substream)
712 return 0;
713 return i2sbus_pcm_pointer(i2sdev, 0);
714}
715
716static struct snd_pcm_ops i2sbus_playback_ops = {
717 .open = i2sbus_playback_open,
718 .close = i2sbus_playback_close,
719 .ioctl = snd_pcm_lib_ioctl,
720 .hw_params = i2sbus_hw_params,
721 .hw_free = i2sbus_hw_free,
722 .prepare = i2sbus_playback_prepare,
723 .trigger = i2sbus_playback_trigger,
724 .pointer = i2sbus_playback_pointer,
725};
726
727static int i2sbus_record_open(struct snd_pcm_substream *substream)
728{
729 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
730
731 if (!i2sdev)
732 return -EINVAL;
733 i2sdev->in.substream = substream;
734 return i2sbus_pcm_open(i2sdev, 1);
735}
736
737static int i2sbus_record_close(struct snd_pcm_substream *substream)
738{
739 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
740 int err;
741
742 if (!i2sdev)
743 return -EINVAL;
744 if (i2sdev->in.substream != substream)
745 return -EINVAL;
746 err = i2sbus_pcm_close(i2sdev, 1);
747 if (!err)
748 i2sdev->in.substream = NULL;
749 return err;
750}
751
752static int i2sbus_record_prepare(struct snd_pcm_substream *substream)
753{
754 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
755
756 if (!i2sdev)
757 return -EINVAL;
758 if (i2sdev->in.substream != substream)
759 return -EINVAL;
760 return i2sbus_pcm_prepare(i2sdev, 1);
761}
762
763static int i2sbus_record_trigger(struct snd_pcm_substream *substream, int cmd)
764{
765 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
766
767 if (!i2sdev)
768 return -EINVAL;
769 if (i2sdev->in.substream != substream)
770 return -EINVAL;
771 return i2sbus_pcm_trigger(i2sdev, 1, cmd);
772}
773
774static snd_pcm_uframes_t i2sbus_record_pointer(struct snd_pcm_substream
775 *substream)
776{
777 struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
778
779 if (!i2sdev)
780 return -EINVAL;
781 if (i2sdev->in.substream != substream)
782 return 0;
783 return i2sbus_pcm_pointer(i2sdev, 1);
784}
785
786static struct snd_pcm_ops i2sbus_record_ops = {
787 .open = i2sbus_record_open,
788 .close = i2sbus_record_close,
789 .ioctl = snd_pcm_lib_ioctl,
790 .hw_params = i2sbus_hw_params,
791 .hw_free = i2sbus_hw_free,
792 .prepare = i2sbus_record_prepare,
793 .trigger = i2sbus_record_trigger,
794 .pointer = i2sbus_record_pointer,
795};
796
797static void i2sbus_private_free(struct snd_pcm *pcm)
798{
799 struct i2sbus_dev *i2sdev = snd_pcm_chip(pcm);
800 struct codec_info_item *p, *tmp;
801
802 i2sdev->sound.pcm = NULL;
803 i2sdev->out.created = 0;
804 i2sdev->in.created = 0;
805 list_for_each_entry_safe(p, tmp, &i2sdev->sound.codec_list, list) {
806 printk(KERN_ERR "i2sbus: a codec didn't unregister!\n");
807 list_del(&p->list);
808 module_put(p->codec->owner);
809 kfree(p);
810 }
811 soundbus_dev_put(&i2sdev->sound);
812 module_put(THIS_MODULE);
813}
814
815/* FIXME: this function needs an error handling strategy with labels */
816int
817i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
818 struct codec_info *ci, void *data)
819{
820 int err, in = 0, out = 0;
821 struct transfer_info *tmp;
822 struct i2sbus_dev *i2sdev = soundbus_dev_to_i2sbus_dev(dev);
823 struct codec_info_item *cii;
824
825 if (!dev->pcmname || dev->pcmid == -1) {
826 printk(KERN_ERR "i2sbus: pcm name and id must be set!\n");
827 return -EINVAL;
828 }
829
830 list_for_each_entry(cii, &dev->codec_list, list) {
831 if (cii->codec_data == data)
832 return -EALREADY;
833 }
834
835 if (!ci->transfers || !ci->transfers->formats
836 || !ci->transfers->rates || !ci->usable)
837 return -EINVAL;
838
839 /* we currently code the i2s transfer on the clock, and support only
840 * 32 and 64 */
841 if (ci->bus_factor != 32 && ci->bus_factor != 64)
842 return -EINVAL;
843
844 /* If you want to fix this, you need to keep track of what transport infos
845 * are to be used, which codecs they belong to, and then fix all the
846 * sysclock/busclock stuff above to depend on which is usable */
847 list_for_each_entry(cii, &dev->codec_list, list) {
848 if (cii->codec->sysclock_factor != ci->sysclock_factor) {
849 printk(KERN_DEBUG
850 "cannot yet handle multiple different sysclocks!\n");
851 return -EINVAL;
852 }
853 if (cii->codec->bus_factor != ci->bus_factor) {
854 printk(KERN_DEBUG
855 "cannot yet handle multiple different bus clocks!\n");
856 return -EINVAL;
857 }
858 }
859
860 tmp = ci->transfers;
861 while (tmp->formats && tmp->rates) {
862 if (tmp->transfer_in)
863 in = 1;
864 else
865 out = 1;
866 tmp++;
867 }
868
869 cii = kzalloc(sizeof(struct codec_info_item), GFP_KERNEL);
870 if (!cii) {
871 printk(KERN_DEBUG "i2sbus: failed to allocate cii\n");
872 return -ENOMEM;
873 }
874
875 /* use the private data to point to the codec info */
876 cii->sdev = soundbus_dev_get(dev);
877 cii->codec = ci;
878 cii->codec_data = data;
879
880 if (!cii->sdev) {
881 printk(KERN_DEBUG
882 "i2sbus: failed to get soundbus dev reference\n");
883 kfree(cii);
884 return -ENODEV;
885 }
886
887 if (!try_module_get(THIS_MODULE)) {
888 printk(KERN_DEBUG "i2sbus: failed to get module reference!\n");
889 soundbus_dev_put(dev);
890 kfree(cii);
891 return -EBUSY;
892 }
893
894 if (!try_module_get(ci->owner)) {
895 printk(KERN_DEBUG
896 "i2sbus: failed to get module reference to codec owner!\n");
897 module_put(THIS_MODULE);
898 soundbus_dev_put(dev);
899 kfree(cii);
900 return -EBUSY;
901 }
902
903 if (!dev->pcm) {
904 err = snd_pcm_new(card,
905 dev->pcmname,
906 dev->pcmid,
907 0,
908 0,
909 &dev->pcm);
910 if (err) {
911 printk(KERN_DEBUG "i2sbus: failed to create pcm\n");
912 kfree(cii);
913 module_put(ci->owner);
914 soundbus_dev_put(dev);
915 module_put(THIS_MODULE);
916 return err;
917 }
918 }
919
920 /* ALSA yet again sucks.
921 * If it is ever fixed, remove this line. See below. */
922 out = in = 1;
923
924 if (!i2sdev->out.created && out) {
925 if (dev->pcm->card != card) {
926 /* eh? */
927 printk(KERN_ERR
928 "Can't attach same bus to different cards!\n");
929 module_put(ci->owner);
930 kfree(cii);
931 soundbus_dev_put(dev);
932 module_put(THIS_MODULE);
933 return -EINVAL;
934 }
935 if ((err =
936 snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, 1))) {
937 module_put(ci->owner);
938 kfree(cii);
939 soundbus_dev_put(dev);
940 module_put(THIS_MODULE);
941 return err;
942 }
943 snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
944 &i2sbus_playback_ops);
945 i2sdev->out.created = 1;
946 }
947
948 if (!i2sdev->in.created && in) {
949 if (dev->pcm->card != card) {
950 printk(KERN_ERR
951 "Can't attach same bus to different cards!\n");
952 module_put(ci->owner);
953 kfree(cii);
954 soundbus_dev_put(dev);
955 module_put(THIS_MODULE);
956 return -EINVAL;
957 }
958 if ((err =
959 snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, 1))) {
960 module_put(ci->owner);
961 kfree(cii);
962 soundbus_dev_put(dev);
963 module_put(THIS_MODULE);
964 return err;
965 }
966 snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
967 &i2sbus_record_ops);
968 i2sdev->in.created = 1;
969 }
970
971 /* so we have to register the pcm after adding any substream
972 * to it because alsa doesn't create the devices for the
973 * substreams when we add them later.
974 * Therefore, force in and out on both busses (above) and
975 * register the pcm now instead of just after creating it.
976 */
977 err = snd_device_register(card, dev->pcm);
978 if (err) {
979 printk(KERN_ERR "i2sbus: error registering new pcm\n");
980 module_put(ci->owner);
981 kfree(cii);
982 soundbus_dev_put(dev);
983 module_put(THIS_MODULE);
984 return err;
985 }
986 /* no errors any more, so let's add this to our list */
987 list_add(&cii->list, &dev->codec_list);
988
989 dev->pcm->private_data = i2sdev;
990 dev->pcm->private_free = i2sbus_private_free;
991
992 /* well, we really should support scatter/gather DMA */
993 snd_pcm_lib_preallocate_pages_for_all(
994 dev->pcm, SNDRV_DMA_TYPE_DEV,
995 snd_dma_pci_data(macio_get_pci_dev(i2sdev->macio)),
996 64 * 1024, 64 * 1024);
997
998 return 0;
999}
1000
1001void i2sbus_detach_codec(struct soundbus_dev *dev, void *data)
1002{
1003 struct codec_info_item *cii = NULL, *i;
1004
1005 list_for_each_entry(i, &dev->codec_list, list) {
1006 if (i->codec_data == data) {
1007 cii = i;
1008 break;
1009 }
1010 }
1011 if (cii) {
1012 list_del(&cii->list);
1013 module_put(cii->codec->owner);
1014 kfree(cii);
1015 }
1016 /* no more codecs, but still a pcm? */
1017 if (list_empty(&dev->codec_list) && dev->pcm) {
1018 /* the actual cleanup is done by the callback above! */
1019 snd_device_free(dev->pcm->card, dev->pcm);
1020 }
1021}
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus.h b/sound/aoa/soundbus/i2sbus/i2sbus.h
new file mode 100644
index 000000000000..cfa5162e3b0f
--- /dev/null
+++ b/sound/aoa/soundbus/i2sbus/i2sbus.h
@@ -0,0 +1,112 @@
1/*
2 * i2sbus driver -- private definitions
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#ifndef __I2SBUS_H
9#define __I2SBUS_H
10#include <asm/dbdma.h>
11#include <linux/interrupt.h>
12#include <sound/pcm.h>
13#include <linux/spinlock.h>
14#include <linux/mutex.h>
15#include <asm/prom.h>
16#include "i2sbus-interface.h"
17#include "i2sbus-control.h"
18#include "../soundbus.h"
19
20struct i2sbus_control {
21 volatile struct i2s_control_regs __iomem *controlregs;
22 struct resource rsrc;
23 struct list_head list;
24};
25
26#define MAX_DBDMA_COMMANDS 32
27
28struct dbdma_command_mem {
29 dma_addr_t bus_addr;
30 dma_addr_t bus_cmd_start;
31 struct dbdma_cmd *cmds;
32 void *space;
33 int size;
34 u32 running:1;
35};
36
37struct pcm_info {
38 u32 created:1, /* has this direction been created with alsa? */
39 active:1; /* is this stream active? */
40 /* runtime information */
41 struct snd_pcm_substream *substream;
42 int current_period;
43 u32 frame_count;
44 struct dbdma_command_mem dbdma_ring;
45 volatile struct dbdma_regs __iomem *dbdma;
46};
47
48struct i2sbus_dev {
49 struct soundbus_dev sound;
50 struct macio_dev *macio;
51 struct i2sbus_control *control;
52 volatile struct i2s_interface_regs __iomem *intfregs;
53
54 struct resource resources[3];
55 struct resource *allocated_resource[3];
56 int interrupts[3];
57 char rnames[3][32];
58
59 /* info about currently active substreams */
60 struct pcm_info out, in;
61 snd_pcm_format_t format;
62 unsigned int rate;
63
64 /* list for a single controller */
65 struct list_head item;
66 /* number of bus on controller */
67 int bus_number;
68 /* for use by control layer */
69 struct pmf_function *enable,
70 *cell_enable,
71 *cell_disable,
72 *clock_enable,
73 *clock_disable;
74
75 /* locks */
76 /* spinlock for low-level interrupt locking */
77 spinlock_t low_lock;
78 /* mutex for high-level consistency */
79 struct mutex lock;
80};
81
82#define soundbus_dev_to_i2sbus_dev(sdev) \
83 container_of(sdev, struct i2sbus_dev, sound)
84
85/* pcm specific functions */
86extern int
87i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
88 struct codec_info *ci, void *data);
89extern void
90i2sbus_detach_codec(struct soundbus_dev *dev, void *data);
91extern irqreturn_t
92i2sbus_tx_intr(int irq, void *devid, struct pt_regs *regs);
93extern irqreturn_t
94i2sbus_rx_intr(int irq, void *devid, struct pt_regs *regs);
95
96/* control specific functions */
97extern int i2sbus_control_init(struct macio_dev* dev,
98 struct i2sbus_control **c);
99extern void i2sbus_control_destroy(struct i2sbus_control *c);
100extern int i2sbus_control_add_dev(struct i2sbus_control *c,
101 struct i2sbus_dev *i2sdev);
102extern void i2sbus_control_remove_dev(struct i2sbus_control *c,
103 struct i2sbus_dev *i2sdev);
104extern int i2sbus_control_enable(struct i2sbus_control *c,
105 struct i2sbus_dev *i2sdev);
106extern int i2sbus_control_cell(struct i2sbus_control *c,
107 struct i2sbus_dev *i2sdev,
108 int enable);
109extern int i2sbus_control_clock(struct i2sbus_control *c,
110 struct i2sbus_dev *i2sdev,
111 int enable);
112#endif /* __I2SBUS_H */
diff --git a/sound/aoa/soundbus/soundbus.h b/sound/aoa/soundbus/soundbus.h
new file mode 100644
index 000000000000..5c27297835d7
--- /dev/null
+++ b/sound/aoa/soundbus/soundbus.h
@@ -0,0 +1,202 @@
1/*
2 * soundbus generic definitions
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPL v2, can be found in COPYING.
7 */
8#ifndef __SOUNDBUS_H
9#define __SOUNDBUS_H
10
11#include <asm/of_device.h>
12#include <sound/pcm.h>
13#include <linux/list.h>
14
15
16/* When switching from master to slave or the other way around,
17 * you don't want to have the codec chip acting as clock source
18 * while the bus still is.
19 * More importantly, while switch from slave to master, you need
20 * to turn off the chip's master function first, but then there's
21 * no clock for a while and other chips might reset, so we notify
22 * their drivers after having switched.
23 * The constants here are codec-point of view, so when we switch
24 * the soundbus to master we tell the codec we're going to switch
25 * and give it CLOCK_SWITCH_PREPARE_SLAVE!
26 */
27enum clock_switch {
28 CLOCK_SWITCH_PREPARE_SLAVE,
29 CLOCK_SWITCH_PREPARE_MASTER,
30 CLOCK_SWITCH_SLAVE,
31 CLOCK_SWITCH_MASTER,
32 CLOCK_SWITCH_NOTIFY,
33};
34
35/* information on a transfer the codec can take */
36struct transfer_info {
37 u64 formats; /* SNDRV_PCM_FMTBIT_* */
38 unsigned int rates; /* SNDRV_PCM_RATE_* */
39 /* flags */
40 u32 transfer_in:1, /* input = 1, output = 0 */
41 must_be_clock_source:1;
42 /* for codecs to distinguish among their TIs */
43 int tag;
44};
45
46struct codec_info_item {
47 struct codec_info *codec;
48 void *codec_data;
49 struct soundbus_dev *sdev;
50 /* internal, to be used by the soundbus provider */
51 struct list_head list;
52};
53
54/* for prepare, where the codecs need to know
55 * what we're going to drive the bus with */
56struct bus_info {
57 /* see below */
58 int sysclock_factor;
59 int bus_factor;
60};
61
62/* information on the codec itself, plus function pointers */
63struct codec_info {
64 /* the module this lives in */
65 struct module *owner;
66
67 /* supported transfer possibilities, array terminated by
68 * formats or rates being 0. */
69 struct transfer_info *transfers;
70
71 /* Master clock speed factor
72 * to be used (master clock speed = sysclock_factor * sampling freq)
73 * Unused if the soundbus provider has no such notion.
74 */
75 int sysclock_factor;
76
77 /* Bus factor, bus clock speed = bus_factor * sampling freq)
78 * Unused if the soundbus provider has no such notion.
79 */
80 int bus_factor;
81
82 /* operations */
83 /* clock switching, see above */
84 int (*switch_clock)(struct codec_info_item *cii,
85 enum clock_switch clock);
86
87 /* called for each transfer_info when the user
88 * opens the pcm device to determine what the
89 * hardware can support at this point in time.
90 * That can depend on other user-switchable controls.
91 * Return 1 if usable, 0 if not.
92 * out points to another instance of a transfer_info
93 * which is initialised to the values in *ti, and
94 * it's format and rate values can be modified by
95 * the callback if it is necessary to further restrict
96 * the formats that can be used at the moment, for
97 * example when one codec has multiple logical codec
98 * info structs for multiple inputs.
99 */
100 int (*usable)(struct codec_info_item *cii,
101 struct transfer_info *ti,
102 struct transfer_info *out);
103
104 /* called when pcm stream is opened, probably not implemented
105 * most of the time since it isn't too useful */
106 int (*open)(struct codec_info_item *cii,
107 struct snd_pcm_substream *substream);
108
109 /* called when the pcm stream is closed, at this point
110 * the user choices can all be unlocked (see below) */
111 int (*close)(struct codec_info_item *cii,
112 struct snd_pcm_substream *substream);
113
114 /* if the codec must forbid some user choices because
115 * they are not valid with the substream/transfer info,
116 * it must do so here. Example: no digital output for
117 * incompatible framerate, say 8KHz, on Onyx.
118 * If the selected stuff in the substream is NOT
119 * compatible, you have to reject this call! */
120 int (*prepare)(struct codec_info_item *cii,
121 struct bus_info *bi,
122 struct snd_pcm_substream *substream);
123
124 /* start() is called before data is pushed to the codec.
125 * Note that start() must be atomic! */
126 int (*start)(struct codec_info_item *cii,
127 struct snd_pcm_substream *substream);
128
129 /* stop() is called after data is no longer pushed to the codec.
130 * Note that stop() must be atomic! */
131 int (*stop)(struct codec_info_item *cii,
132 struct snd_pcm_substream *substream);
133
134 int (*suspend)(struct codec_info_item *cii, pm_message_t state);
135 int (*resume)(struct codec_info_item *cii);
136};
137
138/* information on a soundbus device */
139struct soundbus_dev {
140 /* the bus it belongs to */
141 struct list_head onbuslist;
142
143 /* the of device it represents */
144 struct of_device ofdev;
145
146 /* what modules go by */
147 char modalias[32];
148
149 /* These fields must be before attach_codec can be called.
150 * They should be set by the owner of the alsa card object
151 * that is needed, and whoever sets them must make sure
152 * that they are unique within that alsa card object. */
153 char *pcmname;
154 int pcmid;
155
156 /* this is assigned by the soundbus provider in attach_codec */
157 struct snd_pcm *pcm;
158
159 /* operations */
160 /* attach a codec to this soundbus, give the alsa
161 * card object the PCMs for this soundbus should be in.
162 * The 'data' pointer must be unique, it is used as the
163 * key for detach_codec(). */
164 int (*attach_codec)(struct soundbus_dev *dev, struct snd_card *card,
165 struct codec_info *ci, void *data);
166 void (*detach_codec)(struct soundbus_dev *dev, void *data);
167 /* TODO: suspend/resume */
168
169 /* private for the soundbus provider */
170 struct list_head codec_list;
171 u32 have_out:1, have_in:1;
172};
173#define to_soundbus_device(d) container_of(d, struct soundbus_dev, ofdev.dev)
174#define of_to_soundbus_device(d) container_of(d, struct soundbus_dev, ofdev)
175
176extern int soundbus_add_one(struct soundbus_dev *dev);
177extern void soundbus_remove_one(struct soundbus_dev *dev);
178
179extern struct soundbus_dev *soundbus_dev_get(struct soundbus_dev *dev);
180extern void soundbus_dev_put(struct soundbus_dev *dev);
181
182struct soundbus_driver {
183 char *name;
184 struct module *owner;
185
186 /* we don't implement any matching at all */
187
188 int (*probe)(struct soundbus_dev* dev);
189 int (*remove)(struct soundbus_dev* dev);
190
191 int (*suspend)(struct soundbus_dev* dev, pm_message_t state);
192 int (*resume)(struct soundbus_dev* dev);
193 int (*shutdown)(struct soundbus_dev* dev);
194
195 struct device_driver driver;
196};
197#define to_soundbus_driver(drv) container_of(drv,struct soundbus_driver, driver)
198
199extern int soundbus_register_driver(struct soundbus_driver *drv);
200extern void soundbus_unregister_driver(struct soundbus_driver *drv);
201
202#endif /* __SOUNDBUS_H */
diff --git a/sound/aoa/soundbus/sysfs.c b/sound/aoa/soundbus/sysfs.c
new file mode 100644
index 000000000000..d31f8146952a
--- /dev/null
+++ b/sound/aoa/soundbus/sysfs.c
@@ -0,0 +1,43 @@
1#include <linux/config.h>
2#include <linux/kernel.h>
3#include <linux/stat.h>
4/* FIX UP */
5#include "soundbus.h"
6
7#define soundbus_config_of_attr(field, format_string) \
8static ssize_t \
9field##_show (struct device *dev, struct device_attribute *attr, \
10 char *buf) \
11{ \
12 struct soundbus_dev *mdev = to_soundbus_device (dev); \
13 return sprintf (buf, format_string, mdev->ofdev.node->field); \
14}
15
16static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
17 char *buf)
18{
19 struct soundbus_dev *sdev = to_soundbus_device(dev);
20 struct of_device *of = &sdev->ofdev;
21 int length;
22
23 if (*sdev->modalias) {
24 strlcpy(buf, sdev->modalias, sizeof(sdev->modalias) + 1);
25 strcat(buf, "\n");
26 length = strlen(buf);
27 } else {
28 length = sprintf(buf, "of:N%sT%s\n",
29 of->node->name, of->node->type);
30 }
31
32 return length;
33}
34
35soundbus_config_of_attr (name, "%s\n");
36soundbus_config_of_attr (type, "%s\n");
37
38struct device_attribute soundbus_dev_attrs[] = {
39 __ATTR_RO(name),
40 __ATTR_RO(type),
41 __ATTR_RO(modalias),
42 __ATTR_NULL
43};
diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c
index 13057d92f08a..b88fb0c5a68a 100644
--- a/sound/arm/sa11xx-uda1341.c
+++ b/sound/arm/sa11xx-uda1341.c
@@ -112,7 +112,7 @@ MODULE_LICENSE("GPL");
112MODULE_DESCRIPTION("SA1100/SA1111 + UDA1341TS driver for ALSA"); 112MODULE_DESCRIPTION("SA1100/SA1111 + UDA1341TS driver for ALSA");
113MODULE_SUPPORTED_DEVICE("{{UDA1341,iPAQ H3600 UDA1341TS}}"); 113MODULE_SUPPORTED_DEVICE("{{UDA1341,iPAQ H3600 UDA1341TS}}");
114 114
115static char *id = NULL; /* ID for this card */ 115static char *id; /* ID for this card */
116 116
117module_param(id, charp, 0444); 117module_param(id, charp, 0444);
118MODULE_PARM_DESC(id, "ID string for SA1100/SA1111 + UDA1341TS soundcard."); 118MODULE_PARM_DESC(id, "ID string for SA1100/SA1111 + UDA1341TS soundcard.");
@@ -984,11 +984,15 @@ static int __init sa11xx_uda1341_init(void)
984 if ((err = platform_driver_register(&sa11xx_uda1341_driver)) < 0) 984 if ((err = platform_driver_register(&sa11xx_uda1341_driver)) < 0)
985 return err; 985 return err;
986 device = platform_device_register_simple(SA11XX_UDA1341_DRIVER, -1, NULL, 0); 986 device = platform_device_register_simple(SA11XX_UDA1341_DRIVER, -1, NULL, 0);
987 if (IS_ERR(device)) { 987 if (!IS_ERR(device)) {
988 platform_driver_unregister(&sa11xx_uda1341_driver); 988 if (platform_get_drvdata(device))
989 return PTR_ERR(device); 989 return 0;
990 } 990 platform_device_unregister(device);
991 return 0; 991 err = -ENODEV
992 } else
993 err = PTR_ERR(device);
994 platform_driver_unregister(&sa11xx_uda1341_driver);
995 return err;
992} 996}
993 997
994static void __exit sa11xx_uda1341_exit(void) 998static void __exit sa11xx_uda1341_exit(void)
diff --git a/sound/core/control.c b/sound/core/control.c
index 22565c9b9603..bb397eaa7187 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -176,6 +176,8 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
176 read_unlock(&card->ctl_files_rwlock); 176 read_unlock(&card->ctl_files_rwlock);
177} 177}
178 178
179EXPORT_SYMBOL(snd_ctl_notify);
180
179/** 181/**
180 * snd_ctl_new - create a control instance from the template 182 * snd_ctl_new - create a control instance from the template
181 * @control: the control template 183 * @control: the control template
@@ -204,6 +206,8 @@ struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, unsigned int acce
204 return kctl; 206 return kctl;
205} 207}
206 208
209EXPORT_SYMBOL(snd_ctl_new);
210
207/** 211/**
208 * snd_ctl_new1 - create a control instance from the template 212 * snd_ctl_new1 - create a control instance from the template
209 * @ncontrol: the initialization record 213 * @ncontrol: the initialization record
@@ -242,6 +246,8 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
242 return snd_ctl_new(&kctl, access); 246 return snd_ctl_new(&kctl, access);
243} 247}
244 248
249EXPORT_SYMBOL(snd_ctl_new1);
250
245/** 251/**
246 * snd_ctl_free_one - release the control instance 252 * snd_ctl_free_one - release the control instance
247 * @kcontrol: the control instance 253 * @kcontrol: the control instance
@@ -259,6 +265,8 @@ void snd_ctl_free_one(struct snd_kcontrol *kcontrol)
259 } 265 }
260} 266}
261 267
268EXPORT_SYMBOL(snd_ctl_free_one);
269
262static unsigned int snd_ctl_hole_check(struct snd_card *card, 270static unsigned int snd_ctl_hole_check(struct snd_card *card,
263 unsigned int count) 271 unsigned int count)
264{ 272{
@@ -347,6 +355,8 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
347 return err; 355 return err;
348} 356}
349 357
358EXPORT_SYMBOL(snd_ctl_add);
359
350/** 360/**
351 * snd_ctl_remove - remove the control from the card and release it 361 * snd_ctl_remove - remove the control from the card and release it
352 * @card: the card instance 362 * @card: the card instance
@@ -373,6 +383,8 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
373 return 0; 383 return 0;
374} 384}
375 385
386EXPORT_SYMBOL(snd_ctl_remove);
387
376/** 388/**
377 * snd_ctl_remove_id - remove the control of the given id and release it 389 * snd_ctl_remove_id - remove the control of the given id and release it
378 * @card: the card instance 390 * @card: the card instance
@@ -399,6 +411,8 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id)
399 return ret; 411 return ret;
400} 412}
401 413
414EXPORT_SYMBOL(snd_ctl_remove_id);
415
402/** 416/**
403 * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it 417 * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it
404 * @file: active control handle 418 * @file: active control handle
@@ -461,6 +475,8 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
461 return 0; 475 return 0;
462} 476}
463 477
478EXPORT_SYMBOL(snd_ctl_rename_id);
479
464/** 480/**
465 * snd_ctl_find_numid - find the control instance with the given number-id 481 * snd_ctl_find_numid - find the control instance with the given number-id
466 * @card: the card instance 482 * @card: the card instance
@@ -487,6 +503,8 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi
487 return NULL; 503 return NULL;
488} 504}
489 505
506EXPORT_SYMBOL(snd_ctl_find_numid);
507
490/** 508/**
491 * snd_ctl_find_id - find the control instance with the given id 509 * snd_ctl_find_id - find the control instance with the given id
492 * @card: the card instance 510 * @card: the card instance
@@ -527,6 +545,8 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
527 return NULL; 545 return NULL;
528} 546}
529 547
548EXPORT_SYMBOL(snd_ctl_find_id);
549
530static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, 550static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
531 unsigned int cmd, void __user *arg) 551 unsigned int cmd, void __user *arg)
532{ 552{
@@ -704,6 +724,8 @@ int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control)
704 return result; 724 return result;
705} 725}
706 726
727EXPORT_SYMBOL(snd_ctl_elem_read);
728
707static int snd_ctl_elem_read_user(struct snd_card *card, 729static int snd_ctl_elem_read_user(struct snd_card *card,
708 struct snd_ctl_elem_value __user *_control) 730 struct snd_ctl_elem_value __user *_control)
709{ 731{
@@ -767,6 +789,8 @@ int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
767 return result; 789 return result;
768} 790}
769 791
792EXPORT_SYMBOL(snd_ctl_elem_write);
793
770static int snd_ctl_elem_write_user(struct snd_ctl_file *file, 794static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
771 struct snd_ctl_elem_value __user *_control) 795 struct snd_ctl_elem_value __user *_control)
772{ 796{
@@ -1199,11 +1223,15 @@ int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn)
1199 return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls); 1223 return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls);
1200} 1224}
1201 1225
1226EXPORT_SYMBOL(snd_ctl_register_ioctl);
1227
1202#ifdef CONFIG_COMPAT 1228#ifdef CONFIG_COMPAT
1203int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn) 1229int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn)
1204{ 1230{
1205 return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls); 1231 return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls);
1206} 1232}
1233
1234EXPORT_SYMBOL(snd_ctl_register_ioctl_compat);
1207#endif 1235#endif
1208 1236
1209/* 1237/*
@@ -1236,12 +1264,15 @@ int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn)
1236 return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls); 1264 return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls);
1237} 1265}
1238 1266
1267EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
1268
1239#ifdef CONFIG_COMPAT 1269#ifdef CONFIG_COMPAT
1240int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn) 1270int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn)
1241{ 1271{
1242 return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls); 1272 return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls);
1243} 1273}
1244 1274
1275EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
1245#endif 1276#endif
1246 1277
1247static int snd_ctl_fasync(int fd, struct file * file, int on) 1278static int snd_ctl_fasync(int fd, struct file * file, int on)
diff --git a/sound/core/device.c b/sound/core/device.c
index b1cf6ec56784..6ce4da4a1081 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -63,6 +63,8 @@ int snd_device_new(struct snd_card *card, snd_device_type_t type,
63 return 0; 63 return 0;
64} 64}
65 65
66EXPORT_SYMBOL(snd_device_new);
67
66/** 68/**
67 * snd_device_free - release the device from the card 69 * snd_device_free - release the device from the card
68 * @card: the card instance 70 * @card: the card instance
@@ -107,6 +109,8 @@ int snd_device_free(struct snd_card *card, void *device_data)
107 return -ENXIO; 109 return -ENXIO;
108} 110}
109 111
112EXPORT_SYMBOL(snd_device_free);
113
110/** 114/**
111 * snd_device_disconnect - disconnect the device 115 * snd_device_disconnect - disconnect the device
112 * @card: the card instance 116 * @card: the card instance
@@ -182,6 +186,8 @@ int snd_device_register(struct snd_card *card, void *device_data)
182 return -ENXIO; 186 return -ENXIO;
183} 187}
184 188
189EXPORT_SYMBOL(snd_device_register);
190
185/* 191/*
186 * register all the devices on the card. 192 * register all the devices on the card.
187 * called from init.c 193 * called from init.c
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 2524e66eccdd..8bd0dcc93eba 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -486,7 +486,6 @@ static void __init snd_hwdep_proc_init(void)
486 struct snd_info_entry *entry; 486 struct snd_info_entry *entry;
487 487
488 if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) { 488 if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) {
489 entry->c.text.read_size = PAGE_SIZE;
490 entry->c.text.read = snd_hwdep_proc_read; 489 entry->c.text.read = snd_hwdep_proc_read;
491 if (snd_info_register(entry) < 0) { 490 if (snd_info_register(entry) < 0) {
492 snd_info_free_entry(entry); 491 snd_info_free_entry(entry);
diff --git a/sound/core/info.c b/sound/core/info.c
index 2582b74d3199..10c1772bf3ea 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -21,7 +21,6 @@
21 21
22#include <sound/driver.h> 22#include <sound/driver.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/vmalloc.h>
25#include <linux/time.h> 24#include <linux/time.h>
26#include <linux/smp_lock.h> 25#include <linux/smp_lock.h>
27#include <linux/string.h> 26#include <linux/string.h>
@@ -82,6 +81,24 @@ static int snd_info_version_init(void);
82static int snd_info_version_done(void); 81static int snd_info_version_done(void);
83 82
84 83
84/* resize the proc r/w buffer */
85static int resize_info_buffer(struct snd_info_buffer *buffer,
86 unsigned int nsize)
87{
88 char *nbuf;
89
90 nsize = PAGE_ALIGN(nsize);
91 nbuf = kmalloc(nsize, GFP_KERNEL);
92 if (! nbuf)
93 return -ENOMEM;
94
95 memcpy(nbuf, buffer->buffer, buffer->len);
96 kfree(buffer->buffer);
97 buffer->buffer = nbuf;
98 buffer->len = nsize;
99 return 0;
100}
101
85/** 102/**
86 * snd_iprintf - printf on the procfs buffer 103 * snd_iprintf - printf on the procfs buffer
87 * @buffer: the procfs buffer 104 * @buffer: the procfs buffer
@@ -95,30 +112,43 @@ int snd_iprintf(struct snd_info_buffer *buffer, char *fmt,...)
95{ 112{
96 va_list args; 113 va_list args;
97 int len, res; 114 int len, res;
115 int err = 0;
98 116
117 might_sleep();
99 if (buffer->stop || buffer->error) 118 if (buffer->stop || buffer->error)
100 return 0; 119 return 0;
101 len = buffer->len - buffer->size; 120 len = buffer->len - buffer->size;
102 va_start(args, fmt); 121 va_start(args, fmt);
103 res = vsnprintf(buffer->curr, len, fmt, args); 122 for (;;) {
104 va_end(args); 123 res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, args);
105 if (res >= len) { 124 if (res < len)
106 buffer->stop = 1; 125 break;
107 return 0; 126 err = resize_info_buffer(buffer, buffer->len + PAGE_SIZE);
127 if (err < 0)
128 break;
129 len = buffer->len - buffer->size;
108 } 130 }
131 va_end(args);
132
133 if (err < 0)
134 return err;
109 buffer->curr += res; 135 buffer->curr += res;
110 buffer->size += res; 136 buffer->size += res;
111 return res; 137 return res;
112} 138}
113 139
140EXPORT_SYMBOL(snd_iprintf);
141
114/* 142/*
115 143
116 */ 144 */
117 145
118static struct proc_dir_entry *snd_proc_root = NULL; 146static struct proc_dir_entry *snd_proc_root;
119struct snd_info_entry *snd_seq_root = NULL; 147struct snd_info_entry *snd_seq_root;
148EXPORT_SYMBOL(snd_seq_root);
149
120#ifdef CONFIG_SND_OSSEMUL 150#ifdef CONFIG_SND_OSSEMUL
121struct snd_info_entry *snd_oss_root = NULL; 151struct snd_info_entry *snd_oss_root;
122#endif 152#endif
123 153
124static inline void snd_info_entry_prepare(struct proc_dir_entry *de) 154static inline void snd_info_entry_prepare(struct proc_dir_entry *de)
@@ -221,7 +251,7 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
221 struct snd_info_private_data *data; 251 struct snd_info_private_data *data;
222 struct snd_info_entry *entry; 252 struct snd_info_entry *entry;
223 struct snd_info_buffer *buf; 253 struct snd_info_buffer *buf;
224 size_t size = 0; 254 ssize_t size = 0;
225 loff_t pos; 255 loff_t pos;
226 256
227 data = file->private_data; 257 data = file->private_data;
@@ -237,14 +267,20 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
237 buf = data->wbuffer; 267 buf = data->wbuffer;
238 if (buf == NULL) 268 if (buf == NULL)
239 return -EIO; 269 return -EIO;
240 if (pos >= buf->len) 270 mutex_lock(&entry->access);
241 return -ENOMEM; 271 if (pos + count >= buf->len) {
242 size = buf->len - pos; 272 if (resize_info_buffer(buf, pos + count)) {
243 size = min(count, size); 273 mutex_unlock(&entry->access);
244 if (copy_from_user(buf->buffer + pos, buffer, size)) 274 return -ENOMEM;
275 }
276 }
277 if (copy_from_user(buf->buffer + pos, buffer, count)) {
278 mutex_unlock(&entry->access);
245 return -EFAULT; 279 return -EFAULT;
246 if ((long)buf->size < pos + size) 280 }
247 buf->size = pos + size; 281 buf->size = pos + count;
282 mutex_unlock(&entry->access);
283 size = count;
248 break; 284 break;
249 case SNDRV_INFO_CONTENT_DATA: 285 case SNDRV_INFO_CONTENT_DATA:
250 if (entry->c.ops->write) 286 if (entry->c.ops->write)
@@ -279,18 +315,14 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
279 } 315 }
280 mode = file->f_flags & O_ACCMODE; 316 mode = file->f_flags & O_ACCMODE;
281 if (mode == O_RDONLY || mode == O_RDWR) { 317 if (mode == O_RDONLY || mode == O_RDWR) {
282 if ((entry->content == SNDRV_INFO_CONTENT_TEXT && 318 if ((entry->content == SNDRV_INFO_CONTENT_DATA &&
283 !entry->c.text.read_size) ||
284 (entry->content == SNDRV_INFO_CONTENT_DATA &&
285 entry->c.ops->read == NULL)) { 319 entry->c.ops->read == NULL)) {
286 err = -ENODEV; 320 err = -ENODEV;
287 goto __error; 321 goto __error;
288 } 322 }
289 } 323 }
290 if (mode == O_WRONLY || mode == O_RDWR) { 324 if (mode == O_WRONLY || mode == O_RDWR) {
291 if ((entry->content == SNDRV_INFO_CONTENT_TEXT && 325 if ((entry->content == SNDRV_INFO_CONTENT_DATA &&
292 !entry->c.text.write_size) ||
293 (entry->content == SNDRV_INFO_CONTENT_DATA &&
294 entry->c.ops->write == NULL)) { 326 entry->c.ops->write == NULL)) {
295 err = -ENODEV; 327 err = -ENODEV;
296 goto __error; 328 goto __error;
@@ -306,49 +338,23 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
306 case SNDRV_INFO_CONTENT_TEXT: 338 case SNDRV_INFO_CONTENT_TEXT:
307 if (mode == O_RDONLY || mode == O_RDWR) { 339 if (mode == O_RDONLY || mode == O_RDWR) {
308 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); 340 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
309 if (buffer == NULL) { 341 if (buffer == NULL)
310 kfree(data); 342 goto __nomem;
311 err = -ENOMEM;
312 goto __error;
313 }
314 buffer->len = (entry->c.text.read_size +
315 (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
316 buffer->buffer = vmalloc(buffer->len);
317 if (buffer->buffer == NULL) {
318 kfree(buffer);
319 kfree(data);
320 err = -ENOMEM;
321 goto __error;
322 }
323 buffer->curr = buffer->buffer;
324 data->rbuffer = buffer; 343 data->rbuffer = buffer;
344 buffer->len = PAGE_SIZE;
345 buffer->buffer = kmalloc(buffer->len, GFP_KERNEL);
346 if (buffer->buffer == NULL)
347 goto __nomem;
325 } 348 }
326 if (mode == O_WRONLY || mode == O_RDWR) { 349 if (mode == O_WRONLY || mode == O_RDWR) {
327 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); 350 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
328 if (buffer == NULL) { 351 if (buffer == NULL)
329 if (mode == O_RDWR) { 352 goto __nomem;
330 vfree(data->rbuffer->buffer);
331 kfree(data->rbuffer);
332 }
333 kfree(data);
334 err = -ENOMEM;
335 goto __error;
336 }
337 buffer->len = (entry->c.text.write_size +
338 (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
339 buffer->buffer = vmalloc(buffer->len);
340 if (buffer->buffer == NULL) {
341 if (mode == O_RDWR) {
342 vfree(data->rbuffer->buffer);
343 kfree(data->rbuffer);
344 }
345 kfree(buffer);
346 kfree(data);
347 err = -ENOMEM;
348 goto __error;
349 }
350 buffer->curr = buffer->buffer;
351 data->wbuffer = buffer; 353 data->wbuffer = buffer;
354 buffer->len = PAGE_SIZE;
355 buffer->buffer = kmalloc(buffer->len, GFP_KERNEL);
356 if (buffer->buffer == NULL)
357 goto __nomem;
352 } 358 }
353 break; 359 break;
354 case SNDRV_INFO_CONTENT_DATA: /* data */ 360 case SNDRV_INFO_CONTENT_DATA: /* data */
@@ -373,6 +379,17 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
373 } 379 }
374 return 0; 380 return 0;
375 381
382 __nomem:
383 if (data->rbuffer) {
384 kfree(data->rbuffer->buffer);
385 kfree(data->rbuffer);
386 }
387 if (data->wbuffer) {
388 kfree(data->wbuffer->buffer);
389 kfree(data->wbuffer);
390 }
391 kfree(data);
392 err = -ENOMEM;
376 __error: 393 __error:
377 module_put(entry->module); 394 module_put(entry->module);
378 __error1: 395 __error1:
@@ -391,11 +408,11 @@ static int snd_info_entry_release(struct inode *inode, struct file *file)
391 entry = data->entry; 408 entry = data->entry;
392 switch (entry->content) { 409 switch (entry->content) {
393 case SNDRV_INFO_CONTENT_TEXT: 410 case SNDRV_INFO_CONTENT_TEXT:
394 if (mode == O_RDONLY || mode == O_RDWR) { 411 if (data->rbuffer) {
395 vfree(data->rbuffer->buffer); 412 kfree(data->rbuffer->buffer);
396 kfree(data->rbuffer); 413 kfree(data->rbuffer);
397 } 414 }
398 if (mode == O_WRONLY || mode == O_RDWR) { 415 if (data->wbuffer) {
399 if (entry->c.text.write) { 416 if (entry->c.text.write) {
400 entry->c.text.write(entry, data->wbuffer); 417 entry->c.text.write(entry, data->wbuffer);
401 if (data->wbuffer->error) { 418 if (data->wbuffer->error) {
@@ -404,7 +421,7 @@ static int snd_info_entry_release(struct inode *inode, struct file *file)
404 data->wbuffer->error); 421 data->wbuffer->error);
405 } 422 }
406 } 423 }
407 vfree(data->wbuffer->buffer); 424 kfree(data->wbuffer->buffer);
408 kfree(data->wbuffer); 425 kfree(data->wbuffer);
409 } 426 }
410 break; 427 break;
@@ -664,29 +681,29 @@ int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len)
664 if (len <= 0 || buffer->stop || buffer->error) 681 if (len <= 0 || buffer->stop || buffer->error)
665 return 1; 682 return 1;
666 while (--len > 0) { 683 while (--len > 0) {
667 c = *buffer->curr++; 684 c = buffer->buffer[buffer->curr++];
668 if (c == '\n') { 685 if (c == '\n') {
669 if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { 686 if (buffer->curr >= buffer->size)
670 buffer->stop = 1; 687 buffer->stop = 1;
671 }
672 break; 688 break;
673 } 689 }
674 *line++ = c; 690 *line++ = c;
675 if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { 691 if (buffer->curr >= buffer->size) {
676 buffer->stop = 1; 692 buffer->stop = 1;
677 break; 693 break;
678 } 694 }
679 } 695 }
680 while (c != '\n' && !buffer->stop) { 696 while (c != '\n' && !buffer->stop) {
681 c = *buffer->curr++; 697 c = buffer->buffer[buffer->curr++];
682 if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { 698 if (buffer->curr >= buffer->size)
683 buffer->stop = 1; 699 buffer->stop = 1;
684 }
685 } 700 }
686 *line = '\0'; 701 *line = '\0';
687 return 0; 702 return 0;
688} 703}
689 704
705EXPORT_SYMBOL(snd_info_get_line);
706
690/** 707/**
691 * snd_info_get_str - parse a string token 708 * snd_info_get_str - parse a string token
692 * @dest: the buffer to store the string token 709 * @dest: the buffer to store the string token
@@ -723,6 +740,8 @@ char *snd_info_get_str(char *dest, char *src, int len)
723 return src; 740 return src;
724} 741}
725 742
743EXPORT_SYMBOL(snd_info_get_str);
744
726/** 745/**
727 * snd_info_create_entry - create an info entry 746 * snd_info_create_entry - create an info entry
728 * @name: the proc file name 747 * @name: the proc file name
@@ -774,6 +793,8 @@ struct snd_info_entry *snd_info_create_module_entry(struct module * module,
774 return entry; 793 return entry;
775} 794}
776 795
796EXPORT_SYMBOL(snd_info_create_module_entry);
797
777/** 798/**
778 * snd_info_create_card_entry - create an info entry for the given card 799 * snd_info_create_card_entry - create an info entry for the given card
779 * @card: the card instance 800 * @card: the card instance
@@ -797,6 +818,8 @@ struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card,
797 return entry; 818 return entry;
798} 819}
799 820
821EXPORT_SYMBOL(snd_info_create_card_entry);
822
800static int snd_info_dev_free_entry(struct snd_device *device) 823static int snd_info_dev_free_entry(struct snd_device *device)
801{ 824{
802 struct snd_info_entry *entry = device->device_data; 825 struct snd_info_entry *entry = device->device_data;
@@ -867,6 +890,8 @@ int snd_card_proc_new(struct snd_card *card, const char *name,
867 return 0; 890 return 0;
868} 891}
869 892
893EXPORT_SYMBOL(snd_card_proc_new);
894
870/** 895/**
871 * snd_info_free_entry - release the info entry 896 * snd_info_free_entry - release the info entry
872 * @entry: the info entry 897 * @entry: the info entry
@@ -883,6 +908,8 @@ void snd_info_free_entry(struct snd_info_entry * entry)
883 kfree(entry); 908 kfree(entry);
884} 909}
885 910
911EXPORT_SYMBOL(snd_info_free_entry);
912
886/** 913/**
887 * snd_info_register - register the info entry 914 * snd_info_register - register the info entry
888 * @entry: the info entry 915 * @entry: the info entry
@@ -913,6 +940,8 @@ int snd_info_register(struct snd_info_entry * entry)
913 return 0; 940 return 0;
914} 941}
915 942
943EXPORT_SYMBOL(snd_info_register);
944
916/** 945/**
917 * snd_info_unregister - de-register the info entry 946 * snd_info_unregister - de-register the info entry
918 * @entry: the info entry 947 * @entry: the info entry
@@ -937,11 +966,13 @@ int snd_info_unregister(struct snd_info_entry * entry)
937 return 0; 966 return 0;
938} 967}
939 968
969EXPORT_SYMBOL(snd_info_unregister);
970
940/* 971/*
941 972
942 */ 973 */
943 974
944static struct snd_info_entry *snd_info_version_entry = NULL; 975static struct snd_info_entry *snd_info_version_entry;
945 976
946static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 977static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
947{ 978{
@@ -958,7 +989,6 @@ static int __init snd_info_version_init(void)
958 entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL); 989 entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL);
959 if (entry == NULL) 990 if (entry == NULL)
960 return -ENOMEM; 991 return -ENOMEM;
961 entry->c.text.read_size = 256;
962 entry->c.text.read = snd_info_version_read; 992 entry->c.text.read = snd_info_version_read;
963 if (snd_info_register(entry) < 0) { 993 if (snd_info_register(entry) < 0) {
964 snd_info_free_entry(entry); 994 snd_info_free_entry(entry);
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index f9ce854b3d11..bb2c40d0ab66 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -64,6 +64,8 @@ int snd_oss_info_register(int dev, int num, char *string)
64 return 0; 64 return 0;
65} 65}
66 66
67EXPORT_SYMBOL(snd_oss_info_register);
68
67extern void snd_card_info_read_oss(struct snd_info_buffer *buffer); 69extern void snd_card_info_read_oss(struct snd_info_buffer *buffer);
68 70
69static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev) 71static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev)
@@ -117,7 +119,6 @@ int snd_info_minor_register(void)
117 119
118 memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings)); 120 memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings));
119 if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", snd_oss_root)) != NULL) { 121 if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", snd_oss_root)) != NULL) {
120 entry->c.text.read_size = 2048;
121 entry->c.text.read = snd_sndstat_proc_read; 122 entry->c.text.read = snd_sndstat_proc_read;
122 if (snd_info_register(entry) < 0) { 123 if (snd_info_register(entry) < 0) {
123 snd_info_free_entry(entry); 124 snd_info_free_entry(entry);
diff --git a/sound/core/init.c b/sound/core/init.c
index 39ed2e5bb0af..4d9258884e44 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -38,12 +38,15 @@ struct snd_shutdown_f_ops {
38 struct snd_shutdown_f_ops *next; 38 struct snd_shutdown_f_ops *next;
39}; 39};
40 40
41unsigned int snd_cards_lock = 0; /* locked for registering/using */ 41static unsigned int snd_cards_lock; /* locked for registering/using */
42struct snd_card *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL}; 42struct snd_card *snd_cards[SNDRV_CARDS];
43DEFINE_RWLOCK(snd_card_rwlock); 43EXPORT_SYMBOL(snd_cards);
44
45static DEFINE_MUTEX(snd_card_mutex);
44 46
45#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 47#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
46int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag); 48int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag);
49EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
47#endif 50#endif
48 51
49#ifdef CONFIG_PROC_FS 52#ifdef CONFIG_PROC_FS
@@ -66,7 +69,6 @@ static inline int init_info_for_card(struct snd_card *card)
66 snd_printd("unable to create card entry\n"); 69 snd_printd("unable to create card entry\n");
67 return err; 70 return err;
68 } 71 }
69 entry->c.text.read_size = PAGE_SIZE;
70 entry->c.text.read = snd_card_id_read; 72 entry->c.text.read = snd_card_id_read;
71 if (snd_info_register(entry) < 0) { 73 if (snd_info_register(entry) < 0) {
72 snd_info_free_entry(entry); 74 snd_info_free_entry(entry);
@@ -110,7 +112,7 @@ struct snd_card *snd_card_new(int idx, const char *xid,
110 strlcpy(card->id, xid, sizeof(card->id)); 112 strlcpy(card->id, xid, sizeof(card->id));
111 } 113 }
112 err = 0; 114 err = 0;
113 write_lock(&snd_card_rwlock); 115 mutex_lock(&snd_card_mutex);
114 if (idx < 0) { 116 if (idx < 0) {
115 int idx2; 117 int idx2;
116 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) 118 for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
@@ -128,12 +130,12 @@ struct snd_card *snd_card_new(int idx, const char *xid,
128 else 130 else
129 err = -ENODEV; 131 err = -ENODEV;
130 if (idx < 0 || err < 0) { 132 if (idx < 0 || err < 0) {
131 write_unlock(&snd_card_rwlock); 133 mutex_unlock(&snd_card_mutex);
132 snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1); 134 snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1);
133 goto __error; 135 goto __error;
134 } 136 }
135 snd_cards_lock |= 1 << idx; /* lock it */ 137 snd_cards_lock |= 1 << idx; /* lock it */
136 write_unlock(&snd_card_rwlock); 138 mutex_unlock(&snd_card_mutex);
137 card->number = idx; 139 card->number = idx;
138 card->module = module; 140 card->module = module;
139 INIT_LIST_HEAD(&card->devices); 141 INIT_LIST_HEAD(&card->devices);
@@ -169,6 +171,19 @@ struct snd_card *snd_card_new(int idx, const char *xid,
169 return NULL; 171 return NULL;
170} 172}
171 173
174EXPORT_SYMBOL(snd_card_new);
175
176/* return non-zero if a card is already locked */
177int snd_card_locked(int card)
178{
179 int locked;
180
181 mutex_lock(&snd_card_mutex);
182 locked = snd_cards_lock & (1 << card);
183 mutex_unlock(&snd_card_mutex);
184 return locked;
185}
186
172static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig) 187static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig)
173{ 188{
174 return -ENODEV; 189 return -ENODEV;
@@ -236,9 +251,9 @@ int snd_card_disconnect(struct snd_card *card)
236 spin_unlock(&card->files_lock); 251 spin_unlock(&card->files_lock);
237 252
238 /* phase 1: disable fops (user space) operations for ALSA API */ 253 /* phase 1: disable fops (user space) operations for ALSA API */
239 write_lock(&snd_card_rwlock); 254 mutex_lock(&snd_card_mutex);
240 snd_cards[card->number] = NULL; 255 snd_cards[card->number] = NULL;
241 write_unlock(&snd_card_rwlock); 256 mutex_unlock(&snd_card_mutex);
242 257
243 /* phase 2: replace file->f_op with special dummy operations */ 258 /* phase 2: replace file->f_op with special dummy operations */
244 259
@@ -298,6 +313,8 @@ int snd_card_disconnect(struct snd_card *card)
298 return 0; 313 return 0;
299} 314}
300 315
316EXPORT_SYMBOL(snd_card_disconnect);
317
301/** 318/**
302 * snd_card_free - frees given soundcard structure 319 * snd_card_free - frees given soundcard structure
303 * @card: soundcard structure 320 * @card: soundcard structure
@@ -315,9 +332,9 @@ int snd_card_free(struct snd_card *card)
315 332
316 if (card == NULL) 333 if (card == NULL)
317 return -EINVAL; 334 return -EINVAL;
318 write_lock(&snd_card_rwlock); 335 mutex_lock(&snd_card_mutex);
319 snd_cards[card->number] = NULL; 336 snd_cards[card->number] = NULL;
320 write_unlock(&snd_card_rwlock); 337 mutex_unlock(&snd_card_mutex);
321 338
322#ifdef CONFIG_PM 339#ifdef CONFIG_PM
323 wake_up(&card->power_sleep); 340 wake_up(&card->power_sleep);
@@ -353,13 +370,15 @@ int snd_card_free(struct snd_card *card)
353 card->s_f_ops = s_f_ops->next; 370 card->s_f_ops = s_f_ops->next;
354 kfree(s_f_ops); 371 kfree(s_f_ops);
355 } 372 }
356 write_lock(&snd_card_rwlock); 373 mutex_lock(&snd_card_mutex);
357 snd_cards_lock &= ~(1 << card->number); 374 snd_cards_lock &= ~(1 << card->number);
358 write_unlock(&snd_card_rwlock); 375 mutex_unlock(&snd_card_mutex);
359 kfree(card); 376 kfree(card);
360 return 0; 377 return 0;
361} 378}
362 379
380EXPORT_SYMBOL(snd_card_free);
381
363static void snd_card_free_thread(void * __card) 382static void snd_card_free_thread(void * __card)
364{ 383{
365 struct snd_card *card = __card; 384 struct snd_card *card = __card;
@@ -405,6 +424,8 @@ int snd_card_free_in_thread(struct snd_card *card)
405 return -EFAULT; 424 return -EFAULT;
406} 425}
407 426
427EXPORT_SYMBOL(snd_card_free_in_thread);
428
408static void choose_default_id(struct snd_card *card) 429static void choose_default_id(struct snd_card *card)
409{ 430{
410 int i, len, idx_flag = 0, loops = SNDRV_CARDS; 431 int i, len, idx_flag = 0, loops = SNDRV_CARDS;
@@ -487,16 +508,16 @@ int snd_card_register(struct snd_card *card)
487 snd_assert(card != NULL, return -EINVAL); 508 snd_assert(card != NULL, return -EINVAL);
488 if ((err = snd_device_register_all(card)) < 0) 509 if ((err = snd_device_register_all(card)) < 0)
489 return err; 510 return err;
490 write_lock(&snd_card_rwlock); 511 mutex_lock(&snd_card_mutex);
491 if (snd_cards[card->number]) { 512 if (snd_cards[card->number]) {
492 /* already registered */ 513 /* already registered */
493 write_unlock(&snd_card_rwlock); 514 mutex_unlock(&snd_card_mutex);
494 return 0; 515 return 0;
495 } 516 }
496 if (card->id[0] == '\0') 517 if (card->id[0] == '\0')
497 choose_default_id(card); 518 choose_default_id(card);
498 snd_cards[card->number] = card; 519 snd_cards[card->number] = card;
499 write_unlock(&snd_card_rwlock); 520 mutex_unlock(&snd_card_mutex);
500 init_info_for_card(card); 521 init_info_for_card(card);
501#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) 522#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
502 if (snd_mixer_oss_notify_callback) 523 if (snd_mixer_oss_notify_callback)
@@ -505,8 +526,10 @@ int snd_card_register(struct snd_card *card)
505 return 0; 526 return 0;
506} 527}
507 528
529EXPORT_SYMBOL(snd_card_register);
530
508#ifdef CONFIG_PROC_FS 531#ifdef CONFIG_PROC_FS
509static struct snd_info_entry *snd_card_info_entry = NULL; 532static struct snd_info_entry *snd_card_info_entry;
510 533
511static void snd_card_info_read(struct snd_info_entry *entry, 534static void snd_card_info_read(struct snd_info_entry *entry,
512 struct snd_info_buffer *buffer) 535 struct snd_info_buffer *buffer)
@@ -515,7 +538,7 @@ static void snd_card_info_read(struct snd_info_entry *entry,
515 struct snd_card *card; 538 struct snd_card *card;
516 539
517 for (idx = count = 0; idx < SNDRV_CARDS; idx++) { 540 for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
518 read_lock(&snd_card_rwlock); 541 mutex_lock(&snd_card_mutex);
519 if ((card = snd_cards[idx]) != NULL) { 542 if ((card = snd_cards[idx]) != NULL) {
520 count++; 543 count++;
521 snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n", 544 snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n",
@@ -526,7 +549,7 @@ static void snd_card_info_read(struct snd_info_entry *entry,
526 snd_iprintf(buffer, " %s\n", 549 snd_iprintf(buffer, " %s\n",
527 card->longname); 550 card->longname);
528 } 551 }
529 read_unlock(&snd_card_rwlock); 552 mutex_unlock(&snd_card_mutex);
530 } 553 }
531 if (!count) 554 if (!count)
532 snd_iprintf(buffer, "--- no soundcards ---\n"); 555 snd_iprintf(buffer, "--- no soundcards ---\n");
@@ -540,12 +563,12 @@ void snd_card_info_read_oss(struct snd_info_buffer *buffer)
540 struct snd_card *card; 563 struct snd_card *card;
541 564
542 for (idx = count = 0; idx < SNDRV_CARDS; idx++) { 565 for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
543 read_lock(&snd_card_rwlock); 566 mutex_lock(&snd_card_mutex);
544 if ((card = snd_cards[idx]) != NULL) { 567 if ((card = snd_cards[idx]) != NULL) {
545 count++; 568 count++;
546 snd_iprintf(buffer, "%s\n", card->longname); 569 snd_iprintf(buffer, "%s\n", card->longname);
547 } 570 }
548 read_unlock(&snd_card_rwlock); 571 mutex_unlock(&snd_card_mutex);
549 } 572 }
550 if (!count) { 573 if (!count) {
551 snd_iprintf(buffer, "--- no soundcards ---\n"); 574 snd_iprintf(buffer, "--- no soundcards ---\n");
@@ -563,11 +586,11 @@ static void snd_card_module_info_read(struct snd_info_entry *entry,
563 struct snd_card *card; 586 struct snd_card *card;
564 587
565 for (idx = 0; idx < SNDRV_CARDS; idx++) { 588 for (idx = 0; idx < SNDRV_CARDS; idx++) {
566 read_lock(&snd_card_rwlock); 589 mutex_lock(&snd_card_mutex);
567 if ((card = snd_cards[idx]) != NULL) 590 if ((card = snd_cards[idx]) != NULL)
568 snd_iprintf(buffer, "%2i %s\n", 591 snd_iprintf(buffer, "%2i %s\n",
569 idx, card->module->name); 592 idx, card->module->name);
570 read_unlock(&snd_card_rwlock); 593 mutex_unlock(&snd_card_mutex);
571 } 594 }
572} 595}
573#endif 596#endif
@@ -579,7 +602,6 @@ int __init snd_card_info_init(void)
579 entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL); 602 entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL);
580 if (! entry) 603 if (! entry)
581 return -ENOMEM; 604 return -ENOMEM;
582 entry->c.text.read_size = PAGE_SIZE;
583 entry->c.text.read = snd_card_info_read; 605 entry->c.text.read = snd_card_info_read;
584 if (snd_info_register(entry) < 0) { 606 if (snd_info_register(entry) < 0) {
585 snd_info_free_entry(entry); 607 snd_info_free_entry(entry);
@@ -590,7 +612,6 @@ int __init snd_card_info_init(void)
590#ifdef MODULE 612#ifdef MODULE
591 entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL); 613 entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL);
592 if (entry) { 614 if (entry) {
593 entry->c.text.read_size = PAGE_SIZE;
594 entry->c.text.read = snd_card_module_info_read; 615 entry->c.text.read = snd_card_module_info_read;
595 if (snd_info_register(entry) < 0) 616 if (snd_info_register(entry) < 0)
596 snd_info_free_entry(entry); 617 snd_info_free_entry(entry);
@@ -644,6 +665,8 @@ int snd_component_add(struct snd_card *card, const char *component)
644 return 0; 665 return 0;
645} 666}
646 667
668EXPORT_SYMBOL(snd_component_add);
669
647/** 670/**
648 * snd_card_file_add - add the file to the file list of the card 671 * snd_card_file_add - add the file to the file list of the card
649 * @card: soundcard structure 672 * @card: soundcard structure
@@ -676,6 +699,8 @@ int snd_card_file_add(struct snd_card *card, struct file *file)
676 return 0; 699 return 0;
677} 700}
678 701
702EXPORT_SYMBOL(snd_card_file_add);
703
679/** 704/**
680 * snd_card_file_remove - remove the file from the file list 705 * snd_card_file_remove - remove the file from the file list
681 * @card: soundcard structure 706 * @card: soundcard structure
@@ -717,6 +742,8 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
717 return 0; 742 return 0;
718} 743}
719 744
745EXPORT_SYMBOL(snd_card_file_remove);
746
720#ifdef CONFIG_PM 747#ifdef CONFIG_PM
721/** 748/**
722 * snd_power_wait - wait until the power-state is changed. 749 * snd_power_wait - wait until the power-state is changed.
@@ -753,4 +780,5 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state)
753 return result; 780 return result;
754} 781}
755 782
783EXPORT_SYMBOL(snd_power_wait);
756#endif /* CONFIG_PM */ 784#endif /* CONFIG_PM */
diff --git a/sound/core/isadma.c b/sound/core/isadma.c
index 1a378951da5b..d52398727f0a 100644
--- a/sound/core/isadma.c
+++ b/sound/core/isadma.c
@@ -56,6 +56,8 @@ void snd_dma_program(unsigned long dma,
56 release_dma_lock(flags); 56 release_dma_lock(flags);
57} 57}
58 58
59EXPORT_SYMBOL(snd_dma_program);
60
59/** 61/**
60 * snd_dma_disable - stop the ISA DMA transfer 62 * snd_dma_disable - stop the ISA DMA transfer
61 * @dma: the dma number 63 * @dma: the dma number
@@ -72,6 +74,8 @@ void snd_dma_disable(unsigned long dma)
72 release_dma_lock(flags); 74 release_dma_lock(flags);
73} 75}
74 76
77EXPORT_SYMBOL(snd_dma_disable);
78
75/** 79/**
76 * snd_dma_pointer - return the current pointer to DMA transfer buffer in bytes 80 * snd_dma_pointer - return the current pointer to DMA transfer buffer in bytes
77 * @dma: the dma number 81 * @dma: the dma number
@@ -101,3 +105,5 @@ unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
101 else 105 else
102 return size - result; 106 return size - result;
103} 107}
108
109EXPORT_SYMBOL(snd_dma_pointer);
diff --git a/sound/core/memory.c b/sound/core/memory.c
index 862d62d2e144..fe59850be868 100644
--- a/sound/core/memory.c
+++ b/sound/core/memory.c
@@ -21,6 +21,7 @@
21 */ 21 */
22 22
23#include <linux/config.h> 23#include <linux/config.h>
24#include <linux/module.h>
24#include <asm/io.h> 25#include <asm/io.h>
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26 27
@@ -55,6 +56,8 @@ int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size
55#endif 56#endif
56} 57}
57 58
59EXPORT_SYMBOL(copy_to_user_fromio);
60
58/** 61/**
59 * copy_from_user_toio - copy data from user-space to mmio-space 62 * copy_from_user_toio - copy data from user-space to mmio-space
60 * @dst: the destination pointer on mmio-space 63 * @dst: the destination pointer on mmio-space
@@ -85,3 +88,5 @@ int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size
85 return 0; 88 return 0;
86#endif 89#endif
87} 90}
91
92EXPORT_SYMBOL(copy_from_user_toio);
diff --git a/sound/core/misc.c b/sound/core/misc.c
index b53e563c09e6..03fc711f4127 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -34,6 +34,8 @@ void release_and_free_resource(struct resource *res)
34 } 34 }
35} 35}
36 36
37EXPORT_SYMBOL(release_and_free_resource);
38
37#ifdef CONFIG_SND_VERBOSE_PRINTK 39#ifdef CONFIG_SND_VERBOSE_PRINTK
38void snd_verbose_printk(const char *file, int line, const char *format, ...) 40void snd_verbose_printk(const char *file, int line, const char *format, ...)
39{ 41{
@@ -51,6 +53,8 @@ void snd_verbose_printk(const char *file, int line, const char *format, ...)
51 vprintk(format, args); 53 vprintk(format, args);
52 va_end(args); 54 va_end(args);
53} 55}
56
57EXPORT_SYMBOL(snd_verbose_printk);
54#endif 58#endif
55 59
56#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK) 60#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
@@ -71,4 +75,6 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
71 va_end(args); 75 va_end(args);
72 76
73} 77}
78
79EXPORT_SYMBOL(snd_verbose_printd);
74#endif 80#endif
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 9c68bc3f97aa..71b5080fa66d 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1182,9 +1182,7 @@ static void snd_mixer_oss_proc_init(struct snd_mixer_oss *mixer)
1182 return; 1182 return;
1183 entry->content = SNDRV_INFO_CONTENT_TEXT; 1183 entry->content = SNDRV_INFO_CONTENT_TEXT;
1184 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 1184 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
1185 entry->c.text.read_size = 8192;
1186 entry->c.text.read = snd_mixer_oss_proc_read; 1185 entry->c.text.read = snd_mixer_oss_proc_read;
1187 entry->c.text.write_size = 8192;
1188 entry->c.text.write = snd_mixer_oss_proc_write; 1186 entry->c.text.write = snd_mixer_oss_proc_write;
1189 entry->private_data = mixer; 1187 entry->private_data = mixer;
1190 if (snd_info_register(entry) < 0) { 1188 if (snd_info_register(entry) < 0) {
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index ac990bf0b48f..f5ff4f4a16ee 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -45,7 +45,7 @@
45 45
46#define OSS_ALSAEMULVER _SIOR ('M', 249, int) 46#define OSS_ALSAEMULVER _SIOR ('M', 249, int)
47 47
48static int dsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0}; 48static int dsp_map[SNDRV_CARDS];
49static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; 49static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
50static int nonblock_open = 1; 50static int nonblock_open = 1;
51 51
@@ -78,6 +78,487 @@ static inline void snd_leave_user(mm_segment_t fs)
78 set_fs(fs); 78 set_fs(fs);
79} 79}
80 80
81/*
82 * helper functions to process hw_params
83 */
84static int snd_interval_refine_min(struct snd_interval *i, unsigned int min, int openmin)
85{
86 int changed = 0;
87 if (i->min < min) {
88 i->min = min;
89 i->openmin = openmin;
90 changed = 1;
91 } else if (i->min == min && !i->openmin && openmin) {
92 i->openmin = 1;
93 changed = 1;
94 }
95 if (i->integer) {
96 if (i->openmin) {
97 i->min++;
98 i->openmin = 0;
99 }
100 }
101 if (snd_interval_checkempty(i)) {
102 snd_interval_none(i);
103 return -EINVAL;
104 }
105 return changed;
106}
107
108static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int openmax)
109{
110 int changed = 0;
111 if (i->max > max) {
112 i->max = max;
113 i->openmax = openmax;
114 changed = 1;
115 } else if (i->max == max && !i->openmax && openmax) {
116 i->openmax = 1;
117 changed = 1;
118 }
119 if (i->integer) {
120 if (i->openmax) {
121 i->max--;
122 i->openmax = 0;
123 }
124 }
125 if (snd_interval_checkempty(i)) {
126 snd_interval_none(i);
127 return -EINVAL;
128 }
129 return changed;
130}
131
132static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
133{
134 struct snd_interval t;
135 t.empty = 0;
136 t.min = t.max = val;
137 t.openmin = t.openmax = 0;
138 t.integer = 1;
139 return snd_interval_refine(i, &t);
140}
141
142/**
143 * snd_pcm_hw_param_value_min
144 * @params: the hw_params instance
145 * @var: parameter to retrieve
146 * @dir: pointer to the direction (-1,0,1) or NULL
147 *
148 * Return the minimum value for field PAR.
149 */
150static unsigned int
151snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
152 snd_pcm_hw_param_t var, int *dir)
153{
154 if (hw_is_mask(var)) {
155 if (dir)
156 *dir = 0;
157 return snd_mask_min(hw_param_mask_c(params, var));
158 }
159 if (hw_is_interval(var)) {
160 const struct snd_interval *i = hw_param_interval_c(params, var);
161 if (dir)
162 *dir = i->openmin;
163 return snd_interval_min(i);
164 }
165 return -EINVAL;
166}
167
168/**
169 * snd_pcm_hw_param_value_max
170 * @params: the hw_params instance
171 * @var: parameter to retrieve
172 * @dir: pointer to the direction (-1,0,1) or NULL
173 *
174 * Return the maximum value for field PAR.
175 */
176static unsigned int
177snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
178 snd_pcm_hw_param_t var, int *dir)
179{
180 if (hw_is_mask(var)) {
181 if (dir)
182 *dir = 0;
183 return snd_mask_max(hw_param_mask_c(params, var));
184 }
185 if (hw_is_interval(var)) {
186 const struct snd_interval *i = hw_param_interval_c(params, var);
187 if (dir)
188 *dir = - (int) i->openmax;
189 return snd_interval_max(i);
190 }
191 return -EINVAL;
192}
193
194static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params,
195 snd_pcm_hw_param_t var,
196 const struct snd_mask *val)
197{
198 int changed;
199 changed = snd_mask_refine(hw_param_mask(params, var), val);
200 if (changed) {
201 params->cmask |= 1 << var;
202 params->rmask |= 1 << var;
203 }
204 return changed;
205}
206
207static int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm,
208 struct snd_pcm_hw_params *params,
209 snd_pcm_hw_param_t var,
210 const struct snd_mask *val)
211{
212 int changed = _snd_pcm_hw_param_mask(params, var, val);
213 if (changed < 0)
214 return changed;
215 if (params->rmask) {
216 int err = snd_pcm_hw_refine(pcm, params);
217 if (err < 0)
218 return err;
219 }
220 return 0;
221}
222
223static int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params,
224 snd_pcm_hw_param_t var, unsigned int val,
225 int dir)
226{
227 int changed;
228 int open = 0;
229 if (dir) {
230 if (dir > 0) {
231 open = 1;
232 } else if (dir < 0) {
233 if (val > 0) {
234 open = 1;
235 val--;
236 }
237 }
238 }
239 if (hw_is_mask(var))
240 changed = snd_mask_refine_min(hw_param_mask(params, var),
241 val + !!open);
242 else if (hw_is_interval(var))
243 changed = snd_interval_refine_min(hw_param_interval(params, var),
244 val, open);
245 else
246 return -EINVAL;
247 if (changed) {
248 params->cmask |= 1 << var;
249 params->rmask |= 1 << var;
250 }
251 return changed;
252}
253
254/**
255 * snd_pcm_hw_param_min
256 * @pcm: PCM instance
257 * @params: the hw_params instance
258 * @var: parameter to retrieve
259 * @val: minimal value
260 * @dir: pointer to the direction (-1,0,1) or NULL
261 *
262 * Inside configuration space defined by PARAMS remove from PAR all
263 * values < VAL. Reduce configuration space accordingly.
264 * Return new minimum or -EINVAL if the configuration space is empty
265 */
266static int snd_pcm_hw_param_min(struct snd_pcm_substream *pcm,
267 struct snd_pcm_hw_params *params,
268 snd_pcm_hw_param_t var, unsigned int val,
269 int *dir)
270{
271 int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0);
272 if (changed < 0)
273 return changed;
274 if (params->rmask) {
275 int err = snd_pcm_hw_refine(pcm, params);
276 if (err < 0)
277 return err;
278 }
279 return snd_pcm_hw_param_value_min(params, var, dir);
280}
281
282static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params,
283 snd_pcm_hw_param_t var, unsigned int val,
284 int dir)
285{
286 int changed;
287 int open = 0;
288 if (dir) {
289 if (dir < 0) {
290 open = 1;
291 } else if (dir > 0) {
292 open = 1;
293 val++;
294 }
295 }
296 if (hw_is_mask(var)) {
297 if (val == 0 && open) {
298 snd_mask_none(hw_param_mask(params, var));
299 changed = -EINVAL;
300 } else
301 changed = snd_mask_refine_max(hw_param_mask(params, var),
302 val - !!open);
303 } else if (hw_is_interval(var))
304 changed = snd_interval_refine_max(hw_param_interval(params, var),
305 val, open);
306 else
307 return -EINVAL;
308 if (changed) {
309 params->cmask |= 1 << var;
310 params->rmask |= 1 << var;
311 }
312 return changed;
313}
314
315/**
316 * snd_pcm_hw_param_max
317 * @pcm: PCM instance
318 * @params: the hw_params instance
319 * @var: parameter to retrieve
320 * @val: maximal value
321 * @dir: pointer to the direction (-1,0,1) or NULL
322 *
323 * Inside configuration space defined by PARAMS remove from PAR all
324 * values >= VAL + 1. Reduce configuration space accordingly.
325 * Return new maximum or -EINVAL if the configuration space is empty
326 */
327static int snd_pcm_hw_param_max(struct snd_pcm_substream *pcm,
328 struct snd_pcm_hw_params *params,
329 snd_pcm_hw_param_t var, unsigned int val,
330 int *dir)
331{
332 int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0);
333 if (changed < 0)
334 return changed;
335 if (params->rmask) {
336 int err = snd_pcm_hw_refine(pcm, params);
337 if (err < 0)
338 return err;
339 }
340 return snd_pcm_hw_param_value_max(params, var, dir);
341}
342
343static int boundary_sub(int a, int adir,
344 int b, int bdir,
345 int *c, int *cdir)
346{
347 adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0);
348 bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0);
349 *c = a - b;
350 *cdir = adir - bdir;
351 if (*cdir == -2) {
352 (*c)--;
353 } else if (*cdir == 2) {
354 (*c)++;
355 }
356 return 0;
357}
358
359static int boundary_lt(unsigned int a, int adir,
360 unsigned int b, int bdir)
361{
362 if (adir < 0) {
363 a--;
364 adir = 1;
365 } else if (adir > 0)
366 adir = 1;
367 if (bdir < 0) {
368 b--;
369 bdir = 1;
370 } else if (bdir > 0)
371 bdir = 1;
372 return a < b || (a == b && adir < bdir);
373}
374
375/* Return 1 if min is nearer to best than max */
376static int boundary_nearer(int min, int mindir,
377 int best, int bestdir,
378 int max, int maxdir)
379{
380 int dmin, dmindir;
381 int dmax, dmaxdir;
382 boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir);
383 boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir);
384 return boundary_lt(dmin, dmindir, dmax, dmaxdir);
385}
386
387/**
388 * snd_pcm_hw_param_near
389 * @pcm: PCM instance
390 * @params: the hw_params instance
391 * @var: parameter to retrieve
392 * @best: value to set
393 * @dir: pointer to the direction (-1,0,1) or NULL
394 *
395 * Inside configuration space defined by PARAMS set PAR to the available value
396 * nearest to VAL. Reduce configuration space accordingly.
397 * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS,
398 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
399 * Return the value found.
400 */
401static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
402 struct snd_pcm_hw_params *params,
403 snd_pcm_hw_param_t var, unsigned int best,
404 int *dir)
405{
406 struct snd_pcm_hw_params *save = NULL;
407 int v;
408 unsigned int saved_min;
409 int last = 0;
410 int min, max;
411 int mindir, maxdir;
412 int valdir = dir ? *dir : 0;
413 /* FIXME */
414 if (best > INT_MAX)
415 best = INT_MAX;
416 min = max = best;
417 mindir = maxdir = valdir;
418 if (maxdir > 0)
419 maxdir = 0;
420 else if (maxdir == 0)
421 maxdir = -1;
422 else {
423 maxdir = 1;
424 max--;
425 }
426 save = kmalloc(sizeof(*save), GFP_KERNEL);
427 if (save == NULL)
428 return -ENOMEM;
429 *save = *params;
430 saved_min = min;
431 min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
432 if (min >= 0) {
433 struct snd_pcm_hw_params *params1;
434 if (max < 0)
435 goto _end;
436 if ((unsigned int)min == saved_min && mindir == valdir)
437 goto _end;
438 params1 = kmalloc(sizeof(*params1), GFP_KERNEL);
439 if (params1 == NULL) {
440 kfree(save);
441 return -ENOMEM;
442 }
443 *params1 = *save;
444 max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir);
445 if (max < 0) {
446 kfree(params1);
447 goto _end;
448 }
449 if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) {
450 *params = *params1;
451 last = 1;
452 }
453 kfree(params1);
454 } else {
455 *params = *save;
456 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
457 snd_assert(max >= 0, return -EINVAL);
458 last = 1;
459 }
460 _end:
461 kfree(save);
462 if (last)
463 v = snd_pcm_hw_param_last(pcm, params, var, dir);
464 else
465 v = snd_pcm_hw_param_first(pcm, params, var, dir);
466 snd_assert(v >= 0, return -EINVAL);
467 return v;
468}
469
470static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
471 snd_pcm_hw_param_t var, unsigned int val,
472 int dir)
473{
474 int changed;
475 if (hw_is_mask(var)) {
476 struct snd_mask *m = hw_param_mask(params, var);
477 if (val == 0 && dir < 0) {
478 changed = -EINVAL;
479 snd_mask_none(m);
480 } else {
481 if (dir > 0)
482 val++;
483 else if (dir < 0)
484 val--;
485 changed = snd_mask_refine_set(hw_param_mask(params, var), val);
486 }
487 } else if (hw_is_interval(var)) {
488 struct snd_interval *i = hw_param_interval(params, var);
489 if (val == 0 && dir < 0) {
490 changed = -EINVAL;
491 snd_interval_none(i);
492 } else if (dir == 0)
493 changed = snd_interval_refine_set(i, val);
494 else {
495 struct snd_interval t;
496 t.openmin = 1;
497 t.openmax = 1;
498 t.empty = 0;
499 t.integer = 0;
500 if (dir < 0) {
501 t.min = val - 1;
502 t.max = val;
503 } else {
504 t.min = val;
505 t.max = val+1;
506 }
507 changed = snd_interval_refine(i, &t);
508 }
509 } else
510 return -EINVAL;
511 if (changed) {
512 params->cmask |= 1 << var;
513 params->rmask |= 1 << var;
514 }
515 return changed;
516}
517
518/**
519 * snd_pcm_hw_param_set
520 * @pcm: PCM instance
521 * @params: the hw_params instance
522 * @var: parameter to retrieve
523 * @val: value to set
524 * @dir: pointer to the direction (-1,0,1) or NULL
525 *
526 * Inside configuration space defined by PARAMS remove from PAR all
527 * values != VAL. Reduce configuration space accordingly.
528 * Return VAL or -EINVAL if the configuration space is empty
529 */
530static int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm,
531 struct snd_pcm_hw_params *params,
532 snd_pcm_hw_param_t var, unsigned int val,
533 int dir)
534{
535 int changed = _snd_pcm_hw_param_set(params, var, val, dir);
536 if (changed < 0)
537 return changed;
538 if (params->rmask) {
539 int err = snd_pcm_hw_refine(pcm, params);
540 if (err < 0)
541 return err;
542 }
543 return snd_pcm_hw_param_value(params, var, NULL);
544}
545
546static int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params,
547 snd_pcm_hw_param_t var)
548{
549 int changed;
550 changed = snd_interval_setinteger(hw_param_interval(params, var));
551 if (changed) {
552 params->cmask |= 1 << var;
553 params->rmask |= 1 << var;
554 }
555 return changed;
556}
557
558/*
559 * plugin
560 */
561
81#ifdef CONFIG_SND_PCM_OSS_PLUGINS 562#ifdef CONFIG_SND_PCM_OSS_PLUGINS
82static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream) 563static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream)
83{ 564{
@@ -203,7 +684,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
203 oss_buffer_size = snd_pcm_plug_client_size(substream, 684 oss_buffer_size = snd_pcm_plug_client_size(substream,
204 snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size; 685 snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size;
205 oss_buffer_size = 1 << ld2(oss_buffer_size); 686 oss_buffer_size = 1 << ld2(oss_buffer_size);
206 if (atomic_read(&runtime->mmap_count)) { 687 if (atomic_read(&substream->mmap_count)) {
207 if (oss_buffer_size > runtime->oss.mmap_bytes) 688 if (oss_buffer_size > runtime->oss.mmap_bytes)
208 oss_buffer_size = runtime->oss.mmap_bytes; 689 oss_buffer_size = runtime->oss.mmap_bytes;
209 } 690 }
@@ -338,7 +819,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
338 goto failure; 819 goto failure;
339 } 820 }
340 821
341 if (atomic_read(&runtime->mmap_count)) 822 if (atomic_read(&substream->mmap_count))
342 direct = 1; 823 direct = 1;
343 else 824 else
344 direct = substream->oss.setup.direct; 825 direct = substream->oss.setup.direct;
@@ -347,7 +828,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
347 _snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS); 828 _snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS);
348 _snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0); 829 _snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0);
349 snd_mask_none(&mask); 830 snd_mask_none(&mask);
350 if (atomic_read(&runtime->mmap_count)) 831 if (atomic_read(&substream->mmap_count))
351 snd_mask_set(&mask, SNDRV_PCM_ACCESS_MMAP_INTERLEAVED); 832 snd_mask_set(&mask, SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
352 else { 833 else {
353 snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_INTERLEAVED); 834 snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_INTERLEAVED);
@@ -466,7 +947,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
466 } else { 947 } else {
467 sw_params->start_threshold = runtime->boundary; 948 sw_params->start_threshold = runtime->boundary;
468 } 949 }
469 if (atomic_read(&runtime->mmap_count) || substream->stream == SNDRV_PCM_STREAM_CAPTURE) 950 if (atomic_read(&substream->mmap_count) ||
951 substream->stream == SNDRV_PCM_STREAM_CAPTURE)
470 sw_params->stop_threshold = runtime->boundary; 952 sw_params->stop_threshold = runtime->boundary;
471 else 953 else
472 sw_params->stop_threshold = runtime->buffer_size; 954 sw_params->stop_threshold = runtime->buffer_size;
@@ -476,7 +958,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
476 sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 958 sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
477 1 : runtime->period_size; 959 1 : runtime->period_size;
478 sw_params->xfer_align = 1; 960 sw_params->xfer_align = 1;
479 if (atomic_read(&runtime->mmap_count) || 961 if (atomic_read(&substream->mmap_count) ||
480 substream->oss.setup.nosilence) { 962 substream->oss.setup.nosilence) {
481 sw_params->silence_threshold = 0; 963 sw_params->silence_threshold = 0;
482 sw_params->silence_size = 0; 964 sw_params->silence_size = 0;
@@ -820,7 +1302,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
820 ssize_t tmp; 1302 ssize_t tmp;
821 struct snd_pcm_runtime *runtime = substream->runtime; 1303 struct snd_pcm_runtime *runtime = substream->runtime;
822 1304
823 if (atomic_read(&runtime->mmap_count)) 1305 if (atomic_read(&substream->mmap_count))
824 return -ENXIO; 1306 return -ENXIO;
825 1307
826 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) 1308 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
@@ -850,7 +1332,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
850 if (runtime->oss.period_ptr == 0 || 1332 if (runtime->oss.period_ptr == 0 ||
851 runtime->oss.period_ptr == runtime->oss.buffer_used) 1333 runtime->oss.period_ptr == runtime->oss.buffer_used)
852 runtime->oss.buffer_used = 0; 1334 runtime->oss.buffer_used = 0;
853 else if ((substream->ffile->f_flags & O_NONBLOCK) != 0) 1335 else if ((substream->f_flags & O_NONBLOCK) != 0)
854 return xfer > 0 ? xfer : -EAGAIN; 1336 return xfer > 0 ? xfer : -EAGAIN;
855 } 1337 }
856 } else { 1338 } else {
@@ -863,7 +1345,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
863 buf += tmp; 1345 buf += tmp;
864 bytes -= tmp; 1346 bytes -= tmp;
865 xfer += tmp; 1347 xfer += tmp;
866 if ((substream->ffile->f_flags & O_NONBLOCK) != 0 && 1348 if ((substream->f_flags & O_NONBLOCK) != 0 &&
867 tmp != runtime->oss.period_bytes) 1349 tmp != runtime->oss.period_bytes)
868 break; 1350 break;
869 } 1351 }
@@ -910,7 +1392,7 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
910 ssize_t tmp; 1392 ssize_t tmp;
911 struct snd_pcm_runtime *runtime = substream->runtime; 1393 struct snd_pcm_runtime *runtime = substream->runtime;
912 1394
913 if (atomic_read(&runtime->mmap_count)) 1395 if (atomic_read(&substream->mmap_count))
914 return -ENXIO; 1396 return -ENXIO;
915 1397
916 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) 1398 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
@@ -1040,7 +1522,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1040 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; 1522 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
1041 if (substream != NULL) { 1523 if (substream != NULL) {
1042 runtime = substream->runtime; 1524 runtime = substream->runtime;
1043 if (atomic_read(&runtime->mmap_count)) 1525 if (atomic_read(&substream->mmap_count))
1044 goto __direct; 1526 goto __direct;
1045 if ((err = snd_pcm_oss_make_ready(substream)) < 0) 1527 if ((err = snd_pcm_oss_make_ready(substream)) < 0)
1046 return err; 1528 return err;
@@ -1101,10 +1583,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1101 * finish sync: drain the buffer 1583 * finish sync: drain the buffer
1102 */ 1584 */
1103 __direct: 1585 __direct:
1104 saved_f_flags = substream->ffile->f_flags; 1586 saved_f_flags = substream->f_flags;
1105 substream->ffile->f_flags &= ~O_NONBLOCK; 1587 substream->f_flags &= ~O_NONBLOCK;
1106 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); 1588 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
1107 substream->ffile->f_flags = saved_f_flags; 1589 substream->f_flags = saved_f_flags;
1108 if (err < 0) 1590 if (err < 0)
1109 return err; 1591 return err;
1110 runtime->oss.prepare = 1; 1592 runtime->oss.prepare = 1;
@@ -1209,7 +1691,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
1209 1691
1210 if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0) 1692 if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
1211 return err; 1693 return err;
1212 if (atomic_read(&substream->runtime->mmap_count)) 1694 if (atomic_read(&substream->mmap_count))
1213 direct = 1; 1695 direct = 1;
1214 else 1696 else
1215 direct = substream->oss.setup.direct; 1697 direct = substream->oss.setup.direct;
@@ -1419,7 +1901,7 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1419 if (trigger & PCM_ENABLE_OUTPUT) { 1901 if (trigger & PCM_ENABLE_OUTPUT) {
1420 if (runtime->oss.trigger) 1902 if (runtime->oss.trigger)
1421 goto _skip1; 1903 goto _skip1;
1422 if (atomic_read(&psubstream->runtime->mmap_count)) 1904 if (atomic_read(&psubstream->mmap_count))
1423 snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt); 1905 snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt);
1424 runtime->oss.trigger = 1; 1906 runtime->oss.trigger = 1;
1425 runtime->start_threshold = 1; 1907 runtime->start_threshold = 1;
@@ -1537,7 +2019,7 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream
1537 if (err < 0) 2019 if (err < 0)
1538 return err; 2020 return err;
1539 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); 2021 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size);
1540 if (atomic_read(&runtime->mmap_count)) { 2022 if (atomic_read(&substream->mmap_count)) {
1541 snd_pcm_sframes_t n; 2023 snd_pcm_sframes_t n;
1542 n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt; 2024 n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt;
1543 if (n < 0) 2025 if (n < 0)
@@ -1683,9 +2165,9 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
1683 substream->oss.oss = 1; 2165 substream->oss.oss = 1;
1684 substream->oss.setup = *setup; 2166 substream->oss.setup = *setup;
1685 if (setup->nonblock) 2167 if (setup->nonblock)
1686 substream->ffile->f_flags |= O_NONBLOCK; 2168 substream->f_flags |= O_NONBLOCK;
1687 else if (setup->block) 2169 else if (setup->block)
1688 substream->ffile->f_flags &= ~O_NONBLOCK; 2170 substream->f_flags &= ~O_NONBLOCK;
1689 runtime = substream->runtime; 2171 runtime = substream->runtime;
1690 runtime->oss.params = 1; 2172 runtime->oss.params = 1;
1691 runtime->oss.trigger = 1; 2173 runtime->oss.trigger = 1;
@@ -1742,6 +2224,7 @@ static int snd_pcm_oss_open_file(struct file *file,
1742 (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX)) 2224 (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX))
1743 f_mode = FMODE_WRITE; 2225 f_mode = FMODE_WRITE;
1744 2226
2227 file->f_flags &= ~O_APPEND;
1745 for (idx = 0; idx < 2; idx++) { 2228 for (idx = 0; idx < 2; idx++) {
1746 if (setup[idx].disable) 2229 if (setup[idx].disable)
1747 continue; 2230 continue;
@@ -2059,6 +2542,7 @@ static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t coun
2059 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; 2542 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
2060 if (substream == NULL) 2543 if (substream == NULL)
2061 return -ENXIO; 2544 return -ENXIO;
2545 substream->f_flags = file->f_flags & O_NONBLOCK;
2062#ifndef OSS_DEBUG 2546#ifndef OSS_DEBUG
2063 return snd_pcm_oss_read1(substream, buf, count); 2547 return snd_pcm_oss_read1(substream, buf, count);
2064#else 2548#else
@@ -2080,6 +2564,7 @@ static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size
2080 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; 2564 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
2081 if (substream == NULL) 2565 if (substream == NULL)
2082 return -ENXIO; 2566 return -ENXIO;
2567 substream->f_flags = file->f_flags & O_NONBLOCK;
2083 result = snd_pcm_oss_write1(substream, buf, count); 2568 result = snd_pcm_oss_write1(substream, buf, count);
2084#ifdef OSS_DEBUG 2569#ifdef OSS_DEBUG
2085 printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result); 2570 printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result);
@@ -2090,7 +2575,7 @@ static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size
2090static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream) 2575static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
2091{ 2576{
2092 struct snd_pcm_runtime *runtime = substream->runtime; 2577 struct snd_pcm_runtime *runtime = substream->runtime;
2093 if (atomic_read(&runtime->mmap_count)) 2578 if (atomic_read(&substream->mmap_count))
2094 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2579 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt;
2095 else 2580 else
2096 return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames; 2581 return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames;
@@ -2099,7 +2584,7 @@ static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
2099static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream) 2584static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream)
2100{ 2585{
2101 struct snd_pcm_runtime *runtime = substream->runtime; 2586 struct snd_pcm_runtime *runtime = substream->runtime;
2102 if (atomic_read(&runtime->mmap_count)) 2587 if (atomic_read(&substream->mmap_count))
2103 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2588 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt;
2104 else 2589 else
2105 return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames; 2590 return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames;
@@ -2342,9 +2827,7 @@ static void snd_pcm_oss_proc_init(struct snd_pcm *pcm)
2342 if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) { 2827 if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) {
2343 entry->content = SNDRV_INFO_CONTENT_TEXT; 2828 entry->content = SNDRV_INFO_CONTENT_TEXT;
2344 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 2829 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
2345 entry->c.text.read_size = 8192;
2346 entry->c.text.read = snd_pcm_oss_proc_read; 2830 entry->c.text.read = snd_pcm_oss_proc_read;
2347 entry->c.text.write_size = 8192;
2348 entry->c.text.write = snd_pcm_oss_proc_write; 2831 entry->c.text.write = snd_pcm_oss_proc_write;
2349 entry->private_data = pstr; 2832 entry->private_data = pstr;
2350 if (snd_info_register(entry) < 0) { 2833 if (snd_info_register(entry) < 0) {
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 84b00038236d..7581edd7b9ff 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -351,10 +351,8 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
351 snd_iprintf(buffer, "closed\n"); 351 snd_iprintf(buffer, "closed\n");
352 return; 352 return;
353 } 353 }
354 snd_pcm_stream_lock_irq(substream);
355 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { 354 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
356 snd_iprintf(buffer, "no setup\n"); 355 snd_iprintf(buffer, "no setup\n");
357 snd_pcm_stream_unlock_irq(substream);
358 return; 356 return;
359 } 357 }
360 snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access)); 358 snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));
@@ -375,7 +373,6 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
375 snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames); 373 snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames);
376 } 374 }
377#endif 375#endif
378 snd_pcm_stream_unlock_irq(substream);
379} 376}
380 377
381static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, 378static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
@@ -387,10 +384,8 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
387 snd_iprintf(buffer, "closed\n"); 384 snd_iprintf(buffer, "closed\n");
388 return; 385 return;
389 } 386 }
390 snd_pcm_stream_lock_irq(substream);
391 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { 387 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
392 snd_iprintf(buffer, "no setup\n"); 388 snd_iprintf(buffer, "no setup\n");
393 snd_pcm_stream_unlock_irq(substream);
394 return; 389 return;
395 } 390 }
396 snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode)); 391 snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
@@ -403,7 +398,6 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
403 snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); 398 snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);
404 snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size); 399 snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);
405 snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary); 400 snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);
406 snd_pcm_stream_unlock_irq(substream);
407} 401}
408 402
409static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, 403static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
@@ -472,7 +466,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
472 pstr->proc_root = entry; 466 pstr->proc_root = entry;
473 467
474 if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) { 468 if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) {
475 snd_info_set_text_ops(entry, pstr, 256, snd_pcm_stream_proc_info_read); 469 snd_info_set_text_ops(entry, pstr, snd_pcm_stream_proc_info_read);
476 if (snd_info_register(entry) < 0) { 470 if (snd_info_register(entry) < 0) {
477 snd_info_free_entry(entry); 471 snd_info_free_entry(entry);
478 entry = NULL; 472 entry = NULL;
@@ -483,9 +477,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
483#ifdef CONFIG_SND_PCM_XRUN_DEBUG 477#ifdef CONFIG_SND_PCM_XRUN_DEBUG
484 if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug", 478 if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
485 pstr->proc_root)) != NULL) { 479 pstr->proc_root)) != NULL) {
486 entry->c.text.read_size = 64;
487 entry->c.text.read = snd_pcm_xrun_debug_read; 480 entry->c.text.read = snd_pcm_xrun_debug_read;
488 entry->c.text.write_size = 64;
489 entry->c.text.write = snd_pcm_xrun_debug_write; 481 entry->c.text.write = snd_pcm_xrun_debug_write;
490 entry->mode |= S_IWUSR; 482 entry->mode |= S_IWUSR;
491 entry->private_data = pstr; 483 entry->private_data = pstr;
@@ -537,7 +529,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
537 substream->proc_root = entry; 529 substream->proc_root = entry;
538 530
539 if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) { 531 if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) {
540 snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_info_read); 532 snd_info_set_text_ops(entry, substream,
533 snd_pcm_substream_proc_info_read);
541 if (snd_info_register(entry) < 0) { 534 if (snd_info_register(entry) < 0) {
542 snd_info_free_entry(entry); 535 snd_info_free_entry(entry);
543 entry = NULL; 536 entry = NULL;
@@ -546,7 +539,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
546 substream->proc_info_entry = entry; 539 substream->proc_info_entry = entry;
547 540
548 if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) { 541 if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) {
549 snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_hw_params_read); 542 snd_info_set_text_ops(entry, substream,
543 snd_pcm_substream_proc_hw_params_read);
550 if (snd_info_register(entry) < 0) { 544 if (snd_info_register(entry) < 0) {
551 snd_info_free_entry(entry); 545 snd_info_free_entry(entry);
552 entry = NULL; 546 entry = NULL;
@@ -555,7 +549,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
555 substream->proc_hw_params_entry = entry; 549 substream->proc_hw_params_entry = entry;
556 550
557 if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) { 551 if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) {
558 snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_sw_params_read); 552 snd_info_set_text_ops(entry, substream,
553 snd_pcm_substream_proc_sw_params_read);
559 if (snd_info_register(entry) < 0) { 554 if (snd_info_register(entry) < 0) {
560 snd_info_free_entry(entry); 555 snd_info_free_entry(entry);
561 entry = NULL; 556 entry = NULL;
@@ -564,7 +559,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
564 substream->proc_sw_params_entry = entry; 559 substream->proc_sw_params_entry = entry;
565 560
566 if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) { 561 if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) {
567 snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_status_read); 562 snd_info_set_text_ops(entry, substream,
563 snd_pcm_substream_proc_status_read);
568 if (snd_info_register(entry) < 0) { 564 if (snd_info_register(entry) < 0) {
569 snd_info_free_entry(entry); 565 snd_info_free_entry(entry);
570 entry = NULL; 566 entry = NULL;
@@ -666,11 +662,14 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
666 INIT_LIST_HEAD(&substream->self_group.substreams); 662 INIT_LIST_HEAD(&substream->self_group.substreams);
667 list_add_tail(&substream->link_list, &substream->self_group.substreams); 663 list_add_tail(&substream->link_list, &substream->self_group.substreams);
668 spin_lock_init(&substream->timer_lock); 664 spin_lock_init(&substream->timer_lock);
665 atomic_set(&substream->mmap_count, 0);
669 prev = substream; 666 prev = substream;
670 } 667 }
671 return 0; 668 return 0;
672} 669}
673 670
671EXPORT_SYMBOL(snd_pcm_new_stream);
672
674/** 673/**
675 * snd_pcm_new - create a new PCM instance 674 * snd_pcm_new - create a new PCM instance
676 * @card: the card instance 675 * @card: the card instance
@@ -730,6 +729,8 @@ int snd_pcm_new(struct snd_card *card, char *id, int device,
730 return 0; 729 return 0;
731} 730}
732 731
732EXPORT_SYMBOL(snd_pcm_new);
733
733static void snd_pcm_free_stream(struct snd_pcm_str * pstr) 734static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
734{ 735{
735 struct snd_pcm_substream *substream, *substream_next; 736 struct snd_pcm_substream *substream, *substream_next;
@@ -829,6 +830,26 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
829 return -EINVAL; 830 return -EINVAL;
830 } 831 }
831 832
833 if (file->f_flags & O_APPEND) {
834 if (prefer_subdevice < 0) {
835 if (pstr->substream_count > 1)
836 return -EINVAL; /* must be unique */
837 substream = pstr->substream;
838 } else {
839 for (substream = pstr->substream; substream;
840 substream = substream->next)
841 if (substream->number == prefer_subdevice)
842 break;
843 }
844 if (! substream)
845 return -ENODEV;
846 if (! SUBSTREAM_BUSY(substream))
847 return -EBADFD;
848 substream->ref_count++;
849 *rsubstream = substream;
850 return 0;
851 }
852
832 if (prefer_subdevice >= 0) { 853 if (prefer_subdevice >= 0) {
833 for (substream = pstr->substream; substream; substream = substream->next) 854 for (substream = pstr->substream; substream; substream = substream->next)
834 if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice) 855 if (!SUBSTREAM_BUSY(substream) && substream->number == prefer_subdevice)
@@ -864,7 +885,6 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
864 memset((void*)runtime->control, 0, size); 885 memset((void*)runtime->control, 0, size);
865 886
866 init_waitqueue_head(&runtime->sleep); 887 init_waitqueue_head(&runtime->sleep);
867 atomic_set(&runtime->mmap_count, 0);
868 init_timer(&runtime->tick_timer); 888 init_timer(&runtime->tick_timer);
869 runtime->tick_timer.function = snd_pcm_tick_timer_func; 889 runtime->tick_timer.function = snd_pcm_tick_timer_func;
870 runtime->tick_timer.data = (unsigned long) substream; 890 runtime->tick_timer.data = (unsigned long) substream;
@@ -873,7 +893,8 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
873 893
874 substream->runtime = runtime; 894 substream->runtime = runtime;
875 substream->private_data = pcm->private_data; 895 substream->private_data = pcm->private_data;
876 substream->ffile = file; 896 substream->ref_count = 1;
897 substream->f_flags = file->f_flags;
877 pstr->substream_opened++; 898 pstr->substream_opened++;
878 *rsubstream = substream; 899 *rsubstream = substream;
879 return 0; 900 return 0;
@@ -882,7 +903,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
882void snd_pcm_detach_substream(struct snd_pcm_substream *substream) 903void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
883{ 904{
884 struct snd_pcm_runtime *runtime; 905 struct snd_pcm_runtime *runtime;
885 substream->file = NULL; 906
886 runtime = substream->runtime; 907 runtime = substream->runtime;
887 snd_assert(runtime != NULL, return); 908 snd_assert(runtime != NULL, return);
888 if (runtime->private_free != NULL) 909 if (runtime->private_free != NULL)
@@ -1022,6 +1043,8 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
1022 return 0; 1043 return 0;
1023} 1044}
1024 1045
1046EXPORT_SYMBOL(snd_pcm_notify);
1047
1025#ifdef CONFIG_PROC_FS 1048#ifdef CONFIG_PROC_FS
1026/* 1049/*
1027 * Info interface 1050 * Info interface
@@ -1049,15 +1072,14 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry,
1049 mutex_unlock(&register_mutex); 1072 mutex_unlock(&register_mutex);
1050} 1073}
1051 1074
1052static struct snd_info_entry *snd_pcm_proc_entry = NULL; 1075static struct snd_info_entry *snd_pcm_proc_entry;
1053 1076
1054static void snd_pcm_proc_init(void) 1077static void snd_pcm_proc_init(void)
1055{ 1078{
1056 struct snd_info_entry *entry; 1079 struct snd_info_entry *entry;
1057 1080
1058 if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) { 1081 if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) {
1059 snd_info_set_text_ops(entry, NULL, SNDRV_CARDS * SNDRV_PCM_DEVICES * 128, 1082 snd_info_set_text_ops(entry, NULL, snd_pcm_proc_read);
1060 snd_pcm_proc_read);
1061 if (snd_info_register(entry) < 0) { 1083 if (snd_info_register(entry) < 0) {
1062 snd_info_free_entry(entry); 1084 snd_info_free_entry(entry);
1063 entry = NULL; 1085 entry = NULL;
@@ -1099,33 +1121,3 @@ static void __exit alsa_pcm_exit(void)
1099 1121
1100module_init(alsa_pcm_init) 1122module_init(alsa_pcm_init)
1101module_exit(alsa_pcm_exit) 1123module_exit(alsa_pcm_exit)
1102
1103EXPORT_SYMBOL(snd_pcm_new);
1104EXPORT_SYMBOL(snd_pcm_new_stream);
1105EXPORT_SYMBOL(snd_pcm_notify);
1106EXPORT_SYMBOL(snd_pcm_open_substream);
1107EXPORT_SYMBOL(snd_pcm_release_substream);
1108 /* pcm_native.c */
1109EXPORT_SYMBOL(snd_pcm_link_rwlock);
1110#ifdef CONFIG_PM
1111EXPORT_SYMBOL(snd_pcm_suspend);
1112EXPORT_SYMBOL(snd_pcm_suspend_all);
1113#endif
1114EXPORT_SYMBOL(snd_pcm_kernel_ioctl);
1115EXPORT_SYMBOL(snd_pcm_mmap_data);
1116#if SNDRV_PCM_INFO_MMAP_IOMEM
1117EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
1118#endif
1119 /* pcm_misc.c */
1120EXPORT_SYMBOL(snd_pcm_format_signed);
1121EXPORT_SYMBOL(snd_pcm_format_unsigned);
1122EXPORT_SYMBOL(snd_pcm_format_linear);
1123EXPORT_SYMBOL(snd_pcm_format_little_endian);
1124EXPORT_SYMBOL(snd_pcm_format_big_endian);
1125EXPORT_SYMBOL(snd_pcm_format_width);
1126EXPORT_SYMBOL(snd_pcm_format_physical_width);
1127EXPORT_SYMBOL(snd_pcm_format_size);
1128EXPORT_SYMBOL(snd_pcm_format_silence_64);
1129EXPORT_SYMBOL(snd_pcm_format_set_silence);
1130EXPORT_SYMBOL(snd_pcm_build_linear_format);
1131EXPORT_SYMBOL(snd_pcm_limit_hw_rates);
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index e5133033de5e..2b8aab6fd6cd 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -497,9 +497,9 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
497 case SNDRV_PCM_IOCTL_LINK: 497 case SNDRV_PCM_IOCTL_LINK:
498 case SNDRV_PCM_IOCTL_UNLINK: 498 case SNDRV_PCM_IOCTL_UNLINK:
499 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 499 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
500 return snd_pcm_playback_ioctl1(substream, cmd, argp); 500 return snd_pcm_playback_ioctl1(file, substream, cmd, argp);
501 else 501 else
502 return snd_pcm_capture_ioctl1(substream, cmd, argp); 502 return snd_pcm_capture_ioctl1(file, substream, cmd, argp);
503 case SNDRV_PCM_IOCTL_HW_REFINE32: 503 case SNDRV_PCM_IOCTL_HW_REFINE32:
504 return snd_pcm_ioctl_hw_params_compat(substream, 1, argp); 504 return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
505 case SNDRV_PCM_IOCTL_HW_PARAMS32: 505 case SNDRV_PCM_IOCTL_HW_PARAMS32:
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index eedc6cb038bb..0bb142a28539 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -289,6 +289,7 @@ void snd_pcm_set_ops(struct snd_pcm *pcm, int direction, struct snd_pcm_ops *ops
289 substream->ops = ops; 289 substream->ops = ops;
290} 290}
291 291
292EXPORT_SYMBOL(snd_pcm_set_ops);
292 293
293/** 294/**
294 * snd_pcm_sync - set the PCM sync id 295 * snd_pcm_sync - set the PCM sync id
@@ -306,13 +307,12 @@ void snd_pcm_set_sync(struct snd_pcm_substream *substream)
306 runtime->sync.id32[3] = -1; 307 runtime->sync.id32[3] = -1;
307} 308}
308 309
310EXPORT_SYMBOL(snd_pcm_set_sync);
311
309/* 312/*
310 * Standard ioctl routine 313 * Standard ioctl routine
311 */ 314 */
312 315
313/* Code taken from alsa-lib */
314#define assert(a) snd_assert((a), return -EINVAL)
315
316static inline unsigned int div32(unsigned int a, unsigned int b, 316static inline unsigned int div32(unsigned int a, unsigned int b,
317 unsigned int *r) 317 unsigned int *r)
318{ 318{
@@ -369,56 +369,6 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b,
369 return n; 369 return n;
370} 370}
371 371
372static int snd_interval_refine_min(struct snd_interval *i, unsigned int min, int openmin)
373{
374 int changed = 0;
375 assert(!snd_interval_empty(i));
376 if (i->min < min) {
377 i->min = min;
378 i->openmin = openmin;
379 changed = 1;
380 } else if (i->min == min && !i->openmin && openmin) {
381 i->openmin = 1;
382 changed = 1;
383 }
384 if (i->integer) {
385 if (i->openmin) {
386 i->min++;
387 i->openmin = 0;
388 }
389 }
390 if (snd_interval_checkempty(i)) {
391 snd_interval_none(i);
392 return -EINVAL;
393 }
394 return changed;
395}
396
397static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int openmax)
398{
399 int changed = 0;
400 assert(!snd_interval_empty(i));
401 if (i->max > max) {
402 i->max = max;
403 i->openmax = openmax;
404 changed = 1;
405 } else if (i->max == max && !i->openmax && openmax) {
406 i->openmax = 1;
407 changed = 1;
408 }
409 if (i->integer) {
410 if (i->openmax) {
411 i->max--;
412 i->openmax = 0;
413 }
414 }
415 if (snd_interval_checkempty(i)) {
416 snd_interval_none(i);
417 return -EINVAL;
418 }
419 return changed;
420}
421
422/** 372/**
423 * snd_interval_refine - refine the interval value of configurator 373 * snd_interval_refine - refine the interval value of configurator
424 * @i: the interval value to refine 374 * @i: the interval value to refine
@@ -433,7 +383,7 @@ static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int
433int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) 383int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v)
434{ 384{
435 int changed = 0; 385 int changed = 0;
436 assert(!snd_interval_empty(i)); 386 snd_assert(!snd_interval_empty(i), return -EINVAL);
437 if (i->min < v->min) { 387 if (i->min < v->min) {
438 i->min = v->min; 388 i->min = v->min;
439 i->openmin = v->openmin; 389 i->openmin = v->openmin;
@@ -472,9 +422,11 @@ int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v)
472 return changed; 422 return changed;
473} 423}
474 424
425EXPORT_SYMBOL(snd_interval_refine);
426
475static int snd_interval_refine_first(struct snd_interval *i) 427static int snd_interval_refine_first(struct snd_interval *i)
476{ 428{
477 assert(!snd_interval_empty(i)); 429 snd_assert(!snd_interval_empty(i), return -EINVAL);
478 if (snd_interval_single(i)) 430 if (snd_interval_single(i))
479 return 0; 431 return 0;
480 i->max = i->min; 432 i->max = i->min;
@@ -486,7 +438,7 @@ static int snd_interval_refine_first(struct snd_interval *i)
486 438
487static int snd_interval_refine_last(struct snd_interval *i) 439static int snd_interval_refine_last(struct snd_interval *i)
488{ 440{
489 assert(!snd_interval_empty(i)); 441 snd_assert(!snd_interval_empty(i), return -EINVAL);
490 if (snd_interval_single(i)) 442 if (snd_interval_single(i))
491 return 0; 443 return 0;
492 i->min = i->max; 444 i->min = i->max;
@@ -496,16 +448,6 @@ static int snd_interval_refine_last(struct snd_interval *i)
496 return 1; 448 return 1;
497} 449}
498 450
499static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
500{
501 struct snd_interval t;
502 t.empty = 0;
503 t.min = t.max = val;
504 t.openmin = t.openmax = 0;
505 t.integer = 1;
506 return snd_interval_refine(i, &t);
507}
508
509void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c) 451void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c)
510{ 452{
511 if (a->empty || b->empty) { 453 if (a->empty || b->empty) {
@@ -621,7 +563,6 @@ void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k,
621 c->integer = 0; 563 c->integer = 0;
622} 564}
623 565
624#undef assert
625/* ---- */ 566/* ---- */
626 567
627 568
@@ -727,6 +668,8 @@ int snd_interval_ratnum(struct snd_interval *i,
727 return err; 668 return err;
728} 669}
729 670
671EXPORT_SYMBOL(snd_interval_ratnum);
672
730/** 673/**
731 * snd_interval_ratden - refine the interval value 674 * snd_interval_ratden - refine the interval value
732 * @i: interval to refine 675 * @i: interval to refine
@@ -877,6 +820,8 @@ int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *
877 return changed; 820 return changed;
878} 821}
879 822
823EXPORT_SYMBOL(snd_interval_list);
824
880static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step) 825static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step)
881{ 826{
882 unsigned int n; 827 unsigned int n;
@@ -953,6 +898,8 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
953 return 0; 898 return 0;
954} 899}
955 900
901EXPORT_SYMBOL(snd_pcm_hw_rule_add);
902
956/** 903/**
957 * snd_pcm_hw_constraint_mask 904 * snd_pcm_hw_constraint_mask
958 * @runtime: PCM runtime instance 905 * @runtime: PCM runtime instance
@@ -1007,6 +954,8 @@ int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_pa
1007 return snd_interval_setinteger(constrs_interval(constrs, var)); 954 return snd_interval_setinteger(constrs_interval(constrs, var));
1008} 955}
1009 956
957EXPORT_SYMBOL(snd_pcm_hw_constraint_integer);
958
1010/** 959/**
1011 * snd_pcm_hw_constraint_minmax 960 * snd_pcm_hw_constraint_minmax
1012 * @runtime: PCM runtime instance 961 * @runtime: PCM runtime instance
@@ -1028,6 +977,8 @@ int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_par
1028 return snd_interval_refine(constrs_interval(constrs, var), &t); 977 return snd_interval_refine(constrs_interval(constrs, var), &t);
1029} 978}
1030 979
980EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax);
981
1031static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, 982static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params,
1032 struct snd_pcm_hw_rule *rule) 983 struct snd_pcm_hw_rule *rule)
1033{ 984{
@@ -1055,6 +1006,8 @@ int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
1055 var, -1); 1006 var, -1);
1056} 1007}
1057 1008
1009EXPORT_SYMBOL(snd_pcm_hw_constraint_list);
1010
1058static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, 1011static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params,
1059 struct snd_pcm_hw_rule *rule) 1012 struct snd_pcm_hw_rule *rule)
1060{ 1013{
@@ -1087,6 +1040,8 @@ int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime,
1087 var, -1); 1040 var, -1);
1088} 1041}
1089 1042
1043EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums);
1044
1090static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params, 1045static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params,
1091 struct snd_pcm_hw_rule *rule) 1046 struct snd_pcm_hw_rule *rule)
1092{ 1047{
@@ -1118,6 +1073,8 @@ int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime,
1118 var, -1); 1073 var, -1);
1119} 1074}
1120 1075
1076EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens);
1077
1121static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, 1078static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params,
1122 struct snd_pcm_hw_rule *rule) 1079 struct snd_pcm_hw_rule *rule)
1123{ 1080{
@@ -1149,6 +1106,8 @@ int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime,
1149 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); 1106 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
1150} 1107}
1151 1108
1109EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits);
1110
1152static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params, 1111static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params,
1153 struct snd_pcm_hw_rule *rule) 1112 struct snd_pcm_hw_rule *rule)
1154{ 1113{
@@ -1173,6 +1132,8 @@ int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime,
1173 var, -1); 1132 var, -1);
1174} 1133}
1175 1134
1135EXPORT_SYMBOL(snd_pcm_hw_constraint_step);
1136
1176static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) 1137static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
1177{ 1138{
1178 static int pow2_sizes[] = { 1139 static int pow2_sizes[] = {
@@ -1200,11 +1161,7 @@ int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
1200 var, -1); 1161 var, -1);
1201} 1162}
1202 1163
1203/* To use the same code we have in alsa-lib */ 1164EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2);
1204#define assert(i) snd_assert((i), return -EINVAL)
1205#ifndef INT_MIN
1206#define INT_MIN ((int)((unsigned int)INT_MAX+1))
1207#endif
1208 1165
1209static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params, 1166static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params,
1210 snd_pcm_hw_param_t var) 1167 snd_pcm_hw_param_t var)
@@ -1224,18 +1181,6 @@ static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params,
1224 snd_BUG(); 1181 snd_BUG();
1225} 1182}
1226 1183
1227#if 0
1228/*
1229 * snd_pcm_hw_param_any
1230 */
1231int snd_pcm_hw_param_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1232 snd_pcm_hw_param_t var)
1233{
1234 _snd_pcm_hw_param_any(params, var);
1235 return snd_pcm_hw_refine(pcm, params);
1236}
1237#endif /* 0 */
1238
1239void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params) 1184void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params)
1240{ 1185{
1241 unsigned int k; 1186 unsigned int k;
@@ -1247,18 +1192,7 @@ void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params)
1247 params->info = ~0U; 1192 params->info = ~0U;
1248} 1193}
1249 1194
1250#if 0 1195EXPORT_SYMBOL(_snd_pcm_hw_params_any);
1251/*
1252 * snd_pcm_hw_params_any
1253 *
1254 * Fill PARAMS with full configuration space boundaries
1255 */
1256int snd_pcm_hw_params_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params)
1257{
1258 _snd_pcm_hw_params_any(params);
1259 return snd_pcm_hw_refine(pcm, params);
1260}
1261#endif /* 0 */
1262 1196
1263/** 1197/**
1264 * snd_pcm_hw_param_value 1198 * snd_pcm_hw_param_value
@@ -1269,8 +1203,8 @@ int snd_pcm_hw_params_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_param
1269 * Return the value for field PAR if it's fixed in configuration space 1203 * Return the value for field PAR if it's fixed in configuration space
1270 * defined by PARAMS. Return -EINVAL otherwise 1204 * defined by PARAMS. Return -EINVAL otherwise
1271 */ 1205 */
1272static int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, 1206int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
1273 snd_pcm_hw_param_t var, int *dir) 1207 snd_pcm_hw_param_t var, int *dir)
1274{ 1208{
1275 if (hw_is_mask(var)) { 1209 if (hw_is_mask(var)) {
1276 const struct snd_mask *mask = hw_param_mask_c(params, var); 1210 const struct snd_mask *mask = hw_param_mask_c(params, var);
@@ -1288,61 +1222,10 @@ static int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
1288 *dir = i->openmin; 1222 *dir = i->openmin;
1289 return snd_interval_value(i); 1223 return snd_interval_value(i);
1290 } 1224 }
1291 assert(0);
1292 return -EINVAL;
1293}
1294
1295/**
1296 * snd_pcm_hw_param_value_min
1297 * @params: the hw_params instance
1298 * @var: parameter to retrieve
1299 * @dir: pointer to the direction (-1,0,1) or NULL
1300 *
1301 * Return the minimum value for field PAR.
1302 */
1303unsigned int snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
1304 snd_pcm_hw_param_t var, int *dir)
1305{
1306 if (hw_is_mask(var)) {
1307 if (dir)
1308 *dir = 0;
1309 return snd_mask_min(hw_param_mask_c(params, var));
1310 }
1311 if (hw_is_interval(var)) {
1312 const struct snd_interval *i = hw_param_interval_c(params, var);
1313 if (dir)
1314 *dir = i->openmin;
1315 return snd_interval_min(i);
1316 }
1317 assert(0);
1318 return -EINVAL; 1225 return -EINVAL;
1319} 1226}
1320 1227
1321/** 1228EXPORT_SYMBOL(snd_pcm_hw_param_value);
1322 * snd_pcm_hw_param_value_max
1323 * @params: the hw_params instance
1324 * @var: parameter to retrieve
1325 * @dir: pointer to the direction (-1,0,1) or NULL
1326 *
1327 * Return the maximum value for field PAR.
1328 */
1329unsigned int snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
1330 snd_pcm_hw_param_t var, int *dir)
1331{
1332 if (hw_is_mask(var)) {
1333 if (dir)
1334 *dir = 0;
1335 return snd_mask_max(hw_param_mask_c(params, var));
1336 }
1337 if (hw_is_interval(var)) {
1338 const struct snd_interval *i = hw_param_interval_c(params, var);
1339 if (dir)
1340 *dir = - (int) i->openmax;
1341 return snd_interval_max(i);
1342 }
1343 assert(0);
1344 return -EINVAL;
1345}
1346 1229
1347void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, 1230void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params,
1348 snd_pcm_hw_param_t var) 1231 snd_pcm_hw_param_t var)
@@ -1360,42 +1243,7 @@ void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params,
1360 } 1243 }
1361} 1244}
1362 1245
1363int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params, 1246EXPORT_SYMBOL(_snd_pcm_hw_param_setempty);
1364 snd_pcm_hw_param_t var)
1365{
1366 int changed;
1367 assert(hw_is_interval(var));
1368 changed = snd_interval_setinteger(hw_param_interval(params, var));
1369 if (changed) {
1370 params->cmask |= 1 << var;
1371 params->rmask |= 1 << var;
1372 }
1373 return changed;
1374}
1375
1376#if 0
1377/*
1378 * snd_pcm_hw_param_setinteger
1379 *
1380 * Inside configuration space defined by PARAMS remove from PAR all
1381 * non integer values. Reduce configuration space accordingly.
1382 * Return -EINVAL if the configuration space is empty
1383 */
1384int snd_pcm_hw_param_setinteger(struct snd_pcm_substream *pcm,
1385 struct snd_pcm_hw_params *params,
1386 snd_pcm_hw_param_t var)
1387{
1388 int changed = _snd_pcm_hw_param_setinteger(params, var);
1389 if (changed < 0)
1390 return changed;
1391 if (params->rmask) {
1392 int err = snd_pcm_hw_refine(pcm, params);
1393 if (err < 0)
1394 return err;
1395 }
1396 return 0;
1397}
1398#endif /* 0 */
1399 1247
1400static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, 1248static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
1401 snd_pcm_hw_param_t var) 1249 snd_pcm_hw_param_t var)
@@ -1405,10 +1253,8 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
1405 changed = snd_mask_refine_first(hw_param_mask(params, var)); 1253 changed = snd_mask_refine_first(hw_param_mask(params, var));
1406 else if (hw_is_interval(var)) 1254 else if (hw_is_interval(var))
1407 changed = snd_interval_refine_first(hw_param_interval(params, var)); 1255 changed = snd_interval_refine_first(hw_param_interval(params, var));
1408 else { 1256 else
1409 assert(0);
1410 return -EINVAL; 1257 return -EINVAL;
1411 }
1412 if (changed) { 1258 if (changed) {
1413 params->cmask |= 1 << var; 1259 params->cmask |= 1 << var;
1414 params->rmask |= 1 << var; 1260 params->rmask |= 1 << var;
@@ -1428,20 +1274,22 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
1428 * values > minimum. Reduce configuration space accordingly. 1274 * values > minimum. Reduce configuration space accordingly.
1429 * Return the minimum. 1275 * Return the minimum.
1430 */ 1276 */
1431static int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, 1277int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm,
1432 struct snd_pcm_hw_params *params, 1278 struct snd_pcm_hw_params *params,
1433 snd_pcm_hw_param_t var, int *dir) 1279 snd_pcm_hw_param_t var, int *dir)
1434{ 1280{
1435 int changed = _snd_pcm_hw_param_first(params, var); 1281 int changed = _snd_pcm_hw_param_first(params, var);
1436 if (changed < 0) 1282 if (changed < 0)
1437 return changed; 1283 return changed;
1438 if (params->rmask) { 1284 if (params->rmask) {
1439 int err = snd_pcm_hw_refine(pcm, params); 1285 int err = snd_pcm_hw_refine(pcm, params);
1440 assert(err >= 0); 1286 snd_assert(err >= 0, return err);
1441 } 1287 }
1442 return snd_pcm_hw_param_value(params, var, dir); 1288 return snd_pcm_hw_param_value(params, var, dir);
1443} 1289}
1444 1290
1291EXPORT_SYMBOL(snd_pcm_hw_param_first);
1292
1445static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, 1293static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
1446 snd_pcm_hw_param_t var) 1294 snd_pcm_hw_param_t var)
1447{ 1295{
@@ -1450,10 +1298,8 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
1450 changed = snd_mask_refine_last(hw_param_mask(params, var)); 1298 changed = snd_mask_refine_last(hw_param_mask(params, var));
1451 else if (hw_is_interval(var)) 1299 else if (hw_is_interval(var))
1452 changed = snd_interval_refine_last(hw_param_interval(params, var)); 1300 changed = snd_interval_refine_last(hw_param_interval(params, var));
1453 else { 1301 else
1454 assert(0);
1455 return -EINVAL; 1302 return -EINVAL;
1456 }
1457 if (changed) { 1303 if (changed) {
1458 params->cmask |= 1 << var; 1304 params->cmask |= 1 << var;
1459 params->rmask |= 1 << var; 1305 params->rmask |= 1 << var;
@@ -1473,381 +1319,21 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
1473 * values < maximum. Reduce configuration space accordingly. 1319 * values < maximum. Reduce configuration space accordingly.
1474 * Return the maximum. 1320 * Return the maximum.
1475 */ 1321 */
1476static int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, 1322int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
1477 struct snd_pcm_hw_params *params, 1323 struct snd_pcm_hw_params *params,
1478 snd_pcm_hw_param_t var, int *dir) 1324 snd_pcm_hw_param_t var, int *dir)
1479{ 1325{
1480 int changed = _snd_pcm_hw_param_last(params, var); 1326 int changed = _snd_pcm_hw_param_last(params, var);
1481 if (changed < 0) 1327 if (changed < 0)
1482 return changed; 1328 return changed;
1483 if (params->rmask) { 1329 if (params->rmask) {
1484 int err = snd_pcm_hw_refine(pcm, params); 1330 int err = snd_pcm_hw_refine(pcm, params);
1485 assert(err >= 0); 1331 snd_assert(err >= 0, return err);
1486 } 1332 }
1487 return snd_pcm_hw_param_value(params, var, dir); 1333 return snd_pcm_hw_param_value(params, var, dir);
1488} 1334}
1489 1335
1490int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, 1336EXPORT_SYMBOL(snd_pcm_hw_param_last);
1491 snd_pcm_hw_param_t var, unsigned int val, int dir)
1492{
1493 int changed;
1494 int open = 0;
1495 if (dir) {
1496 if (dir > 0) {
1497 open = 1;
1498 } else if (dir < 0) {
1499 if (val > 0) {
1500 open = 1;
1501 val--;
1502 }
1503 }
1504 }
1505 if (hw_is_mask(var))
1506 changed = snd_mask_refine_min(hw_param_mask(params, var), val + !!open);
1507 else if (hw_is_interval(var))
1508 changed = snd_interval_refine_min(hw_param_interval(params, var), val, open);
1509 else {
1510 assert(0);
1511 return -EINVAL;
1512 }
1513 if (changed) {
1514 params->cmask |= 1 << var;
1515 params->rmask |= 1 << var;
1516 }
1517 return changed;
1518}
1519
1520/**
1521 * snd_pcm_hw_param_min
1522 * @pcm: PCM instance
1523 * @params: the hw_params instance
1524 * @var: parameter to retrieve
1525 * @val: minimal value
1526 * @dir: pointer to the direction (-1,0,1) or NULL
1527 *
1528 * Inside configuration space defined by PARAMS remove from PAR all
1529 * values < VAL. Reduce configuration space accordingly.
1530 * Return new minimum or -EINVAL if the configuration space is empty
1531 */
1532static int snd_pcm_hw_param_min(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1533 snd_pcm_hw_param_t var, unsigned int val,
1534 int *dir)
1535{
1536 int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0);
1537 if (changed < 0)
1538 return changed;
1539 if (params->rmask) {
1540 int err = snd_pcm_hw_refine(pcm, params);
1541 if (err < 0)
1542 return err;
1543 }
1544 return snd_pcm_hw_param_value_min(params, var, dir);
1545}
1546
1547static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params,
1548 snd_pcm_hw_param_t var, unsigned int val,
1549 int dir)
1550{
1551 int changed;
1552 int open = 0;
1553 if (dir) {
1554 if (dir < 0) {
1555 open = 1;
1556 } else if (dir > 0) {
1557 open = 1;
1558 val++;
1559 }
1560 }
1561 if (hw_is_mask(var)) {
1562 if (val == 0 && open) {
1563 snd_mask_none(hw_param_mask(params, var));
1564 changed = -EINVAL;
1565 } else
1566 changed = snd_mask_refine_max(hw_param_mask(params, var), val - !!open);
1567 } else if (hw_is_interval(var))
1568 changed = snd_interval_refine_max(hw_param_interval(params, var), val, open);
1569 else {
1570 assert(0);
1571 return -EINVAL;
1572 }
1573 if (changed) {
1574 params->cmask |= 1 << var;
1575 params->rmask |= 1 << var;
1576 }
1577 return changed;
1578}
1579
1580/**
1581 * snd_pcm_hw_param_max
1582 * @pcm: PCM instance
1583 * @params: the hw_params instance
1584 * @var: parameter to retrieve
1585 * @val: maximal value
1586 * @dir: pointer to the direction (-1,0,1) or NULL
1587 *
1588 * Inside configuration space defined by PARAMS remove from PAR all
1589 * values >= VAL + 1. Reduce configuration space accordingly.
1590 * Return new maximum or -EINVAL if the configuration space is empty
1591 */
1592static int snd_pcm_hw_param_max(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1593 snd_pcm_hw_param_t var, unsigned int val,
1594 int *dir)
1595{
1596 int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0);
1597 if (changed < 0)
1598 return changed;
1599 if (params->rmask) {
1600 int err = snd_pcm_hw_refine(pcm, params);
1601 if (err < 0)
1602 return err;
1603 }
1604 return snd_pcm_hw_param_value_max(params, var, dir);
1605}
1606
1607int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
1608 snd_pcm_hw_param_t var, unsigned int val, int dir)
1609{
1610 int changed;
1611 if (hw_is_mask(var)) {
1612 struct snd_mask *m = hw_param_mask(params, var);
1613 if (val == 0 && dir < 0) {
1614 changed = -EINVAL;
1615 snd_mask_none(m);
1616 } else {
1617 if (dir > 0)
1618 val++;
1619 else if (dir < 0)
1620 val--;
1621 changed = snd_mask_refine_set(hw_param_mask(params, var), val);
1622 }
1623 } else if (hw_is_interval(var)) {
1624 struct snd_interval *i = hw_param_interval(params, var);
1625 if (val == 0 && dir < 0) {
1626 changed = -EINVAL;
1627 snd_interval_none(i);
1628 } else if (dir == 0)
1629 changed = snd_interval_refine_set(i, val);
1630 else {
1631 struct snd_interval t;
1632 t.openmin = 1;
1633 t.openmax = 1;
1634 t.empty = 0;
1635 t.integer = 0;
1636 if (dir < 0) {
1637 t.min = val - 1;
1638 t.max = val;
1639 } else {
1640 t.min = val;
1641 t.max = val+1;
1642 }
1643 changed = snd_interval_refine(i, &t);
1644 }
1645 } else {
1646 assert(0);
1647 return -EINVAL;
1648 }
1649 if (changed) {
1650 params->cmask |= 1 << var;
1651 params->rmask |= 1 << var;
1652 }
1653 return changed;
1654}
1655
1656/**
1657 * snd_pcm_hw_param_set
1658 * @pcm: PCM instance
1659 * @params: the hw_params instance
1660 * @var: parameter to retrieve
1661 * @val: value to set
1662 * @dir: pointer to the direction (-1,0,1) or NULL
1663 *
1664 * Inside configuration space defined by PARAMS remove from PAR all
1665 * values != VAL. Reduce configuration space accordingly.
1666 * Return VAL or -EINVAL if the configuration space is empty
1667 */
1668int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1669 snd_pcm_hw_param_t var, unsigned int val, int dir)
1670{
1671 int changed = _snd_pcm_hw_param_set(params, var, val, dir);
1672 if (changed < 0)
1673 return changed;
1674 if (params->rmask) {
1675 int err = snd_pcm_hw_refine(pcm, params);
1676 if (err < 0)
1677 return err;
1678 }
1679 return snd_pcm_hw_param_value(params, var, NULL);
1680}
1681
1682static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params,
1683 snd_pcm_hw_param_t var, const struct snd_mask *val)
1684{
1685 int changed;
1686 assert(hw_is_mask(var));
1687 changed = snd_mask_refine(hw_param_mask(params, var), val);
1688 if (changed) {
1689 params->cmask |= 1 << var;
1690 params->rmask |= 1 << var;
1691 }
1692 return changed;
1693}
1694
1695/**
1696 * snd_pcm_hw_param_mask
1697 * @pcm: PCM instance
1698 * @params: the hw_params instance
1699 * @var: parameter to retrieve
1700 * @val: mask to apply
1701 *
1702 * Inside configuration space defined by PARAMS remove from PAR all values
1703 * not contained in MASK. Reduce configuration space accordingly.
1704 * This function can be called only for SNDRV_PCM_HW_PARAM_ACCESS,
1705 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
1706 * Return 0 on success or -EINVAL
1707 * if the configuration space is empty
1708 */
1709int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1710 snd_pcm_hw_param_t var, const struct snd_mask *val)
1711{
1712 int changed = _snd_pcm_hw_param_mask(params, var, val);
1713 if (changed < 0)
1714 return changed;
1715 if (params->rmask) {
1716 int err = snd_pcm_hw_refine(pcm, params);
1717 if (err < 0)
1718 return err;
1719 }
1720 return 0;
1721}
1722
1723static int boundary_sub(int a, int adir,
1724 int b, int bdir,
1725 int *c, int *cdir)
1726{
1727 adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0);
1728 bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0);
1729 *c = a - b;
1730 *cdir = adir - bdir;
1731 if (*cdir == -2) {
1732 assert(*c > INT_MIN);
1733 (*c)--;
1734 } else if (*cdir == 2) {
1735 assert(*c < INT_MAX);
1736 (*c)++;
1737 }
1738 return 0;
1739}
1740
1741static int boundary_lt(unsigned int a, int adir,
1742 unsigned int b, int bdir)
1743{
1744 assert(a > 0 || adir >= 0);
1745 assert(b > 0 || bdir >= 0);
1746 if (adir < 0) {
1747 a--;
1748 adir = 1;
1749 } else if (adir > 0)
1750 adir = 1;
1751 if (bdir < 0) {
1752 b--;
1753 bdir = 1;
1754 } else if (bdir > 0)
1755 bdir = 1;
1756 return a < b || (a == b && adir < bdir);
1757}
1758
1759/* Return 1 if min is nearer to best than max */
1760static int boundary_nearer(int min, int mindir,
1761 int best, int bestdir,
1762 int max, int maxdir)
1763{
1764 int dmin, dmindir;
1765 int dmax, dmaxdir;
1766 boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir);
1767 boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir);
1768 return boundary_lt(dmin, dmindir, dmax, dmaxdir);
1769}
1770
1771/**
1772 * snd_pcm_hw_param_near
1773 * @pcm: PCM instance
1774 * @params: the hw_params instance
1775 * @var: parameter to retrieve
1776 * @best: value to set
1777 * @dir: pointer to the direction (-1,0,1) or NULL
1778 *
1779 * Inside configuration space defined by PARAMS set PAR to the available value
1780 * nearest to VAL. Reduce configuration space accordingly.
1781 * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS,
1782 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
1783 * Return the value found.
1784 */
1785int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1786 snd_pcm_hw_param_t var, unsigned int best, int *dir)
1787{
1788 struct snd_pcm_hw_params *save = NULL;
1789 int v;
1790 unsigned int saved_min;
1791 int last = 0;
1792 int min, max;
1793 int mindir, maxdir;
1794 int valdir = dir ? *dir : 0;
1795 /* FIXME */
1796 if (best > INT_MAX)
1797 best = INT_MAX;
1798 min = max = best;
1799 mindir = maxdir = valdir;
1800 if (maxdir > 0)
1801 maxdir = 0;
1802 else if (maxdir == 0)
1803 maxdir = -1;
1804 else {
1805 maxdir = 1;
1806 max--;
1807 }
1808 save = kmalloc(sizeof(*save), GFP_KERNEL);
1809 if (save == NULL)
1810 return -ENOMEM;
1811 *save = *params;
1812 saved_min = min;
1813 min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
1814 if (min >= 0) {
1815 struct snd_pcm_hw_params *params1;
1816 if (max < 0)
1817 goto _end;
1818 if ((unsigned int)min == saved_min && mindir == valdir)
1819 goto _end;
1820 params1 = kmalloc(sizeof(*params1), GFP_KERNEL);
1821 if (params1 == NULL) {
1822 kfree(save);
1823 return -ENOMEM;
1824 }
1825 *params1 = *save;
1826 max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir);
1827 if (max < 0) {
1828 kfree(params1);
1829 goto _end;
1830 }
1831 if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) {
1832 *params = *params1;
1833 last = 1;
1834 }
1835 kfree(params1);
1836 } else {
1837 *params = *save;
1838 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
1839 assert(max >= 0);
1840 last = 1;
1841 }
1842 _end:
1843 kfree(save);
1844 if (last)
1845 v = snd_pcm_hw_param_last(pcm, params, var, dir);
1846 else
1847 v = snd_pcm_hw_param_first(pcm, params, var, dir);
1848 assert(v >= 0);
1849 return v;
1850}
1851 1337
1852/** 1338/**
1853 * snd_pcm_hw_param_choose 1339 * snd_pcm_hw_param_choose
@@ -1859,39 +1345,32 @@ int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, struct snd_pcm_hw_param
1859 * first access, first format, first subformat, min channels, 1345 * first access, first format, first subformat, min channels,
1860 * min rate, min period time, max buffer size, min tick time 1346 * min rate, min period time, max buffer size, min tick time
1861 */ 1347 */
1862int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params) 1348int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm,
1863{ 1349 struct snd_pcm_hw_params *params)
1864 int err; 1350{
1865 1351 static int vars[] = {
1866 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_ACCESS, NULL); 1352 SNDRV_PCM_HW_PARAM_ACCESS,
1867 assert(err >= 0); 1353 SNDRV_PCM_HW_PARAM_FORMAT,
1868 1354 SNDRV_PCM_HW_PARAM_SUBFORMAT,
1869 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_FORMAT, NULL); 1355 SNDRV_PCM_HW_PARAM_CHANNELS,
1870 assert(err >= 0); 1356 SNDRV_PCM_HW_PARAM_RATE,
1871 1357 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1872 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_SUBFORMAT, NULL); 1358 SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
1873 assert(err >= 0); 1359 SNDRV_PCM_HW_PARAM_TICK_TIME,
1874 1360 -1
1875 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_CHANNELS, NULL); 1361 };
1876 assert(err >= 0); 1362 int err, *v;
1877
1878 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_RATE, NULL);
1879 assert(err >= 0);
1880
1881 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_PERIOD_TIME, NULL);
1882 assert(err >= 0);
1883
1884 err = snd_pcm_hw_param_last(pcm, params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL);
1885 assert(err >= 0);
1886
1887 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_TICK_TIME, NULL);
1888 assert(err >= 0);
1889 1363
1364 for (v = vars; *v != -1; v++) {
1365 if (*v != SNDRV_PCM_HW_PARAM_BUFFER_SIZE)
1366 err = snd_pcm_hw_param_first(pcm, params, *v, NULL);
1367 else
1368 err = snd_pcm_hw_param_last(pcm, params, *v, NULL);
1369 snd_assert(err >= 0, return err);
1370 }
1890 return 0; 1371 return 0;
1891} 1372}
1892 1373
1893#undef assert
1894
1895static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream, 1374static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
1896 void *arg) 1375 void *arg)
1897{ 1376{
@@ -1967,6 +1446,8 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
1967 return -ENXIO; 1446 return -ENXIO;
1968} 1447}
1969 1448
1449EXPORT_SYMBOL(snd_pcm_lib_ioctl);
1450
1970/* 1451/*
1971 * Conditions 1452 * Conditions
1972 */ 1453 */
@@ -2101,6 +1582,8 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
2101 kill_fasync(&runtime->fasync, SIGIO, POLL_IN); 1582 kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
2102} 1583}
2103 1584
1585EXPORT_SYMBOL(snd_pcm_period_elapsed);
1586
2104static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, 1587static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
2105 unsigned int hwoff, 1588 unsigned int hwoff,
2106 unsigned long data, unsigned int off, 1589 unsigned long data, unsigned int off,
@@ -2299,7 +1782,7 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v
2299 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1782 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2300 return -EBADFD; 1783 return -EBADFD;
2301 1784
2302 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 1785 nonblock = !!(substream->f_flags & O_NONBLOCK);
2303 1786
2304 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && 1787 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
2305 runtime->channels > 1) 1788 runtime->channels > 1)
@@ -2308,6 +1791,8 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v
2308 snd_pcm_lib_write_transfer); 1791 snd_pcm_lib_write_transfer);
2309} 1792}
2310 1793
1794EXPORT_SYMBOL(snd_pcm_lib_write);
1795
2311static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, 1796static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
2312 unsigned int hwoff, 1797 unsigned int hwoff,
2313 unsigned long data, unsigned int off, 1798 unsigned long data, unsigned int off,
@@ -2362,7 +1847,7 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
2362 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1847 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2363 return -EBADFD; 1848 return -EBADFD;
2364 1849
2365 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 1850 nonblock = !!(substream->f_flags & O_NONBLOCK);
2366 1851
2367 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 1852 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
2368 return -EINVAL; 1853 return -EINVAL;
@@ -2370,6 +1855,8 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
2370 nonblock, snd_pcm_lib_writev_transfer); 1855 nonblock, snd_pcm_lib_writev_transfer);
2371} 1856}
2372 1857
1858EXPORT_SYMBOL(snd_pcm_lib_writev);
1859
2373static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, 1860static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream,
2374 unsigned int hwoff, 1861 unsigned int hwoff,
2375 unsigned long data, unsigned int off, 1862 unsigned long data, unsigned int off,
@@ -2572,12 +2059,14 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u
2572 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2059 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2573 return -EBADFD; 2060 return -EBADFD;
2574 2061
2575 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2062 nonblock = !!(substream->f_flags & O_NONBLOCK);
2576 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) 2063 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED)
2577 return -EINVAL; 2064 return -EINVAL;
2578 return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); 2065 return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer);
2579} 2066}
2580 2067
2068EXPORT_SYMBOL(snd_pcm_lib_read);
2069
2581static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, 2070static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
2582 unsigned int hwoff, 2071 unsigned int hwoff,
2583 unsigned long data, unsigned int off, 2072 unsigned long data, unsigned int off,
@@ -2629,58 +2118,10 @@ snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
2629 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2118 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2630 return -EBADFD; 2119 return -EBADFD;
2631 2120
2632 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2121 nonblock = !!(substream->f_flags & O_NONBLOCK);
2633 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 2122 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
2634 return -EINVAL; 2123 return -EINVAL;
2635 return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer); 2124 return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer);
2636} 2125}
2637 2126
2638/*
2639 * Exported symbols
2640 */
2641
2642EXPORT_SYMBOL(snd_interval_refine);
2643EXPORT_SYMBOL(snd_interval_list);
2644EXPORT_SYMBOL(snd_interval_ratnum);
2645EXPORT_SYMBOL(_snd_pcm_hw_params_any);
2646EXPORT_SYMBOL(_snd_pcm_hw_param_min);
2647EXPORT_SYMBOL(_snd_pcm_hw_param_set);
2648EXPORT_SYMBOL(_snd_pcm_hw_param_setempty);
2649EXPORT_SYMBOL(_snd_pcm_hw_param_setinteger);
2650EXPORT_SYMBOL(snd_pcm_hw_param_value_min);
2651EXPORT_SYMBOL(snd_pcm_hw_param_value_max);
2652EXPORT_SYMBOL(snd_pcm_hw_param_mask);
2653EXPORT_SYMBOL(snd_pcm_hw_param_first);
2654EXPORT_SYMBOL(snd_pcm_hw_param_last);
2655EXPORT_SYMBOL(snd_pcm_hw_param_near);
2656EXPORT_SYMBOL(snd_pcm_hw_param_set);
2657EXPORT_SYMBOL(snd_pcm_hw_refine);
2658EXPORT_SYMBOL(snd_pcm_hw_constraints_init);
2659EXPORT_SYMBOL(snd_pcm_hw_constraints_complete);
2660EXPORT_SYMBOL(snd_pcm_hw_constraint_list);
2661EXPORT_SYMBOL(snd_pcm_hw_constraint_step);
2662EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums);
2663EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens);
2664EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits);
2665EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax);
2666EXPORT_SYMBOL(snd_pcm_hw_constraint_integer);
2667EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2);
2668EXPORT_SYMBOL(snd_pcm_hw_rule_add);
2669EXPORT_SYMBOL(snd_pcm_set_ops);
2670EXPORT_SYMBOL(snd_pcm_set_sync);
2671EXPORT_SYMBOL(snd_pcm_lib_ioctl);
2672EXPORT_SYMBOL(snd_pcm_stop);
2673EXPORT_SYMBOL(snd_pcm_period_elapsed);
2674EXPORT_SYMBOL(snd_pcm_lib_write);
2675EXPORT_SYMBOL(snd_pcm_lib_read);
2676EXPORT_SYMBOL(snd_pcm_lib_writev);
2677EXPORT_SYMBOL(snd_pcm_lib_readv); 2127EXPORT_SYMBOL(snd_pcm_lib_readv);
2678EXPORT_SYMBOL(snd_pcm_lib_buffer_bytes);
2679EXPORT_SYMBOL(snd_pcm_lib_period_bytes);
2680/* pcm_memory.c */
2681EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all);
2682EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages);
2683EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
2684EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
2685EXPORT_SYMBOL(snd_pcm_lib_malloc_pages);
2686EXPORT_SYMBOL(snd_pcm_lib_free_pages);
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index 428f8c169ee1..067d2056db9a 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -126,6 +126,8 @@ int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm)
126 return 0; 126 return 0;
127} 127}
128 128
129EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all);
130
129#ifdef CONFIG_SND_VERBOSE_PROCFS 131#ifdef CONFIG_SND_VERBOSE_PROCFS
130/* 132/*
131 * read callback for prealloc proc file 133 * read callback for prealloc proc file
@@ -191,9 +193,7 @@ static inline void preallocate_info_init(struct snd_pcm_substream *substream)
191 struct snd_info_entry *entry; 193 struct snd_info_entry *entry;
192 194
193 if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) { 195 if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) {
194 entry->c.text.read_size = 64;
195 entry->c.text.read = snd_pcm_lib_preallocate_proc_read; 196 entry->c.text.read = snd_pcm_lib_preallocate_proc_read;
196 entry->c.text.write_size = 64;
197 entry->c.text.write = snd_pcm_lib_preallocate_proc_write; 197 entry->c.text.write = snd_pcm_lib_preallocate_proc_write;
198 entry->mode |= S_IWUSR; 198 entry->mode |= S_IWUSR;
199 entry->private_data = substream; 199 entry->private_data = substream;
@@ -253,6 +253,8 @@ int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream,
253 return snd_pcm_lib_preallocate_pages1(substream, size, max); 253 return snd_pcm_lib_preallocate_pages1(substream, size, max);
254} 254}
255 255
256EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages);
257
256/** 258/**
257 * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams) 259 * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams)
258 * @pcm: the pcm instance 260 * @pcm: the pcm instance
@@ -280,6 +282,8 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
280 return 0; 282 return 0;
281} 283}
282 284
285EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
286
283/** 287/**
284 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset 288 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset
285 * @substream: the pcm substream instance 289 * @substream: the pcm substream instance
@@ -298,6 +302,8 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne
298 return sgbuf->page_table[idx]; 302 return sgbuf->page_table[idx];
299} 303}
300 304
305EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
306
301/** 307/**
302 * snd_pcm_lib_malloc_pages - allocate the DMA buffer 308 * snd_pcm_lib_malloc_pages - allocate the DMA buffer
303 * @substream: the substream to allocate the DMA buffer to 309 * @substream: the substream to allocate the DMA buffer to
@@ -349,6 +355,8 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size)
349 return 1; /* area was changed */ 355 return 1; /* area was changed */
350} 356}
351 357
358EXPORT_SYMBOL(snd_pcm_lib_malloc_pages);
359
352/** 360/**
353 * snd_pcm_lib_free_pages - release the allocated DMA buffer. 361 * snd_pcm_lib_free_pages - release the allocated DMA buffer.
354 * @substream: the substream to release the DMA buffer 362 * @substream: the substream to release the DMA buffer
@@ -374,3 +382,5 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
374 snd_pcm_set_runtime_buffer(substream, NULL); 382 snd_pcm_set_runtime_buffer(substream, NULL);
375 return 0; 383 return 0;
376} 384}
385
386EXPORT_SYMBOL(snd_pcm_lib_free_pages);
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index 593c77f4d181..0019c59a779d 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -207,6 +207,8 @@ int snd_pcm_format_signed(snd_pcm_format_t format)
207 return val; 207 return val;
208} 208}
209 209
210EXPORT_SYMBOL(snd_pcm_format_signed);
211
210/** 212/**
211 * snd_pcm_format_unsigned - Check the PCM format is unsigned linear 213 * snd_pcm_format_unsigned - Check the PCM format is unsigned linear
212 * @format: the format to check 214 * @format: the format to check
@@ -224,6 +226,8 @@ int snd_pcm_format_unsigned(snd_pcm_format_t format)
224 return !val; 226 return !val;
225} 227}
226 228
229EXPORT_SYMBOL(snd_pcm_format_unsigned);
230
227/** 231/**
228 * snd_pcm_format_linear - Check the PCM format is linear 232 * snd_pcm_format_linear - Check the PCM format is linear
229 * @format: the format to check 233 * @format: the format to check
@@ -235,6 +239,8 @@ int snd_pcm_format_linear(snd_pcm_format_t format)
235 return snd_pcm_format_signed(format) >= 0; 239 return snd_pcm_format_signed(format) >= 0;
236} 240}
237 241
242EXPORT_SYMBOL(snd_pcm_format_linear);
243
238/** 244/**
239 * snd_pcm_format_little_endian - Check the PCM format is little-endian 245 * snd_pcm_format_little_endian - Check the PCM format is little-endian
240 * @format: the format to check 246 * @format: the format to check
@@ -252,6 +258,8 @@ int snd_pcm_format_little_endian(snd_pcm_format_t format)
252 return val; 258 return val;
253} 259}
254 260
261EXPORT_SYMBOL(snd_pcm_format_little_endian);
262
255/** 263/**
256 * snd_pcm_format_big_endian - Check the PCM format is big-endian 264 * snd_pcm_format_big_endian - Check the PCM format is big-endian
257 * @format: the format to check 265 * @format: the format to check
@@ -269,6 +277,8 @@ int snd_pcm_format_big_endian(snd_pcm_format_t format)
269 return !val; 277 return !val;
270} 278}
271 279
280EXPORT_SYMBOL(snd_pcm_format_big_endian);
281
272/** 282/**
273 * snd_pcm_format_width - return the bit-width of the format 283 * snd_pcm_format_width - return the bit-width of the format
274 * @format: the format to check 284 * @format: the format to check
@@ -286,6 +296,8 @@ int snd_pcm_format_width(snd_pcm_format_t format)
286 return val; 296 return val;
287} 297}
288 298
299EXPORT_SYMBOL(snd_pcm_format_width);
300
289/** 301/**
290 * snd_pcm_format_physical_width - return the physical bit-width of the format 302 * snd_pcm_format_physical_width - return the physical bit-width of the format
291 * @format: the format to check 303 * @format: the format to check
@@ -303,6 +315,8 @@ int snd_pcm_format_physical_width(snd_pcm_format_t format)
303 return val; 315 return val;
304} 316}
305 317
318EXPORT_SYMBOL(snd_pcm_format_physical_width);
319
306/** 320/**
307 * snd_pcm_format_size - return the byte size of samples on the given format 321 * snd_pcm_format_size - return the byte size of samples on the given format
308 * @format: the format to check 322 * @format: the format to check
@@ -318,6 +332,8 @@ ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
318 return samples * phys_width / 8; 332 return samples * phys_width / 8;
319} 333}
320 334
335EXPORT_SYMBOL(snd_pcm_format_size);
336
321/** 337/**
322 * snd_pcm_format_silence_64 - return the silent data in 8 bytes array 338 * snd_pcm_format_silence_64 - return the silent data in 8 bytes array
323 * @format: the format to check 339 * @format: the format to check
@@ -333,6 +349,8 @@ const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format)
333 return pcm_formats[format].silence; 349 return pcm_formats[format].silence;
334} 350}
335 351
352EXPORT_SYMBOL(snd_pcm_format_silence_64);
353
336/** 354/**
337 * snd_pcm_format_set_silence - set the silence data on the buffer 355 * snd_pcm_format_set_silence - set the silence data on the buffer
338 * @format: the PCM format 356 * @format: the PCM format
@@ -402,6 +420,8 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
402 return 0; 420 return 0;
403} 421}
404 422
423EXPORT_SYMBOL(snd_pcm_format_set_silence);
424
405/* [width][unsigned][bigendian] */ 425/* [width][unsigned][bigendian] */
406static int linear_formats[4][2][2] = { 426static int linear_formats[4][2][2] = {
407 {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8}, 427 {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8},
@@ -432,6 +452,8 @@ snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_end
432 return linear_formats[width][!!unsignd][!!big_endian]; 452 return linear_formats[width][!!unsignd][!!big_endian];
433} 453}
434 454
455EXPORT_SYMBOL(snd_pcm_build_linear_format);
456
435/** 457/**
436 * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields 458 * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields
437 * @runtime: the runtime instance 459 * @runtime: the runtime instance
@@ -463,3 +485,5 @@ int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime)
463 } 485 }
464 return 0; 486 return 0;
465} 487}
488
489EXPORT_SYMBOL(snd_pcm_limit_hw_rates);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 0860c5a84502..439f047929e1 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -71,8 +71,9 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream);
71 */ 71 */
72 72
73DEFINE_RWLOCK(snd_pcm_link_rwlock); 73DEFINE_RWLOCK(snd_pcm_link_rwlock);
74static DECLARE_RWSEM(snd_pcm_link_rwsem); 74EXPORT_SYMBOL(snd_pcm_link_rwlock);
75 75
76static DECLARE_RWSEM(snd_pcm_link_rwsem);
76 77
77static inline mm_segment_t snd_enter_user(void) 78static inline mm_segment_t snd_enter_user(void)
78{ 79{
@@ -319,6 +320,8 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
319 return 0; 320 return 0;
320} 321}
321 322
323EXPORT_SYMBOL(snd_pcm_hw_refine);
324
322static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream, 325static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream,
323 struct snd_pcm_hw_params __user * _params) 326 struct snd_pcm_hw_params __user * _params)
324{ 327{
@@ -369,7 +372,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
369#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 372#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
370 if (!substream->oss.oss) 373 if (!substream->oss.oss)
371#endif 374#endif
372 if (atomic_read(&runtime->mmap_count)) 375 if (atomic_read(&substream->mmap_count))
373 return -EBADFD; 376 return -EBADFD;
374 377
375 params->rmask = ~0U; 378 params->rmask = ~0U;
@@ -482,7 +485,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
482 return -EBADFD; 485 return -EBADFD;
483 } 486 }
484 snd_pcm_stream_unlock_irq(substream); 487 snd_pcm_stream_unlock_irq(substream);
485 if (atomic_read(&runtime->mmap_count)) 488 if (atomic_read(&substream->mmap_count))
486 return -EBADFD; 489 return -EBADFD;
487 if (substream->ops->hw_free) 490 if (substream->ops->hw_free)
488 result = substream->ops->hw_free(substream); 491 result = substream->ops->hw_free(substream);
@@ -936,6 +939,8 @@ int snd_pcm_stop(struct snd_pcm_substream *substream, int state)
936 return snd_pcm_action(&snd_pcm_action_stop, substream, state); 939 return snd_pcm_action(&snd_pcm_action_stop, substream, state);
937} 940}
938 941
942EXPORT_SYMBOL(snd_pcm_stop);
943
939/** 944/**
940 * snd_pcm_drain_done 945 * snd_pcm_drain_done
941 * @substream: the PCM substream 946 * @substream: the PCM substream
@@ -1085,6 +1090,8 @@ int snd_pcm_suspend(struct snd_pcm_substream *substream)
1085 return err; 1090 return err;
1086} 1091}
1087 1092
1093EXPORT_SYMBOL(snd_pcm_suspend);
1094
1088/** 1095/**
1089 * snd_pcm_suspend_all 1096 * snd_pcm_suspend_all
1090 * @pcm: the PCM instance 1097 * @pcm: the PCM instance
@@ -1114,6 +1121,8 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm)
1114 return 0; 1121 return 0;
1115} 1122}
1116 1123
1124EXPORT_SYMBOL(snd_pcm_suspend_all);
1125
1117/* resume */ 1126/* resume */
1118 1127
1119static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state) 1128static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state)
@@ -1275,13 +1284,16 @@ static int snd_pcm_reset(struct snd_pcm_substream *substream)
1275/* 1284/*
1276 * prepare ioctl 1285 * prepare ioctl
1277 */ 1286 */
1278static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream, int state) 1287/* we use the second argument for updating f_flags */
1288static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
1289 int f_flags)
1279{ 1290{
1280 struct snd_pcm_runtime *runtime = substream->runtime; 1291 struct snd_pcm_runtime *runtime = substream->runtime;
1281 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 1292 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1282 return -EBADFD; 1293 return -EBADFD;
1283 if (snd_pcm_running(substream)) 1294 if (snd_pcm_running(substream))
1284 return -EBUSY; 1295 return -EBUSY;
1296 substream->f_flags = f_flags;
1285 return 0; 1297 return 0;
1286} 1298}
1287 1299
@@ -1310,17 +1322,26 @@ static struct action_ops snd_pcm_action_prepare = {
1310/** 1322/**
1311 * snd_pcm_prepare 1323 * snd_pcm_prepare
1312 * @substream: the PCM substream instance 1324 * @substream: the PCM substream instance
1325 * @file: file to refer f_flags
1313 * 1326 *
1314 * Prepare the PCM substream to be triggerable. 1327 * Prepare the PCM substream to be triggerable.
1315 */ 1328 */
1316static int snd_pcm_prepare(struct snd_pcm_substream *substream) 1329static int snd_pcm_prepare(struct snd_pcm_substream *substream,
1330 struct file *file)
1317{ 1331{
1318 int res; 1332 int res;
1319 struct snd_card *card = substream->pcm->card; 1333 struct snd_card *card = substream->pcm->card;
1334 int f_flags;
1335
1336 if (file)
1337 f_flags = file->f_flags;
1338 else
1339 f_flags = substream->f_flags;
1320 1340
1321 snd_power_lock(card); 1341 snd_power_lock(card);
1322 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0) 1342 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0)
1323 res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare, substream, 0); 1343 res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
1344 substream, f_flags);
1324 snd_power_unlock(card); 1345 snd_power_unlock(card);
1325 return res; 1346 return res;
1326} 1347}
@@ -1331,7 +1352,7 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream)
1331 1352
1332static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state) 1353static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state)
1333{ 1354{
1334 if (substream->ffile->f_flags & O_NONBLOCK) 1355 if (substream->f_flags & O_NONBLOCK)
1335 return -EAGAIN; 1356 return -EAGAIN;
1336 substream->runtime->trigger_master = substream; 1357 substream->runtime->trigger_master = substream;
1337 return 0; 1358 return 0;
@@ -1448,8 +1469,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
1448 } 1469 }
1449 } 1470 }
1450 up_read(&snd_pcm_link_rwsem); 1471 up_read(&snd_pcm_link_rwsem);
1451 if (! num_drecs)
1452 goto _error;
1453 1472
1454 snd_pcm_stream_lock_irq(substream); 1473 snd_pcm_stream_lock_irq(substream);
1455 /* resume pause */ 1474 /* resume pause */
@@ -2006,6 +2025,10 @@ static void pcm_release_private(struct snd_pcm_substream *substream)
2006 2025
2007void snd_pcm_release_substream(struct snd_pcm_substream *substream) 2026void snd_pcm_release_substream(struct snd_pcm_substream *substream)
2008{ 2027{
2028 substream->ref_count--;
2029 if (substream->ref_count > 0)
2030 return;
2031
2009 snd_pcm_drop(substream); 2032 snd_pcm_drop(substream);
2010 if (substream->hw_opened) { 2033 if (substream->hw_opened) {
2011 if (substream->ops->hw_free != NULL) 2034 if (substream->ops->hw_free != NULL)
@@ -2020,6 +2043,8 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream)
2020 snd_pcm_detach_substream(substream); 2043 snd_pcm_detach_substream(substream);
2021} 2044}
2022 2045
2046EXPORT_SYMBOL(snd_pcm_release_substream);
2047
2023int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, 2048int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2024 struct file *file, 2049 struct file *file,
2025 struct snd_pcm_substream **rsubstream) 2050 struct snd_pcm_substream **rsubstream)
@@ -2030,6 +2055,11 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2030 err = snd_pcm_attach_substream(pcm, stream, file, &substream); 2055 err = snd_pcm_attach_substream(pcm, stream, file, &substream);
2031 if (err < 0) 2056 if (err < 0)
2032 return err; 2057 return err;
2058 if (substream->ref_count > 1) {
2059 *rsubstream = substream;
2060 return 0;
2061 }
2062
2033 substream->no_mmap_ctrl = 0; 2063 substream->no_mmap_ctrl = 0;
2034 err = snd_pcm_hw_constraints_init(substream); 2064 err = snd_pcm_hw_constraints_init(substream);
2035 if (err < 0) { 2065 if (err < 0) {
@@ -2056,6 +2086,8 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2056 return err; 2086 return err;
2057} 2087}
2058 2088
2089EXPORT_SYMBOL(snd_pcm_open_substream);
2090
2059static int snd_pcm_open_file(struct file *file, 2091static int snd_pcm_open_file(struct file *file,
2060 struct snd_pcm *pcm, 2092 struct snd_pcm *pcm,
2061 int stream, 2093 int stream,
@@ -2073,17 +2105,20 @@ static int snd_pcm_open_file(struct file *file,
2073 if (err < 0) 2105 if (err < 0)
2074 return err; 2106 return err;
2075 2107
2076 pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); 2108 if (substream->ref_count > 1)
2077 if (pcm_file == NULL) { 2109 pcm_file = substream->file;
2078 snd_pcm_release_substream(substream); 2110 else {
2079 return -ENOMEM; 2111 pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
2112 if (pcm_file == NULL) {
2113 snd_pcm_release_substream(substream);
2114 return -ENOMEM;
2115 }
2116 str = substream->pstr;
2117 substream->file = pcm_file;
2118 substream->pcm_release = pcm_release_private;
2119 pcm_file->substream = substream;
2120 snd_pcm_add_file(str, pcm_file);
2080 } 2121 }
2081 str = substream->pstr;
2082 substream->file = pcm_file;
2083 substream->pcm_release = pcm_release_private;
2084 pcm_file->substream = substream;
2085 snd_pcm_add_file(str, pcm_file);
2086
2087 file->private_data = pcm_file; 2122 file->private_data = pcm_file;
2088 *rpcm_file = pcm_file; 2123 *rpcm_file = pcm_file;
2089 return 0; 2124 return 0;
@@ -2170,7 +2205,6 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
2170 pcm_file = file->private_data; 2205 pcm_file = file->private_data;
2171 substream = pcm_file->substream; 2206 substream = pcm_file->substream;
2172 snd_assert(substream != NULL, return -ENXIO); 2207 snd_assert(substream != NULL, return -ENXIO);
2173 snd_assert(!atomic_read(&substream->runtime->mmap_count), );
2174 pcm = substream->pcm; 2208 pcm = substream->pcm;
2175 fasync_helper(-1, file, 0, &substream->runtime->fasync); 2209 fasync_helper(-1, file, 0, &substream->runtime->fasync);
2176 mutex_lock(&pcm->open_mutex); 2210 mutex_lock(&pcm->open_mutex);
@@ -2493,7 +2527,8 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
2493 return 0; 2527 return 0;
2494} 2528}
2495 2529
2496static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, 2530static int snd_pcm_common_ioctl1(struct file *file,
2531 struct snd_pcm_substream *substream,
2497 unsigned int cmd, void __user *arg) 2532 unsigned int cmd, void __user *arg)
2498{ 2533{
2499 snd_assert(substream != NULL, return -ENXIO); 2534 snd_assert(substream != NULL, return -ENXIO);
@@ -2518,7 +2553,7 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
2518 case SNDRV_PCM_IOCTL_CHANNEL_INFO: 2553 case SNDRV_PCM_IOCTL_CHANNEL_INFO:
2519 return snd_pcm_channel_info_user(substream, arg); 2554 return snd_pcm_channel_info_user(substream, arg);
2520 case SNDRV_PCM_IOCTL_PREPARE: 2555 case SNDRV_PCM_IOCTL_PREPARE:
2521 return snd_pcm_prepare(substream); 2556 return snd_pcm_prepare(substream, file);
2522 case SNDRV_PCM_IOCTL_RESET: 2557 case SNDRV_PCM_IOCTL_RESET:
2523 return snd_pcm_reset(substream); 2558 return snd_pcm_reset(substream);
2524 case SNDRV_PCM_IOCTL_START: 2559 case SNDRV_PCM_IOCTL_START:
@@ -2560,7 +2595,8 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
2560 return -ENOTTY; 2595 return -ENOTTY;
2561} 2596}
2562 2597
2563static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream, 2598static int snd_pcm_playback_ioctl1(struct file *file,
2599 struct snd_pcm_substream *substream,
2564 unsigned int cmd, void __user *arg) 2600 unsigned int cmd, void __user *arg)
2565{ 2601{
2566 snd_assert(substream != NULL, return -ENXIO); 2602 snd_assert(substream != NULL, return -ENXIO);
@@ -2636,10 +2672,11 @@ static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream,
2636 return result < 0 ? result : 0; 2672 return result < 0 ? result : 0;
2637 } 2673 }
2638 } 2674 }
2639 return snd_pcm_common_ioctl1(substream, cmd, arg); 2675 return snd_pcm_common_ioctl1(file, substream, cmd, arg);
2640} 2676}
2641 2677
2642static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream, 2678static int snd_pcm_capture_ioctl1(struct file *file,
2679 struct snd_pcm_substream *substream,
2643 unsigned int cmd, void __user *arg) 2680 unsigned int cmd, void __user *arg)
2644{ 2681{
2645 snd_assert(substream != NULL, return -ENXIO); 2682 snd_assert(substream != NULL, return -ENXIO);
@@ -2715,7 +2752,7 @@ static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream,
2715 return result < 0 ? result : 0; 2752 return result < 0 ? result : 0;
2716 } 2753 }
2717 } 2754 }
2718 return snd_pcm_common_ioctl1(substream, cmd, arg); 2755 return snd_pcm_common_ioctl1(file, substream, cmd, arg);
2719} 2756}
2720 2757
2721static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd, 2758static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
@@ -2728,7 +2765,8 @@ static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
2728 if (((cmd >> 8) & 0xff) != 'A') 2765 if (((cmd >> 8) & 0xff) != 'A')
2729 return -ENOTTY; 2766 return -ENOTTY;
2730 2767
2731 return snd_pcm_playback_ioctl1(pcm_file->substream, cmd, (void __user *)arg); 2768 return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd,
2769 (void __user *)arg);
2732} 2770}
2733 2771
2734static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, 2772static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
@@ -2741,7 +2779,8 @@ static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
2741 if (((cmd >> 8) & 0xff) != 'A') 2779 if (((cmd >> 8) & 0xff) != 'A')
2742 return -ENOTTY; 2780 return -ENOTTY;
2743 2781
2744 return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg); 2782 return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd,
2783 (void __user *)arg);
2745} 2784}
2746 2785
2747int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, 2786int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
@@ -2753,12 +2792,12 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
2753 fs = snd_enter_user(); 2792 fs = snd_enter_user();
2754 switch (substream->stream) { 2793 switch (substream->stream) {
2755 case SNDRV_PCM_STREAM_PLAYBACK: 2794 case SNDRV_PCM_STREAM_PLAYBACK:
2756 result = snd_pcm_playback_ioctl1(substream, 2795 result = snd_pcm_playback_ioctl1(NULL, substream, cmd,
2757 cmd, (void __user *)arg); 2796 (void __user *)arg);
2758 break; 2797 break;
2759 case SNDRV_PCM_STREAM_CAPTURE: 2798 case SNDRV_PCM_STREAM_CAPTURE:
2760 result = snd_pcm_capture_ioctl1(substream, 2799 result = snd_pcm_capture_ioctl1(NULL, substream, cmd,
2761 cmd, (void __user *)arg); 2800 (void __user *)arg);
2762 break; 2801 break;
2763 default: 2802 default:
2764 result = -EINVAL; 2803 result = -EINVAL;
@@ -2768,6 +2807,8 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
2768 return result; 2807 return result;
2769} 2808}
2770 2809
2810EXPORT_SYMBOL(snd_pcm_kernel_ioctl);
2811
2771static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, 2812static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count,
2772 loff_t * offset) 2813 loff_t * offset)
2773{ 2814{
@@ -3134,7 +3175,7 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
3134 area->vm_ops = &snd_pcm_vm_ops_data; 3175 area->vm_ops = &snd_pcm_vm_ops_data;
3135 area->vm_private_data = substream; 3176 area->vm_private_data = substream;
3136 area->vm_flags |= VM_RESERVED; 3177 area->vm_flags |= VM_RESERVED;
3137 atomic_inc(&substream->runtime->mmap_count); 3178 atomic_inc(&substream->mmap_count);
3138 return 0; 3179 return 0;
3139} 3180}
3140 3181
@@ -3166,9 +3207,11 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3166 (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, 3207 (substream->runtime->dma_addr + offset) >> PAGE_SHIFT,
3167 size, area->vm_page_prot)) 3208 size, area->vm_page_prot))
3168 return -EAGAIN; 3209 return -EAGAIN;
3169 atomic_inc(&substream->runtime->mmap_count); 3210 atomic_inc(&substream->mmap_count);
3170 return 0; 3211 return 0;
3171} 3212}
3213
3214EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
3172#endif /* SNDRV_PCM_INFO_MMAP */ 3215#endif /* SNDRV_PCM_INFO_MMAP */
3173 3216
3174/* 3217/*
@@ -3212,6 +3255,8 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
3212 return snd_pcm_default_mmap(substream, area); 3255 return snd_pcm_default_mmap(substream, area);
3213} 3256}
3214 3257
3258EXPORT_SYMBOL(snd_pcm_mmap_data);
3259
3215static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) 3260static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
3216{ 3261{
3217 struct snd_pcm_file * pcm_file; 3262 struct snd_pcm_file * pcm_file;
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 87b47c9564f7..8c15c66eb4aa 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -43,7 +43,7 @@ MODULE_DESCRIPTION("Midlevel RawMidi code for ALSA.");
43MODULE_LICENSE("GPL"); 43MODULE_LICENSE("GPL");
44 44
45#ifdef CONFIG_SND_OSSEMUL 45#ifdef CONFIG_SND_OSSEMUL
46static int midi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0}; 46static int midi_map[SNDRV_CARDS];
47static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; 47static int amidi_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
48module_param_array(midi_map, int, NULL, 0444); 48module_param_array(midi_map, int, NULL, 0444);
49MODULE_PARM_DESC(midi_map, "Raw MIDI device number assigned to 1st OSS device."); 49MODULE_PARM_DESC(midi_map, "Raw MIDI device number assigned to 1st OSS device.");
@@ -1561,7 +1561,6 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
1561 entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); 1561 entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
1562 if (entry) { 1562 if (entry) {
1563 entry->private_data = rmidi; 1563 entry->private_data = rmidi;
1564 entry->c.text.read_size = 1024;
1565 entry->c.text.read = snd_rawmidi_proc_info_read; 1564 entry->c.text.read = snd_rawmidi_proc_info_read;
1566 if (snd_info_register(entry) < 0) { 1565 if (snd_info_register(entry) < 0) {
1567 snd_info_free_entry(entry); 1566 snd_info_free_entry(entry);
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index b9919785180b..e7234135641c 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -291,7 +291,6 @@ register_proc(void)
291 291
292 entry->content = SNDRV_INFO_CONTENT_TEXT; 292 entry->content = SNDRV_INFO_CONTENT_TEXT;
293 entry->private_data = NULL; 293 entry->private_data = NULL;
294 entry->c.text.read_size = 1024;
295 entry->c.text.read = info_read; 294 entry->c.text.read = info_read;
296 if (snd_info_register(entry) < 0) { 295 if (snd_info_register(entry) < 0) {
297 snd_info_free_entry(entry); 296 snd_info_free_entry(entry);
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index 20f954bc7aa0..2f0d8773ac6b 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -129,25 +129,3 @@ static void __exit alsa_seq_exit(void)
129 129
130module_init(alsa_seq_init) 130module_init(alsa_seq_init)
131module_exit(alsa_seq_exit) 131module_exit(alsa_seq_exit)
132
133 /* seq_clientmgr.c */
134EXPORT_SYMBOL(snd_seq_create_kernel_client);
135EXPORT_SYMBOL(snd_seq_delete_kernel_client);
136EXPORT_SYMBOL(snd_seq_kernel_client_enqueue);
137EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking);
138EXPORT_SYMBOL(snd_seq_kernel_client_dispatch);
139EXPORT_SYMBOL(snd_seq_kernel_client_ctl);
140EXPORT_SYMBOL(snd_seq_kernel_client_write_poll);
141EXPORT_SYMBOL(snd_seq_set_queue_tempo);
142 /* seq_memory.c */
143EXPORT_SYMBOL(snd_seq_expand_var_event);
144EXPORT_SYMBOL(snd_seq_dump_var_event);
145 /* seq_ports.c */
146EXPORT_SYMBOL(snd_seq_event_port_attach);
147EXPORT_SYMBOL(snd_seq_event_port_detach);
148 /* seq_lock.c */
149#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
150/*EXPORT_SYMBOL(snd_seq_sleep_in_lock);*/
151/*EXPORT_SYMBOL(snd_seq_sleep_timeout_in_lock);*/
152EXPORT_SYMBOL(snd_use_lock_sync_helper);
153#endif
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index bb15d9ee8842..532a660df51d 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -1714,6 +1714,8 @@ int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo)
1714 return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo); 1714 return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo);
1715} 1715}
1716 1716
1717EXPORT_SYMBOL(snd_seq_set_queue_tempo);
1718
1717static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client, 1719static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client,
1718 void __user *arg) 1720 void __user *arg)
1719{ 1721{
@@ -2264,6 +2266,8 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
2264 return client->number; 2266 return client->number;
2265} 2267}
2266 2268
2269EXPORT_SYMBOL(snd_seq_create_kernel_client);
2270
2267/* exported to kernel modules */ 2271/* exported to kernel modules */
2268int snd_seq_delete_kernel_client(int client) 2272int snd_seq_delete_kernel_client(int client)
2269{ 2273{
@@ -2280,6 +2284,7 @@ int snd_seq_delete_kernel_client(int client)
2280 return 0; 2284 return 0;
2281} 2285}
2282 2286
2287EXPORT_SYMBOL(snd_seq_delete_kernel_client);
2283 2288
2284/* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue 2289/* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue
2285 * and snd_seq_kernel_client_enqueue_blocking 2290 * and snd_seq_kernel_client_enqueue_blocking
@@ -2328,6 +2333,8 @@ int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event * ev,
2328 return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop); 2333 return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop);
2329} 2334}
2330 2335
2336EXPORT_SYMBOL(snd_seq_kernel_client_enqueue);
2337
2331/* 2338/*
2332 * exported, called by kernel clients to enqueue events (with blocking) 2339 * exported, called by kernel clients to enqueue events (with blocking)
2333 * 2340 *
@@ -2340,6 +2347,7 @@ int snd_seq_kernel_client_enqueue_blocking(int client, struct snd_seq_event * ev
2340 return kernel_client_enqueue(client, ev, file, 1, atomic, hop); 2347 return kernel_client_enqueue(client, ev, file, 1, atomic, hop);
2341} 2348}
2342 2349
2350EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking);
2343 2351
2344/* 2352/*
2345 * exported, called by kernel clients to dispatch events directly to other 2353 * exported, called by kernel clients to dispatch events directly to other
@@ -2376,6 +2384,7 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev,
2376 return result; 2384 return result;
2377} 2385}
2378 2386
2387EXPORT_SYMBOL(snd_seq_kernel_client_dispatch);
2379 2388
2380/* 2389/*
2381 * exported, called by kernel clients to perform same functions as with 2390 * exported, called by kernel clients to perform same functions as with
@@ -2396,6 +2405,7 @@ int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
2396 return result; 2405 return result;
2397} 2406}
2398 2407
2408EXPORT_SYMBOL(snd_seq_kernel_client_ctl);
2399 2409
2400/* exported (for OSS emulator) */ 2410/* exported (for OSS emulator) */
2401int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait) 2411int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait)
@@ -2413,6 +2423,8 @@ int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table
2413 return 0; 2423 return 0;
2414} 2424}
2415 2425
2426EXPORT_SYMBOL(snd_seq_kernel_client_write_poll);
2427
2416/*---------------------------------------------------------------------------*/ 2428/*---------------------------------------------------------------------------*/
2417 2429
2418#ifdef CONFIG_PROC_FS 2430#ifdef CONFIG_PROC_FS
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index d9a3e5a18d6a..d812dc886360 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -80,7 +80,7 @@ static LIST_HEAD(opslist);
80static int num_ops; 80static int num_ops;
81static DEFINE_MUTEX(ops_mutex); 81static DEFINE_MUTEX(ops_mutex);
82#ifdef CONFIG_PROC_FS 82#ifdef CONFIG_PROC_FS
83static struct snd_info_entry *info_entry = NULL; 83static struct snd_info_entry *info_entry;
84#endif 84#endif
85 85
86/* 86/*
@@ -555,7 +555,6 @@ static int __init alsa_seq_device_init(void)
555 if (info_entry == NULL) 555 if (info_entry == NULL)
556 return -ENOMEM; 556 return -ENOMEM;
557 info_entry->content = SNDRV_INFO_CONTENT_TEXT; 557 info_entry->content = SNDRV_INFO_CONTENT_TEXT;
558 info_entry->c.text.read_size = 2048;
559 info_entry->c.text.read = snd_seq_device_info; 558 info_entry->c.text.read = snd_seq_device_info;
560 if (snd_info_register(info_entry) < 0) { 559 if (snd_info_register(info_entry) < 0) {
561 snd_info_free_entry(info_entry); 560 snd_info_free_entry(info_entry);
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
index 2a283a59ea4d..e55488d1237c 100644
--- a/sound/core/seq/seq_dummy.c
+++ b/sound/core/seq/seq_dummy.c
@@ -66,7 +66,7 @@ MODULE_LICENSE("GPL");
66MODULE_ALIAS("snd-seq-client-" __stringify(SNDRV_SEQ_CLIENT_DUMMY)); 66MODULE_ALIAS("snd-seq-client-" __stringify(SNDRV_SEQ_CLIENT_DUMMY));
67 67
68static int ports = 1; 68static int ports = 1;
69static int duplex = 0; 69static int duplex;
70 70
71module_param(ports, int, 0444); 71module_param(ports, int, 0444);
72MODULE_PARM_DESC(ports, "number of ports to be created"); 72MODULE_PARM_DESC(ports, "number of ports to be created");
@@ -171,7 +171,9 @@ create_port(int idx, int type)
171 pinfo.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; 171 pinfo.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
172 if (duplex) 172 if (duplex)
173 pinfo.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; 173 pinfo.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
174 pinfo.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; 174 pinfo.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
175 | SNDRV_SEQ_PORT_TYPE_SOFTWARE
176 | SNDRV_SEQ_PORT_TYPE_PORT;
175 memset(&pcb, 0, sizeof(pcb)); 177 memset(&pcb, 0, sizeof(pcb));
176 pcb.owner = THIS_MODULE; 178 pcb.owner = THIS_MODULE;
177 pcb.unuse = dummy_unuse; 179 pcb.unuse = dummy_unuse;
diff --git a/sound/core/seq/seq_info.c b/sound/core/seq/seq_info.c
index acce21afdaa4..142e9e6882c9 100644
--- a/sound/core/seq/seq_info.c
+++ b/sound/core/seq/seq_info.c
@@ -34,8 +34,8 @@ static struct snd_info_entry *timer_entry;
34 34
35 35
36static struct snd_info_entry * __init 36static struct snd_info_entry * __init
37create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *, 37create_info_entry(char *name, void (*read)(struct snd_info_entry *,
38 struct snd_info_buffer *)) 38 struct snd_info_buffer *))
39{ 39{
40 struct snd_info_entry *entry; 40 struct snd_info_entry *entry;
41 41
@@ -43,7 +43,6 @@ create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *,
43 if (entry == NULL) 43 if (entry == NULL)
44 return NULL; 44 return NULL;
45 entry->content = SNDRV_INFO_CONTENT_TEXT; 45 entry->content = SNDRV_INFO_CONTENT_TEXT;
46 entry->c.text.read_size = size;
47 entry->c.text.read = read; 46 entry->c.text.read = read;
48 if (snd_info_register(entry) < 0) { 47 if (snd_info_register(entry) < 0) {
49 snd_info_free_entry(entry); 48 snd_info_free_entry(entry);
@@ -55,11 +54,11 @@ create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *,
55/* create all our /proc entries */ 54/* create all our /proc entries */
56int __init snd_seq_info_init(void) 55int __init snd_seq_info_init(void)
57{ 56{
58 queues_entry = create_info_entry("queues", 512 + (256 * SNDRV_SEQ_MAX_QUEUES), 57 queues_entry = create_info_entry("queues",
59 snd_seq_info_queues_read); 58 snd_seq_info_queues_read);
60 clients_entry = create_info_entry("clients", 512 + (256 * SNDRV_SEQ_MAX_CLIENTS), 59 clients_entry = create_info_entry("clients",
61 snd_seq_info_clients_read); 60 snd_seq_info_clients_read);
62 timer_entry = create_info_entry("timer", 1024, snd_seq_info_timer_read); 61 timer_entry = create_info_entry("timer", snd_seq_info_timer_read);
63 return 0; 62 return 0;
64} 63}
65 64
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c
index a837a94b2d2a..1a34941d4217 100644
--- a/sound/core/seq/seq_lock.c
+++ b/sound/core/seq/seq_lock.c
@@ -44,4 +44,6 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
44 } 44 }
45} 45}
46 46
47EXPORT_SYMBOL(snd_use_lock_sync_helper);
48
47#endif 49#endif
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index 40b4f679c80e..4bffe509f719 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -118,6 +118,8 @@ int snd_seq_dump_var_event(const struct snd_seq_event *event,
118 return 0; 118 return 0;
119} 119}
120 120
121EXPORT_SYMBOL(snd_seq_dump_var_event);
122
121 123
122/* 124/*
123 * exported: 125 * exported:
@@ -167,6 +169,7 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char
167 return err < 0 ? err : newlen; 169 return err < 0 ? err : newlen;
168} 170}
169 171
172EXPORT_SYMBOL(snd_seq_expand_var_event);
170 173
171/* 174/*
172 * release this cell, free extended data if available 175 * release this cell, free extended data if available
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index 9caa1372bece..1daa5b069c79 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -278,6 +278,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
278 struct seq_midisynth *msynth, *ms; 278 struct seq_midisynth *msynth, *ms;
279 struct snd_seq_port_info *port; 279 struct snd_seq_port_info *port;
280 struct snd_rawmidi_info *info; 280 struct snd_rawmidi_info *info;
281 struct snd_rawmidi *rmidi = dev->private_data;
281 int newclient = 0; 282 int newclient = 0;
282 unsigned int p, ports; 283 unsigned int p, ports;
283 struct snd_seq_port_callback pcallbacks; 284 struct snd_seq_port_callback pcallbacks;
@@ -320,8 +321,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
320 } 321 }
321 client->seq_client = 322 client->seq_client =
322 snd_seq_create_kernel_client( 323 snd_seq_create_kernel_client(
323 card, 0, "%s", info->name[0] ? 324 card, 0, "%s", card->shortname[0] ?
324 (const char *)info->name : "External MIDI"); 325 (const char *)card->shortname : "External MIDI");
325 if (client->seq_client < 0) { 326 if (client->seq_client < 0) {
326 kfree(client); 327 kfree(client);
327 mutex_unlock(&register_mutex); 328 mutex_unlock(&register_mutex);
@@ -376,7 +377,9 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
376 if ((port->capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) && 377 if ((port->capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) &&
377 info->flags & SNDRV_RAWMIDI_INFO_DUPLEX) 378 info->flags & SNDRV_RAWMIDI_INFO_DUPLEX)
378 port->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; 379 port->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
379 port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; 380 port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
381 | SNDRV_SEQ_PORT_TYPE_HARDWARE
382 | SNDRV_SEQ_PORT_TYPE_PORT;
380 port->midi_channels = 16; 383 port->midi_channels = 16;
381 memset(&pcallbacks, 0, sizeof(pcallbacks)); 384 memset(&pcallbacks, 0, sizeof(pcallbacks));
382 pcallbacks.owner = THIS_MODULE; 385 pcallbacks.owner = THIS_MODULE;
@@ -387,6 +390,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
387 pcallbacks.unuse = midisynth_unuse; 390 pcallbacks.unuse = midisynth_unuse;
388 pcallbacks.event_input = event_process_midi; 391 pcallbacks.event_input = event_process_midi;
389 port->kernel = &pcallbacks; 392 port->kernel = &pcallbacks;
393 if (rmidi->ops && rmidi->ops->get_port_info)
394 rmidi->ops->get_port_info(rmidi, p, port);
390 if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, port)<0) 395 if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, port)<0)
391 goto __nomem; 396 goto __nomem;
392 ms->seq_client = client->seq_client; 397 ms->seq_client = client->seq_client;
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index 41e078c938cd..334579a9f268 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -221,7 +221,6 @@ static void clear_subscriber_list(struct snd_seq_client *client,
221{ 221{
222 struct list_head *p, *n; 222 struct list_head *p, *n;
223 223
224 down_write(&grp->list_mutex);
225 list_for_each_safe(p, n, &grp->list_head) { 224 list_for_each_safe(p, n, &grp->list_head) {
226 struct snd_seq_subscribers *subs; 225 struct snd_seq_subscribers *subs;
227 struct snd_seq_client *c; 226 struct snd_seq_client *c;
@@ -259,7 +258,6 @@ static void clear_subscriber_list(struct snd_seq_client *client,
259 snd_seq_client_unlock(c); 258 snd_seq_client_unlock(c);
260 } 259 }
261 } 260 }
262 up_write(&grp->list_mutex);
263} 261}
264 262
265/* delete port data */ 263/* delete port data */
@@ -677,6 +675,7 @@ int snd_seq_event_port_attach(int client,
677 return ret; 675 return ret;
678} 676}
679 677
678EXPORT_SYMBOL(snd_seq_event_port_attach);
680 679
681/* 680/*
682 * Detach the driver from a port. 681 * Detach the driver from a port.
@@ -696,3 +695,5 @@ int snd_seq_event_port_detach(int client, int port)
696 695
697 return err; 696 return err;
698} 697}
698
699EXPORT_SYMBOL(snd_seq_event_port_detach);
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index f4edec603b8f..0cfa06c6b81f 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -390,7 +390,9 @@ static int snd_virmidi_dev_attach_seq(struct snd_virmidi_dev *rdev)
390 pinfo->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; 390 pinfo->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
391 pinfo->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ; 391 pinfo->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
392 pinfo->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; 392 pinfo->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
393 pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC; 393 pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
394 | SNDRV_SEQ_PORT_TYPE_SOFTWARE
395 | SNDRV_SEQ_PORT_TYPE_PORT;
394 pinfo->midi_channels = 16; 396 pinfo->midi_channels = 16;
395 memset(&pcallbacks, 0, sizeof(pcallbacks)); 397 memset(&pcallbacks, 0, sizeof(pcallbacks));
396 pcallbacks.owner = THIS_MODULE; 398 pcallbacks.owner = THIS_MODULE;
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 108e430b5036..cd862728346c 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -39,6 +39,8 @@
39 39
40static int major = CONFIG_SND_MAJOR; 40static int major = CONFIG_SND_MAJOR;
41int snd_major; 41int snd_major;
42EXPORT_SYMBOL(snd_major);
43
42static int cards_limit = 1; 44static int cards_limit = 1;
43static int device_mode = S_IFCHR | S_IRUGO | S_IWUGO; 45static int device_mode = S_IFCHR | S_IRUGO | S_IWUGO;
44 46
@@ -60,6 +62,7 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
60 * modules are loaded manually, this limit number increases, too. 62 * modules are loaded manually, this limit number increases, too.
61 */ 63 */
62int snd_ecards_limit; 64int snd_ecards_limit;
65EXPORT_SYMBOL(snd_ecards_limit);
63 66
64static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; 67static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
65static DEFINE_MUTEX(sound_mutex); 68static DEFINE_MUTEX(sound_mutex);
@@ -78,20 +81,17 @@ extern struct class *sound_class;
78 */ 81 */
79void snd_request_card(int card) 82void snd_request_card(int card)
80{ 83{
81 int locked;
82
83 if (! current->fs->root) 84 if (! current->fs->root)
84 return; 85 return;
85 read_lock(&snd_card_rwlock); 86 if (snd_card_locked(card))
86 locked = snd_cards_lock & (1 << card);
87 read_unlock(&snd_card_rwlock);
88 if (locked)
89 return; 87 return;
90 if (card < 0 || card >= cards_limit) 88 if (card < 0 || card >= cards_limit)
91 return; 89 return;
92 request_module("snd-card-%i", card); 90 request_module("snd-card-%i", card);
93} 91}
94 92
93EXPORT_SYMBOL(snd_request_card);
94
95static void snd_request_other(int minor) 95static void snd_request_other(int minor)
96{ 96{
97 char *str; 97 char *str;
@@ -133,6 +133,8 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
133 return private_data; 133 return private_data;
134} 134}
135 135
136EXPORT_SYMBOL(snd_lookup_minor_data);
137
136static int snd_open(struct inode *inode, struct file *file) 138static int snd_open(struct inode *inode, struct file *file)
137{ 139{
138 unsigned int minor = iminor(inode); 140 unsigned int minor = iminor(inode);
@@ -281,6 +283,8 @@ int snd_register_device(int type, struct snd_card *card, int dev,
281 return 0; 283 return 0;
282} 284}
283 285
286EXPORT_SYMBOL(snd_register_device);
287
284/** 288/**
285 * snd_unregister_device - unregister the device on the given card 289 * snd_unregister_device - unregister the device on the given card
286 * @type: the device type, SNDRV_DEVICE_TYPE_XXX 290 * @type: the device type, SNDRV_DEVICE_TYPE_XXX
@@ -321,12 +325,14 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
321 return 0; 325 return 0;
322} 326}
323 327
328EXPORT_SYMBOL(snd_unregister_device);
329
324#ifdef CONFIG_PROC_FS 330#ifdef CONFIG_PROC_FS
325/* 331/*
326 * INFO PART 332 * INFO PART
327 */ 333 */
328 334
329static struct snd_info_entry *snd_minor_info_entry = NULL; 335static struct snd_info_entry *snd_minor_info_entry;
330 336
331static const char *snd_device_type_name(int type) 337static const char *snd_device_type_name(int type)
332{ 338{
@@ -381,7 +387,6 @@ int __init snd_minor_info_init(void)
381 387
382 entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL); 388 entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL);
383 if (entry) { 389 if (entry) {
384 entry->c.text.read_size = PAGE_SIZE;
385 entry->c.text.read = snd_minor_info_read; 390 entry->c.text.read = snd_minor_info_read;
386 if (snd_info_register(entry) < 0) { 391 if (snd_info_register(entry) < 0) {
387 snd_info_free_entry(entry); 392 snd_info_free_entry(entry);
@@ -446,91 +451,3 @@ static void __exit alsa_sound_exit(void)
446 451
447module_init(alsa_sound_init) 452module_init(alsa_sound_init)
448module_exit(alsa_sound_exit) 453module_exit(alsa_sound_exit)
449
450 /* sound.c */
451EXPORT_SYMBOL(snd_major);
452EXPORT_SYMBOL(snd_ecards_limit);
453#if defined(CONFIG_KMOD)
454EXPORT_SYMBOL(snd_request_card);
455#endif
456EXPORT_SYMBOL(snd_register_device);
457EXPORT_SYMBOL(snd_unregister_device);
458EXPORT_SYMBOL(snd_lookup_minor_data);
459#if defined(CONFIG_SND_OSSEMUL)
460EXPORT_SYMBOL(snd_register_oss_device);
461EXPORT_SYMBOL(snd_unregister_oss_device);
462EXPORT_SYMBOL(snd_lookup_oss_minor_data);
463#endif
464 /* memory.c */
465EXPORT_SYMBOL(copy_to_user_fromio);
466EXPORT_SYMBOL(copy_from_user_toio);
467 /* init.c */
468EXPORT_SYMBOL(snd_cards);
469#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
470EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
471#endif
472EXPORT_SYMBOL(snd_card_new);
473EXPORT_SYMBOL(snd_card_disconnect);
474EXPORT_SYMBOL(snd_card_free);
475EXPORT_SYMBOL(snd_card_free_in_thread);
476EXPORT_SYMBOL(snd_card_register);
477EXPORT_SYMBOL(snd_component_add);
478EXPORT_SYMBOL(snd_card_file_add);
479EXPORT_SYMBOL(snd_card_file_remove);
480#ifdef CONFIG_PM
481EXPORT_SYMBOL(snd_power_wait);
482#endif
483 /* device.c */
484EXPORT_SYMBOL(snd_device_new);
485EXPORT_SYMBOL(snd_device_register);
486EXPORT_SYMBOL(snd_device_free);
487 /* isadma.c */
488#ifdef CONFIG_ISA_DMA_API
489EXPORT_SYMBOL(snd_dma_program);
490EXPORT_SYMBOL(snd_dma_disable);
491EXPORT_SYMBOL(snd_dma_pointer);
492#endif
493 /* info.c */
494#ifdef CONFIG_PROC_FS
495EXPORT_SYMBOL(snd_seq_root);
496EXPORT_SYMBOL(snd_iprintf);
497EXPORT_SYMBOL(snd_info_get_line);
498EXPORT_SYMBOL(snd_info_get_str);
499EXPORT_SYMBOL(snd_info_create_module_entry);
500EXPORT_SYMBOL(snd_info_create_card_entry);
501EXPORT_SYMBOL(snd_info_free_entry);
502EXPORT_SYMBOL(snd_info_register);
503EXPORT_SYMBOL(snd_info_unregister);
504EXPORT_SYMBOL(snd_card_proc_new);
505#endif
506 /* info_oss.c */
507#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
508EXPORT_SYMBOL(snd_oss_info_register);
509#endif
510 /* control.c */
511EXPORT_SYMBOL(snd_ctl_new);
512EXPORT_SYMBOL(snd_ctl_new1);
513EXPORT_SYMBOL(snd_ctl_free_one);
514EXPORT_SYMBOL(snd_ctl_add);
515EXPORT_SYMBOL(snd_ctl_remove);
516EXPORT_SYMBOL(snd_ctl_remove_id);
517EXPORT_SYMBOL(snd_ctl_rename_id);
518EXPORT_SYMBOL(snd_ctl_find_numid);
519EXPORT_SYMBOL(snd_ctl_find_id);
520EXPORT_SYMBOL(snd_ctl_notify);
521EXPORT_SYMBOL(snd_ctl_register_ioctl);
522EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
523#ifdef CONFIG_COMPAT
524EXPORT_SYMBOL(snd_ctl_register_ioctl_compat);
525EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
526#endif
527EXPORT_SYMBOL(snd_ctl_elem_read);
528EXPORT_SYMBOL(snd_ctl_elem_write);
529 /* misc.c */
530EXPORT_SYMBOL(release_and_free_resource);
531#ifdef CONFIG_SND_VERBOSE_PRINTK
532EXPORT_SYMBOL(snd_verbose_printk);
533#endif
534#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
535EXPORT_SYMBOL(snd_verbose_printd);
536#endif
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index 9055c6de9587..74f0fe5a1ba0 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -58,6 +58,8 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type)
58 return private_data; 58 return private_data;
59} 59}
60 60
61EXPORT_SYMBOL(snd_lookup_oss_minor_data);
62
61static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) 63static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
62{ 64{
63 int minor; 65 int minor;
@@ -158,6 +160,8 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
158 return -EBUSY; 160 return -EBUSY;
159} 161}
160 162
163EXPORT_SYMBOL(snd_register_oss_device);
164
161int snd_unregister_oss_device(int type, struct snd_card *card, int dev) 165int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
162{ 166{
163 int minor = snd_oss_kernel_minor(type, card, dev); 167 int minor = snd_oss_kernel_minor(type, card, dev);
@@ -197,13 +201,15 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
197 return 0; 201 return 0;
198} 202}
199 203
204EXPORT_SYMBOL(snd_unregister_oss_device);
205
200/* 206/*
201 * INFO PART 207 * INFO PART
202 */ 208 */
203 209
204#ifdef CONFIG_PROC_FS 210#ifdef CONFIG_PROC_FS
205 211
206static struct snd_info_entry *snd_minor_info_oss_entry = NULL; 212static struct snd_info_entry *snd_minor_info_oss_entry;
207 213
208static const char *snd_oss_device_type_name(int type) 214static const char *snd_oss_device_type_name(int type)
209{ 215{
@@ -252,7 +258,6 @@ int __init snd_minor_info_oss_init(void)
252 258
253 entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root); 259 entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root);
254 if (entry) { 260 if (entry) {
255 entry->c.text.read_size = PAGE_SIZE;
256 entry->c.text.read = snd_minor_info_oss_read; 261 entry->c.text.read = snd_minor_info_oss_read;
257 if (snd_info_register(entry) < 0) { 262 if (snd_info_register(entry) < 0) {
258 snd_info_free_entry(entry); 263 snd_info_free_entry(entry);
diff --git a/sound/core/timer.c b/sound/core/timer.c
index cdeeb639b675..78199f58b93a 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1061,7 +1061,6 @@ static int snd_timer_register_system(void)
1061static void snd_timer_proc_read(struct snd_info_entry *entry, 1061static void snd_timer_proc_read(struct snd_info_entry *entry,
1062 struct snd_info_buffer *buffer) 1062 struct snd_info_buffer *buffer)
1063{ 1063{
1064 unsigned long flags;
1065 struct snd_timer *timer; 1064 struct snd_timer *timer;
1066 struct snd_timer_instance *ti; 1065 struct snd_timer_instance *ti;
1067 struct list_head *p, *q; 1066 struct list_head *p, *q;
@@ -1095,7 +1094,6 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
1095 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) 1094 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
1096 snd_iprintf(buffer, " SLAVE"); 1095 snd_iprintf(buffer, " SLAVE");
1097 snd_iprintf(buffer, "\n"); 1096 snd_iprintf(buffer, "\n");
1098 spin_lock_irqsave(&timer->lock, flags);
1099 list_for_each(q, &timer->open_list_head) { 1097 list_for_each(q, &timer->open_list_head) {
1100 ti = list_entry(q, struct snd_timer_instance, open_list); 1098 ti = list_entry(q, struct snd_timer_instance, open_list);
1101 snd_iprintf(buffer, " Client %s : %s\n", 1099 snd_iprintf(buffer, " Client %s : %s\n",
@@ -1104,12 +1102,11 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
1104 SNDRV_TIMER_IFLG_RUNNING) 1102 SNDRV_TIMER_IFLG_RUNNING)
1105 ? "running" : "stopped"); 1103 ? "running" : "stopped");
1106 } 1104 }
1107 spin_unlock_irqrestore(&timer->lock, flags);
1108 } 1105 }
1109 mutex_unlock(&register_mutex); 1106 mutex_unlock(&register_mutex);
1110} 1107}
1111 1108
1112static struct snd_info_entry *snd_timer_proc_entry = NULL; 1109static struct snd_info_entry *snd_timer_proc_entry;
1113 1110
1114static void __init snd_timer_proc_init(void) 1111static void __init snd_timer_proc_init(void)
1115{ 1112{
@@ -1117,7 +1114,6 @@ static void __init snd_timer_proc_init(void)
1117 1114
1118 entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL); 1115 entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
1119 if (entry != NULL) { 1116 if (entry != NULL) {
1120 entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128;
1121 entry->c.text.read = snd_timer_proc_read; 1117 entry->c.text.read = snd_timer_proc_read;
1122 if (snd_info_register(entry) < 0) { 1118 if (snd_info_register(entry) < 0) {
1123 snd_info_free_entry(entry); 1119 snd_info_free_entry(entry);
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index ae0df549fac7..ffeafaf2ecca 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -677,6 +677,10 @@ static int __init alsa_card_dummy_init(void)
677 i, NULL, 0); 677 i, NULL, 0);
678 if (IS_ERR(device)) 678 if (IS_ERR(device))
679 continue; 679 continue;
680 if (!platform_get_drvdata(device)) {
681 platform_device_unregister(device);
682 continue;
683 }
680 devices[i] = device; 684 devices[i] = device;
681 cards++; 685 cards++;
682 } 686 }
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 77b06009735d..d3cbbb047582 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -253,6 +253,10 @@ static int __init alsa_card_mpu401_init(void)
253 i, NULL, 0); 253 i, NULL, 0);
254 if (IS_ERR(device)) 254 if (IS_ERR(device))
255 continue; 255 continue;
256 if (!platform_get_drvdata(device)) {
257 platform_device_unregister(device);
258 continue;
259 }
256 platform_devices[i] = device; 260 platform_devices[i] = device;
257 snd_mpu401_devices++; 261 snd_mpu401_devices++;
258 } 262 }
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index b49a45cbf67a..4bf07ca9b17d 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -58,22 +58,26 @@ static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu);
58#define MPU401_ACK 0xfe 58#define MPU401_ACK 0xfe
59 59
60/* Build in lowlevel io */ 60/* Build in lowlevel io */
61static void mpu401_write_port(struct snd_mpu401 *mpu, unsigned char data, unsigned long addr) 61static void mpu401_write_port(struct snd_mpu401 *mpu, unsigned char data,
62 unsigned long addr)
62{ 63{
63 outb(data, addr); 64 outb(data, addr);
64} 65}
65 66
66static unsigned char mpu401_read_port(struct snd_mpu401 *mpu, unsigned long addr) 67static unsigned char mpu401_read_port(struct snd_mpu401 *mpu,
68 unsigned long addr)
67{ 69{
68 return inb(addr); 70 return inb(addr);
69} 71}
70 72
71static void mpu401_write_mmio(struct snd_mpu401 *mpu, unsigned char data, unsigned long addr) 73static void mpu401_write_mmio(struct snd_mpu401 *mpu, unsigned char data,
74 unsigned long addr)
72{ 75{
73 writeb(data, (void __iomem *)addr); 76 writeb(data, (void __iomem *)addr);
74} 77}
75 78
76static unsigned char mpu401_read_mmio(struct snd_mpu401 *mpu, unsigned long addr) 79static unsigned char mpu401_read_mmio(struct snd_mpu401 *mpu,
80 unsigned long addr)
77{ 81{
78 return readb((void __iomem *)addr); 82 return readb((void __iomem *)addr);
79} 83}
@@ -86,20 +90,13 @@ static void snd_mpu401_uart_clear_rx(struct snd_mpu401 *mpu)
86 mpu->read(mpu, MPU401D(mpu)); 90 mpu->read(mpu, MPU401D(mpu));
87#ifdef CONFIG_SND_DEBUG 91#ifdef CONFIG_SND_DEBUG
88 if (timeout <= 0) 92 if (timeout <= 0)
89 snd_printk("cmd: clear rx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu))); 93 snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n",
94 mpu->read(mpu, MPU401C(mpu)));
90#endif 95#endif
91} 96}
92 97
93static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu) 98static void uart_interrupt_tx(struct snd_mpu401 *mpu)
94{ 99{
95 spin_lock(&mpu->input_lock);
96 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
97 snd_mpu401_uart_input_read(mpu);
98 } else {
99 snd_mpu401_uart_clear_rx(mpu);
100 }
101 spin_unlock(&mpu->input_lock);
102 /* ok. for better Tx performance try do some output when input is done */
103 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && 100 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
104 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { 101 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
105 spin_lock(&mpu->output_lock); 102 spin_lock(&mpu->output_lock);
@@ -108,6 +105,22 @@ static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
108 } 105 }
109} 106}
110 107
108static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
109{
110 if (mpu->info_flags & MPU401_INFO_INPUT) {
111 spin_lock(&mpu->input_lock);
112 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
113 snd_mpu401_uart_input_read(mpu);
114 else
115 snd_mpu401_uart_clear_rx(mpu);
116 spin_unlock(&mpu->input_lock);
117 }
118 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
119 /* ok. for better Tx performance try do some output
120 when input is done */
121 uart_interrupt_tx(mpu);
122}
123
111/** 124/**
112 * snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler 125 * snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler
113 * @irq: the irq number 126 * @irq: the irq number
@@ -116,7 +129,8 @@ static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
116 * 129 *
117 * Processes the interrupt for MPU401-UART i/o. 130 * Processes the interrupt for MPU401-UART i/o.
118 */ 131 */
119irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs) 132irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id,
133 struct pt_regs *regs)
120{ 134{
121 struct snd_mpu401 *mpu = dev_id; 135 struct snd_mpu401 *mpu = dev_id;
122 136
@@ -126,6 +140,29 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *reg
126 return IRQ_HANDLED; 140 return IRQ_HANDLED;
127} 141}
128 142
143EXPORT_SYMBOL(snd_mpu401_uart_interrupt);
144
145/**
146 * snd_mpu401_uart_interrupt_tx - generic MPU401-UART transmit irq handler
147 * @irq: the irq number
148 * @dev_id: mpu401 instance
149 * @regs: the reigster
150 *
151 * Processes the interrupt for MPU401-UART output.
152 */
153irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id,
154 struct pt_regs *regs)
155{
156 struct snd_mpu401 *mpu = dev_id;
157
158 if (mpu == NULL)
159 return IRQ_NONE;
160 uart_interrupt_tx(mpu);
161 return IRQ_HANDLED;
162}
163
164EXPORT_SYMBOL(snd_mpu401_uart_interrupt_tx);
165
129/* 166/*
130 * timer callback 167 * timer callback
131 * reprogram the timer and call the interrupt job 168 * reprogram the timer and call the interrupt job
@@ -159,7 +196,8 @@ static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input)
159 mpu->timer.expires = 1 + jiffies; 196 mpu->timer.expires = 1 + jiffies;
160 add_timer(&mpu->timer); 197 add_timer(&mpu->timer);
161 } 198 }
162 mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER : MPU401_MODE_OUTPUT_TIMER; 199 mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER :
200 MPU401_MODE_OUTPUT_TIMER;
163 spin_unlock_irqrestore (&mpu->timer_lock, flags); 201 spin_unlock_irqrestore (&mpu->timer_lock, flags);
164} 202}
165 203
@@ -172,7 +210,8 @@ static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input)
172 210
173 spin_lock_irqsave (&mpu->timer_lock, flags); 211 spin_lock_irqsave (&mpu->timer_lock, flags);
174 if (mpu->timer_invoked) { 212 if (mpu->timer_invoked) {
175 mpu->timer_invoked &= input ? ~MPU401_MODE_INPUT_TIMER : ~MPU401_MODE_OUTPUT_TIMER; 213 mpu->timer_invoked &= input ? ~MPU401_MODE_INPUT_TIMER :
214 ~MPU401_MODE_OUTPUT_TIMER;
176 if (! mpu->timer_invoked) 215 if (! mpu->timer_invoked)
177 del_timer(&mpu->timer); 216 del_timer(&mpu->timer);
178 } 217 }
@@ -180,11 +219,12 @@ static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input)
180} 219}
181 220
182/* 221/*
183 222 * send a UART command
223 * return zero if successful, non-zero for some errors
184 */ 224 */
185 225
186static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, 226static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
187 int ack) 227 int ack)
188{ 228{
189 unsigned long flags; 229 unsigned long flags;
190 int timeout, ok; 230 int timeout, ok;
@@ -196,11 +236,13 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
196 } 236 }
197 /* ok. standard MPU-401 initialization */ 237 /* ok. standard MPU-401 initialization */
198 if (mpu->hardware != MPU401_HW_SB) { 238 if (mpu->hardware != MPU401_HW_SB) {
199 for (timeout = 1000; timeout > 0 && !snd_mpu401_output_ready(mpu); timeout--) 239 for (timeout = 1000; timeout > 0 &&
240 !snd_mpu401_output_ready(mpu); timeout--)
200 udelay(10); 241 udelay(10);
201#ifdef CONFIG_SND_DEBUG 242#ifdef CONFIG_SND_DEBUG
202 if (!timeout) 243 if (!timeout)
203 snd_printk("cmd: tx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu))); 244 snd_printk(KERN_ERR "cmd: tx timeout (status = 0x%x)\n",
245 mpu->read(mpu, MPU401C(mpu)));
204#endif 246#endif
205 } 247 }
206 mpu->write(mpu, cmd, MPU401C(mpu)); 248 mpu->write(mpu, cmd, MPU401C(mpu));
@@ -215,12 +257,14 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
215 } 257 }
216 if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK) 258 if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK)
217 ok = 1; 259 ok = 1;
218 } else { 260 } else
219 ok = 1; 261 ok = 1;
220 }
221 spin_unlock_irqrestore(&mpu->input_lock, flags); 262 spin_unlock_irqrestore(&mpu->input_lock, flags);
222 if (!ok) { 263 if (!ok) {
223 snd_printk("cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu))); 264 snd_printk(KERN_ERR "cmd: 0x%x failed at 0x%lx "
265 "(status = 0x%x, data = 0x%x)\n", cmd, mpu->port,
266 mpu->read(mpu, MPU401C(mpu)),
267 mpu->read(mpu, MPU401D(mpu)));
224 return 1; 268 return 1;
225 } 269 }
226 return 0; 270 return 0;
@@ -314,7 +358,8 @@ static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream)
314/* 358/*
315 * trigger input callback 359 * trigger input callback
316 */ 360 */
317static void snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up) 361static void
362snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
318{ 363{
319 unsigned long flags; 364 unsigned long flags;
320 struct snd_mpu401 *mpu; 365 struct snd_mpu401 *mpu;
@@ -322,7 +367,8 @@ static void snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substrea
322 367
323 mpu = substream->rmidi->private_data; 368 mpu = substream->rmidi->private_data;
324 if (up) { 369 if (up) {
325 if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) { 370 if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER,
371 &mpu->mode)) {
326 /* first time - flush FIFO */ 372 /* first time - flush FIFO */
327 while (max-- > 0) 373 while (max-- > 0)
328 mpu->read(mpu, MPU401D(mpu)); 374 mpu->read(mpu, MPU401D(mpu));
@@ -352,13 +398,11 @@ static void snd_mpu401_uart_input_read(struct snd_mpu401 * mpu)
352 unsigned char byte; 398 unsigned char byte;
353 399
354 while (max-- > 0) { 400 while (max-- > 0) {
355 if (snd_mpu401_input_avail(mpu)) { 401 if (! snd_mpu401_input_avail(mpu))
356 byte = mpu->read(mpu, MPU401D(mpu));
357 if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode))
358 snd_rawmidi_receive(mpu->substream_input, &byte, 1);
359 } else {
360 break; /* input not available */ 402 break; /* input not available */
361 } 403 byte = mpu->read(mpu, MPU401D(mpu));
404 if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode))
405 snd_rawmidi_receive(mpu->substream_input, &byte, 1);
362 } 406 }
363} 407}
364 408
@@ -380,16 +424,16 @@ static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu)
380 int max = 256, timeout; 424 int max = 256, timeout;
381 425
382 do { 426 do {
383 if (snd_rawmidi_transmit_peek(mpu->substream_output, &byte, 1) == 1) { 427 if (snd_rawmidi_transmit_peek(mpu->substream_output,
428 &byte, 1) == 1) {
384 for (timeout = 100; timeout > 0; timeout--) { 429 for (timeout = 100; timeout > 0; timeout--) {
385 if (snd_mpu401_output_ready(mpu)) { 430 if (snd_mpu401_output_ready(mpu))
386 mpu->write(mpu, byte, MPU401D(mpu));
387 snd_rawmidi_transmit_ack(mpu->substream_output, 1);
388 break; 431 break;
389 }
390 } 432 }
391 if (timeout == 0) 433 if (timeout == 0)
392 break; /* Tx FIFO full - try again later */ 434 break; /* Tx FIFO full - try again later */
435 mpu->write(mpu, byte, MPU401D(mpu));
436 snd_rawmidi_transmit_ack(mpu->substream_output, 1);
393 } else { 437 } else {
394 snd_mpu401_uart_remove_timer (mpu, 0); 438 snd_mpu401_uart_remove_timer (mpu, 0);
395 break; /* no other data - leave the tx loop */ 439 break; /* no other data - leave the tx loop */
@@ -400,7 +444,8 @@ static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu)
400/* 444/*
401 * output trigger callback 445 * output trigger callback
402 */ 446 */
403static void snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up) 447static void
448snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up)
404{ 449{
405 unsigned long flags; 450 unsigned long flags;
406 struct snd_mpu401 *mpu; 451 struct snd_mpu401 *mpu;
@@ -413,14 +458,16 @@ static void snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substre
413 * since the output timer might have been removed in 458 * since the output timer might have been removed in
414 * snd_mpu401_uart_output_write(). 459 * snd_mpu401_uart_output_write().
415 */ 460 */
416 snd_mpu401_uart_add_timer(mpu, 0); 461 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
462 snd_mpu401_uart_add_timer(mpu, 0);
417 463
418 /* output pending data */ 464 /* output pending data */
419 spin_lock_irqsave(&mpu->output_lock, flags); 465 spin_lock_irqsave(&mpu->output_lock, flags);
420 snd_mpu401_uart_output_write(mpu); 466 snd_mpu401_uart_output_write(mpu);
421 spin_unlock_irqrestore(&mpu->output_lock, flags); 467 spin_unlock_irqrestore(&mpu->output_lock, flags);
422 } else { 468 } else {
423 snd_mpu401_uart_remove_timer(mpu, 0); 469 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
470 snd_mpu401_uart_remove_timer(mpu, 0);
424 clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); 471 clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode);
425 } 472 }
426} 473}
@@ -458,7 +505,7 @@ static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi)
458 * @device: the device index, zero-based 505 * @device: the device index, zero-based
459 * @hardware: the hardware type, MPU401_HW_XXXX 506 * @hardware: the hardware type, MPU401_HW_XXXX
460 * @port: the base address of MPU401 port 507 * @port: the base address of MPU401 port
461 * @integrated: non-zero if the port was already reserved by the chip 508 * @info_flags: bitflags MPU401_INFO_XXX
462 * @irq: the irq number, -1 if no interrupt for mpu 509 * @irq: the irq number, -1 if no interrupt for mpu
463 * @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved. 510 * @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved.
464 * @rrawmidi: the pointer to store the new rawmidi instance 511 * @rrawmidi: the pointer to store the new rawmidi instance
@@ -473,17 +520,24 @@ static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi)
473 */ 520 */
474int snd_mpu401_uart_new(struct snd_card *card, int device, 521int snd_mpu401_uart_new(struct snd_card *card, int device,
475 unsigned short hardware, 522 unsigned short hardware,
476 unsigned long port, int integrated, 523 unsigned long port,
524 unsigned int info_flags,
477 int irq, int irq_flags, 525 int irq, int irq_flags,
478 struct snd_rawmidi ** rrawmidi) 526 struct snd_rawmidi ** rrawmidi)
479{ 527{
480 struct snd_mpu401 *mpu; 528 struct snd_mpu401 *mpu;
481 struct snd_rawmidi *rmidi; 529 struct snd_rawmidi *rmidi;
530 int in_enable, out_enable;
482 int err; 531 int err;
483 532
484 if (rrawmidi) 533 if (rrawmidi)
485 *rrawmidi = NULL; 534 *rrawmidi = NULL;
486 if ((err = snd_rawmidi_new(card, "MPU-401U", device, 1, 1, &rmidi)) < 0) 535 if (! (info_flags & (MPU401_INFO_INPUT | MPU401_INFO_OUTPUT)))
536 info_flags |= MPU401_INFO_INPUT | MPU401_INFO_OUTPUT;
537 in_enable = (info_flags & MPU401_INFO_INPUT) ? 1 : 0;
538 out_enable = (info_flags & MPU401_INFO_OUTPUT) ? 1 : 0;
539 if ((err = snd_rawmidi_new(card, "MPU-401U", device,
540 out_enable, in_enable, &rmidi)) < 0)
487 return err; 541 return err;
488 mpu = kzalloc(sizeof(*mpu), GFP_KERNEL); 542 mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
489 if (mpu == NULL) { 543 if (mpu == NULL) {
@@ -497,23 +551,23 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
497 spin_lock_init(&mpu->output_lock); 551 spin_lock_init(&mpu->output_lock);
498 spin_lock_init(&mpu->timer_lock); 552 spin_lock_init(&mpu->timer_lock);
499 mpu->hardware = hardware; 553 mpu->hardware = hardware;
500 if (!integrated) { 554 if (! (info_flags & MPU401_INFO_INTEGRATED)) {
501 int res_size = hardware == MPU401_HW_PC98II ? 4 : 2; 555 int res_size = hardware == MPU401_HW_PC98II ? 4 : 2;
502 if ((mpu->res = request_region(port, res_size, "MPU401 UART")) == NULL) { 556 mpu->res = request_region(port, res_size, "MPU401 UART");
503 snd_printk(KERN_ERR "mpu401_uart: unable to grab port 0x%lx size %d\n", port, res_size); 557 if (mpu->res == NULL) {
558 snd_printk(KERN_ERR "mpu401_uart: "
559 "unable to grab port 0x%lx size %d\n",
560 port, res_size);
504 snd_device_free(card, rmidi); 561 snd_device_free(card, rmidi);
505 return -EBUSY; 562 return -EBUSY;
506 } 563 }
507 } 564 }
508 switch (hardware) { 565 if (info_flags & MPU401_INFO_MMIO) {
509 case MPU401_HW_AUREAL:
510 mpu->write = mpu401_write_mmio; 566 mpu->write = mpu401_write_mmio;
511 mpu->read = mpu401_read_mmio; 567 mpu->read = mpu401_read_mmio;
512 break; 568 } else {
513 default:
514 mpu->write = mpu401_write_port; 569 mpu->write = mpu401_write_port;
515 mpu->read = mpu401_read_port; 570 mpu->read = mpu401_read_port;
516 break;
517 } 571 }
518 mpu->port = port; 572 mpu->port = port;
519 if (hardware == MPU401_HW_PC98II) 573 if (hardware == MPU401_HW_PC98II)
@@ -521,30 +575,40 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
521 else 575 else
522 mpu->cport = port + 1; 576 mpu->cport = port + 1;
523 if (irq >= 0 && irq_flags) { 577 if (irq >= 0 && irq_flags) {
524 if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags, "MPU401 UART", (void *) mpu)) { 578 if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags,
525 snd_printk(KERN_ERR "mpu401_uart: unable to grab IRQ %d\n", irq); 579 "MPU401 UART", (void *) mpu)) {
580 snd_printk(KERN_ERR "mpu401_uart: "
581 "unable to grab IRQ %d\n", irq);
526 snd_device_free(card, rmidi); 582 snd_device_free(card, rmidi);
527 return -EBUSY; 583 return -EBUSY;
528 } 584 }
529 } 585 }
586 mpu->info_flags = info_flags;
530 mpu->irq = irq; 587 mpu->irq = irq;
531 mpu->irq_flags = irq_flags; 588 mpu->irq_flags = irq_flags;
532 if (card->shortname[0]) 589 if (card->shortname[0])
533 snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI", card->shortname); 590 snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI",
591 card->shortname);
534 else 592 else
535 sprintf(rmidi->name, "MPU-401 MIDI %d-%d", card->number, device); 593 sprintf(rmidi->name, "MPU-401 MIDI %d-%d",card->number, device);
536 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mpu401_uart_output); 594 if (out_enable) {
537 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mpu401_uart_input); 595 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
538 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | 596 &snd_mpu401_uart_output);
539 SNDRV_RAWMIDI_INFO_INPUT | 597 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
540 SNDRV_RAWMIDI_INFO_DUPLEX; 598 }
599 if (in_enable) {
600 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
601 &snd_mpu401_uart_input);
602 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
603 if (out_enable)
604 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
605 }
541 mpu->rmidi = rmidi; 606 mpu->rmidi = rmidi;
542 if (rrawmidi) 607 if (rrawmidi)
543 *rrawmidi = rmidi; 608 *rrawmidi = rmidi;
544 return 0; 609 return 0;
545} 610}
546 611
547EXPORT_SYMBOL(snd_mpu401_uart_interrupt);
548EXPORT_SYMBOL(snd_mpu401_uart_new); 612EXPORT_SYMBOL(snd_mpu401_uart_new);
549 613
550/* 614/*
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index b7a0b42813e1..474eed06e70f 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -770,11 +770,15 @@ static int __init alsa_card_mtpav_init(void)
770 return err; 770 return err;
771 771
772 device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0); 772 device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0);
773 if (IS_ERR(device)) { 773 if (!IS_ERR(device)) {
774 platform_driver_unregister(&snd_mtpav_driver); 774 if (platform_get_drvdata(device))
775 return PTR_ERR(device); 775 return 0;
776 } 776 platform_device_unregister(device);
777 return 0; 777 err = -ENODEV;
778 } else
779 err = PTR_ERR(device);
780 platform_driver_unregister(&snd_mtpav_driver);
781 return err;
778} 782}
779 783
780static void __exit alsa_card_mtpav_exit(void) 784static void __exit alsa_card_mtpav_exit(void)
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index 4f8556976774..87fe376f38f0 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -316,6 +316,8 @@ void snd_opl3_interrupt(struct snd_hwdep * hw)
316 } 316 }
317} 317}
318 318
319EXPORT_SYMBOL(snd_opl3_interrupt);
320
319/* 321/*
320 322
321 */ 323 */
@@ -369,6 +371,8 @@ int snd_opl3_new(struct snd_card *card,
369 return 0; 371 return 0;
370} 372}
371 373
374EXPORT_SYMBOL(snd_opl3_new);
375
372int snd_opl3_init(struct snd_opl3 *opl3) 376int snd_opl3_init(struct snd_opl3 *opl3)
373{ 377{
374 if (! opl3->command) { 378 if (! opl3->command) {
@@ -393,6 +397,8 @@ int snd_opl3_init(struct snd_opl3 *opl3)
393 return 0; 397 return 0;
394} 398}
395 399
400EXPORT_SYMBOL(snd_opl3_init);
401
396int snd_opl3_create(struct snd_card *card, 402int snd_opl3_create(struct snd_card *card,
397 unsigned long l_port, 403 unsigned long l_port,
398 unsigned long r_port, 404 unsigned long r_port,
@@ -451,6 +457,8 @@ int snd_opl3_create(struct snd_card *card,
451 return 0; 457 return 0;
452} 458}
453 459
460EXPORT_SYMBOL(snd_opl3_create);
461
454int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev) 462int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
455{ 463{
456 int err; 464 int err;
@@ -468,6 +476,8 @@ int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
468 return 0; 476 return 0;
469} 477}
470 478
479EXPORT_SYMBOL(snd_opl3_timer_new);
480
471int snd_opl3_hwdep_new(struct snd_opl3 * opl3, 481int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
472 int device, int seq_device, 482 int device, int seq_device,
473 struct snd_hwdep ** rhwdep) 483 struct snd_hwdep ** rhwdep)
@@ -526,17 +536,8 @@ int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
526 return 0; 536 return 0;
527} 537}
528 538
529EXPORT_SYMBOL(snd_opl3_interrupt);
530EXPORT_SYMBOL(snd_opl3_new);
531EXPORT_SYMBOL(snd_opl3_init);
532EXPORT_SYMBOL(snd_opl3_create);
533EXPORT_SYMBOL(snd_opl3_timer_new);
534EXPORT_SYMBOL(snd_opl3_hwdep_new); 539EXPORT_SYMBOL(snd_opl3_hwdep_new);
535 540
536/* opl3_synth.c */
537EXPORT_SYMBOL(snd_opl3_regmap);
538EXPORT_SYMBOL(snd_opl3_reset);
539
540/* 541/*
541 * INIT part 542 * INIT part
542 */ 543 */
diff --git a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c
index fccf019a6d85..5fd3a4c95626 100644
--- a/sound/drivers/opl3/opl3_oss.c
+++ b/sound/drivers/opl3/opl3_oss.c
@@ -100,7 +100,8 @@ static int snd_opl3_oss_create_port(struct snd_opl3 * opl3)
100 SNDRV_SEQ_PORT_CAP_WRITE, 100 SNDRV_SEQ_PORT_CAP_WRITE,
101 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | 101 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
102 SNDRV_SEQ_PORT_TYPE_MIDI_GM | 102 SNDRV_SEQ_PORT_TYPE_MIDI_GM |
103 SNDRV_SEQ_PORT_TYPE_SYNTH, 103 SNDRV_SEQ_PORT_TYPE_HARDWARE |
104 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
104 voices, voices, 105 voices, voices,
105 name); 106 name);
106 if (opl3->oss_chset->port < 0) { 107 if (opl3->oss_chset->port < 0) {
diff --git a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c
index 57becf34f43e..96762c9d4855 100644
--- a/sound/drivers/opl3/opl3_seq.c
+++ b/sound/drivers/opl3/opl3_seq.c
@@ -203,7 +203,9 @@ static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
203 SNDRV_SEQ_PORT_CAP_SUBS_WRITE, 203 SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
204 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | 204 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
205 SNDRV_SEQ_PORT_TYPE_MIDI_GM | 205 SNDRV_SEQ_PORT_TYPE_MIDI_GM |
206 SNDRV_SEQ_PORT_TYPE_SYNTH, 206 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
207 SNDRV_SEQ_PORT_TYPE_HARDWARE |
208 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
207 16, voices, 209 16, voices,
208 name); 210 name);
209 if (opl3->chset->port < 0) { 211 if (opl3->chset->port < 0) {
diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c
index 6db503f025b3..a4b3543a7118 100644
--- a/sound/drivers/opl3/opl3_synth.c
+++ b/sound/drivers/opl3/opl3_synth.c
@@ -58,6 +58,8 @@ char snd_opl3_regmap[MAX_OPL2_VOICES][4] =
58 { 0x12, 0x15, 0x00, 0x00 } /* is selected (only left reg block) */ 58 { 0x12, 0x15, 0x00, 0x00 } /* is selected (only left reg block) */
59}; 59};
60 60
61EXPORT_SYMBOL(snd_opl3_regmap);
62
61/* 63/*
62 * prototypes 64 * prototypes
63 */ 65 */
@@ -228,6 +230,7 @@ void snd_opl3_reset(struct snd_opl3 * opl3)
228 opl3->rhythm = 0; 230 opl3->rhythm = 0;
229} 231}
230 232
233EXPORT_SYMBOL(snd_opl3_reset);
231 234
232static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note) 235static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note)
233{ 236{
@@ -445,3 +448,4 @@ static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection)
445 448
446 return 0; 449 return 0;
447} 450}
451
diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c
index 4bc860ae02de..01997f24c895 100644
--- a/sound/drivers/opl4/opl4_lib.c
+++ b/sound/drivers/opl4/opl4_lib.c
@@ -43,6 +43,8 @@ void snd_opl4_write(struct snd_opl4 *opl4, u8 reg, u8 value)
43 outb(value, opl4->pcm_port + 1); 43 outb(value, opl4->pcm_port + 1);
44} 44}
45 45
46EXPORT_SYMBOL(snd_opl4_write);
47
46u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg) 48u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg)
47{ 49{
48 snd_opl4_wait(opl4); 50 snd_opl4_wait(opl4);
@@ -52,6 +54,8 @@ u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg)
52 return inb(opl4->pcm_port + 1); 54 return inb(opl4->pcm_port + 1);
53} 55}
54 56
57EXPORT_SYMBOL(snd_opl4_read);
58
55void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size) 59void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size)
56{ 60{
57 unsigned long flags; 61 unsigned long flags;
@@ -76,6 +80,8 @@ void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size
76 spin_unlock_irqrestore(&opl4->reg_lock, flags); 80 spin_unlock_irqrestore(&opl4->reg_lock, flags);
77} 81}
78 82
83EXPORT_SYMBOL(snd_opl4_read_memory);
84
79void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size) 85void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size)
80{ 86{
81 unsigned long flags; 87 unsigned long flags;
@@ -100,6 +106,8 @@ void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, i
100 spin_unlock_irqrestore(&opl4->reg_lock, flags); 106 spin_unlock_irqrestore(&opl4->reg_lock, flags);
101} 107}
102 108
109EXPORT_SYMBOL(snd_opl4_write_memory);
110
103static void snd_opl4_enable_opl4(struct snd_opl4 *opl4) 111static void snd_opl4_enable_opl4(struct snd_opl4 *opl4)
104{ 112{
105 outb(OPL3_REG_MODE, opl4->fm_port + 2); 113 outb(OPL3_REG_MODE, opl4->fm_port + 2);
@@ -256,10 +264,6 @@ int snd_opl4_create(struct snd_card *card,
256 return 0; 264 return 0;
257} 265}
258 266
259EXPORT_SYMBOL(snd_opl4_write);
260EXPORT_SYMBOL(snd_opl4_read);
261EXPORT_SYMBOL(snd_opl4_write_memory);
262EXPORT_SYMBOL(snd_opl4_read_memory);
263EXPORT_SYMBOL(snd_opl4_create); 267EXPORT_SYMBOL(snd_opl4_create);
264 268
265static int __init alsa_opl4_init(void) 269static int __init alsa_opl4_init(void)
diff --git a/sound/drivers/opl4/opl4_seq.c b/sound/drivers/opl4/opl4_seq.c
index dc0dcdc6c313..43d8a2bdd280 100644
--- a/sound/drivers/opl4/opl4_seq.c
+++ b/sound/drivers/opl4/opl4_seq.c
@@ -164,7 +164,9 @@ static int snd_opl4_seq_new_device(struct snd_seq_device *dev)
164 SNDRV_SEQ_PORT_CAP_WRITE | 164 SNDRV_SEQ_PORT_CAP_WRITE |
165 SNDRV_SEQ_PORT_CAP_SUBS_WRITE, 165 SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
166 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | 166 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
167 SNDRV_SEQ_PORT_TYPE_MIDI_GM, 167 SNDRV_SEQ_PORT_TYPE_MIDI_GM |
168 SNDRV_SEQ_PORT_TYPE_HARDWARE |
169 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
168 16, 24, 170 16, 24,
169 "OPL4 Wavetable Port"); 171 "OPL4 Wavetable Port");
170 if (opl4->chset->port < 0) { 172 if (opl4->chset->port < 0) {
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index c01b4c5118b9..2330fec505da 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -998,6 +998,10 @@ static int __init alsa_card_serial_init(void)
998 i, NULL, 0); 998 i, NULL, 0);
999 if (IS_ERR(device)) 999 if (IS_ERR(device))
1000 continue; 1000 continue;
1001 if (!platform_get_drvdata(device)) {
1002 platform_device_unregister(device);
1003 continue;
1004 }
1001 devices[i] = device; 1005 devices[i] = device;
1002 cards++; 1006 cards++;
1003 } 1007 }
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index 26eb2499d442..59171f8200df 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -171,6 +171,10 @@ static int __init alsa_card_virmidi_init(void)
171 i, NULL, 0); 171 i, NULL, 0);
172 if (IS_ERR(device)) 172 if (IS_ERR(device))
173 continue; 173 continue;
174 if (!platform_get_drvdata(device)) {
175 platform_device_unregister(device);
176 continue;
177 }
174 devices[i] = device; 178 devices[i] = device;
175 cards++; 179 cards++;
176 } 180 }
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index fa4a2b5c2d8d..a60168268ddd 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -70,6 +70,8 @@ int snd_vx_check_reg_bit(struct vx_core *chip, int reg, int mask, int bit, int t
70 return -EIO; 70 return -EIO;
71} 71}
72 72
73EXPORT_SYMBOL(snd_vx_check_reg_bit);
74
73/* 75/*
74 * vx_send_irq_dsp - set command irq bit 76 * vx_send_irq_dsp - set command irq bit
75 * @num: the requested IRQ type, IRQ_XXX 77 * @num: the requested IRQ type, IRQ_XXX
@@ -465,6 +467,8 @@ int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot)
465 return 0; 467 return 0;
466} 468}
467 469
470EXPORT_SYMBOL(snd_vx_load_boot_image);
471
468/* 472/*
469 * vx_test_irq_src - query the source of interrupts 473 * vx_test_irq_src - query the source of interrupts
470 * 474 *
@@ -545,6 +549,7 @@ irqreturn_t snd_vx_irq_handler(int irq, void *dev, struct pt_regs *regs)
545 return IRQ_HANDLED; 549 return IRQ_HANDLED;
546} 550}
547 551
552EXPORT_SYMBOL(snd_vx_irq_handler);
548 553
549/* 554/*
550 */ 555 */
@@ -635,7 +640,7 @@ static void vx_proc_init(struct vx_core *chip)
635 struct snd_info_entry *entry; 640 struct snd_info_entry *entry;
636 641
637 if (! snd_card_proc_new(chip->card, "vx-status", &entry)) 642 if (! snd_card_proc_new(chip->card, "vx-status", &entry))
638 snd_info_set_text_ops(entry, chip, 1024, vx_proc_read); 643 snd_info_set_text_ops(entry, chip, vx_proc_read);
639} 644}
640 645
641 646
@@ -657,6 +662,8 @@ int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *boot)
657 return 0; 662 return 0;
658} 663}
659 664
665EXPORT_SYMBOL(snd_vx_dsp_boot);
666
660/** 667/**
661 * snd_vx_dsp_load - load the DSP image 668 * snd_vx_dsp_load - load the DSP image
662 */ 669 */
@@ -705,6 +712,8 @@ int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp)
705 return 0; 712 return 0;
706} 713}
707 714
715EXPORT_SYMBOL(snd_vx_dsp_load);
716
708#ifdef CONFIG_PM 717#ifdef CONFIG_PM
709/* 718/*
710 * suspend 719 * suspend
@@ -721,6 +730,8 @@ int snd_vx_suspend(struct vx_core *chip, pm_message_t state)
721 return 0; 730 return 0;
722} 731}
723 732
733EXPORT_SYMBOL(snd_vx_suspend);
734
724/* 735/*
725 * resume 736 * resume
726 */ 737 */
@@ -747,6 +758,7 @@ int snd_vx_resume(struct vx_core *chip)
747 return 0; 758 return 0;
748} 759}
749 760
761EXPORT_SYMBOL(snd_vx_resume);
750#endif 762#endif
751 763
752/** 764/**
@@ -790,6 +802,8 @@ struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
790 return chip; 802 return chip;
791} 803}
792 804
805EXPORT_SYMBOL(snd_vx_create);
806
793/* 807/*
794 * module entries 808 * module entries
795 */ 809 */
@@ -804,19 +818,3 @@ static void __exit alsa_vx_core_exit(void)
804 818
805module_init(alsa_vx_core_init) 819module_init(alsa_vx_core_init)
806module_exit(alsa_vx_core_exit) 820module_exit(alsa_vx_core_exit)
807
808/*
809 * exports
810 */
811EXPORT_SYMBOL(snd_vx_check_reg_bit);
812EXPORT_SYMBOL(snd_vx_create);
813EXPORT_SYMBOL(snd_vx_setup_firmware);
814EXPORT_SYMBOL(snd_vx_free_firmware);
815EXPORT_SYMBOL(snd_vx_irq_handler);
816EXPORT_SYMBOL(snd_vx_dsp_boot);
817EXPORT_SYMBOL(snd_vx_dsp_load);
818EXPORT_SYMBOL(snd_vx_load_boot_image);
819#ifdef CONFIG_PM
820EXPORT_SYMBOL(snd_vx_suspend);
821EXPORT_SYMBOL(snd_vx_resume);
822#endif
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index d837783fb538..e1920af4501d 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -250,3 +250,6 @@ void snd_vx_free_firmware(struct vx_core *chip)
250} 250}
251 251
252#endif /* SND_VX_FW_LOADER */ 252#endif /* SND_VX_FW_LOADER */
253
254EXPORT_SYMBOL(snd_vx_setup_firmware);
255EXPORT_SYMBOL(snd_vx_free_firmware);
diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c
index edfe76fb0074..b60fb1892828 100644
--- a/sound/i2c/i2c.c
+++ b/sound/i2c/i2c.c
@@ -106,6 +106,8 @@ int snd_i2c_bus_create(struct snd_card *card, const char *name,
106 return 0; 106 return 0;
107} 107}
108 108
109EXPORT_SYMBOL(snd_i2c_bus_create);
110
109int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name, 111int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name,
110 unsigned char addr, struct snd_i2c_device **rdevice) 112 unsigned char addr, struct snd_i2c_device **rdevice)
111{ 113{
@@ -124,6 +126,8 @@ int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name,
124 return 0; 126 return 0;
125} 127}
126 128
129EXPORT_SYMBOL(snd_i2c_device_create);
130
127int snd_i2c_device_free(struct snd_i2c_device *device) 131int snd_i2c_device_free(struct snd_i2c_device *device)
128{ 132{
129 if (device->bus) 133 if (device->bus)
@@ -134,22 +138,29 @@ int snd_i2c_device_free(struct snd_i2c_device *device)
134 return 0; 138 return 0;
135} 139}
136 140
141EXPORT_SYMBOL(snd_i2c_device_free);
142
137int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count) 143int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
138{ 144{
139 return device->bus->ops->sendbytes(device, bytes, count); 145 return device->bus->ops->sendbytes(device, bytes, count);
140} 146}
141 147
148EXPORT_SYMBOL(snd_i2c_sendbytes);
142 149
143int snd_i2c_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count) 150int snd_i2c_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
144{ 151{
145 return device->bus->ops->readbytes(device, bytes, count); 152 return device->bus->ops->readbytes(device, bytes, count);
146} 153}
147 154
155EXPORT_SYMBOL(snd_i2c_readbytes);
156
148int snd_i2c_probeaddr(struct snd_i2c_bus *bus, unsigned short addr) 157int snd_i2c_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
149{ 158{
150 return bus->ops->probeaddr(bus, addr); 159 return bus->ops->probeaddr(bus, addr);
151} 160}
152 161
162EXPORT_SYMBOL(snd_i2c_probeaddr);
163
153/* 164/*
154 * bit-operations 165 * bit-operations
155 */ 166 */
@@ -320,12 +331,6 @@ static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
320 return err; 331 return err;
321} 332}
322 333
323EXPORT_SYMBOL(snd_i2c_bus_create);
324EXPORT_SYMBOL(snd_i2c_device_create);
325EXPORT_SYMBOL(snd_i2c_device_free);
326EXPORT_SYMBOL(snd_i2c_sendbytes);
327EXPORT_SYMBOL(snd_i2c_readbytes);
328EXPORT_SYMBOL(snd_i2c_probeaddr);
329 334
330static int __init alsa_i2c_init(void) 335static int __init alsa_i2c_init(void)
331{ 336{
diff --git a/sound/i2c/l3/uda1341.c b/sound/i2c/l3/uda1341.c
index 746500e06950..b074fdddea55 100644
--- a/sound/i2c/l3/uda1341.c
+++ b/sound/i2c/l3/uda1341.c
@@ -517,9 +517,9 @@ static void __devinit snd_uda1341_proc_init(struct snd_card *card, struct l3_cli
517 struct snd_info_entry *entry; 517 struct snd_info_entry *entry;
518 518
519 if (! snd_card_proc_new(card, "uda1341", &entry)) 519 if (! snd_card_proc_new(card, "uda1341", &entry))
520 snd_info_set_text_ops(entry, clnt, 1024, snd_uda1341_proc_read); 520 snd_info_set_text_ops(entry, clnt, snd_uda1341_proc_read);
521 if (! snd_card_proc_new(card, "uda1341-regs", &entry)) 521 if (! snd_card_proc_new(card, "uda1341-regs", &entry))
522 snd_info_set_text_ops(entry, clnt, 1024, snd_uda1341_proc_regs_read); 522 snd_info_set_text_ops(entry, clnt, snd_uda1341_proc_regs_read);
523} 523}
524 524
525/* }}} */ 525/* }}} */
diff --git a/sound/isa/gus/gus_irq.c b/sound/isa/gus/gus_irq.c
index c19ba2910b72..42db37552efb 100644
--- a/sound/isa/gus/gus_irq.c
+++ b/sound/isa/gus/gus_irq.c
@@ -136,7 +136,7 @@ void snd_gus_irq_profile_init(struct snd_gus_card *gus)
136 struct snd_info_entry *entry; 136 struct snd_info_entry *entry;
137 137
138 if (! snd_card_proc_new(gus->card, "gusirq", &entry)) 138 if (! snd_card_proc_new(gus->card, "gusirq", &entry))
139 snd_info_set_text_ops(entry, gus, 1024, snd_gus_irq_info_read); 139 snd_info_set_text_ops(entry, gus, snd_gus_irq_info_read);
140} 140}
141 141
142#endif 142#endif
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
index 3c0d27aa08b3..f50c276caee8 100644
--- a/sound/isa/gus/gus_mem.c
+++ b/sound/isa/gus/gus_mem.c
@@ -264,10 +264,8 @@ int snd_gf1_mem_init(struct snd_gus_card * gus)
264 if (snd_gf1_mem_xalloc(alloc, &block) == NULL) 264 if (snd_gf1_mem_xalloc(alloc, &block) == NULL)
265 return -ENOMEM; 265 return -ENOMEM;
266#ifdef CONFIG_SND_DEBUG 266#ifdef CONFIG_SND_DEBUG
267 if (! snd_card_proc_new(gus->card, "gusmem", &entry)) { 267 if (! snd_card_proc_new(gus->card, "gusmem", &entry))
268 snd_info_set_text_ops(entry, gus, 1024, snd_gf1_mem_info_read); 268 snd_info_set_text_ops(entry, gus, snd_gf1_mem_info_read);
269 entry->c.text.read_size = 256 * 1024;
270 }
271#endif 269#endif
272 return 0; 270 return 0;
273} 271}
diff --git a/sound/isa/gus/gus_synth.c b/sound/isa/gus/gus_synth.c
index 2767cc187ae3..3e4d4d6edd8b 100644
--- a/sound/isa/gus/gus_synth.c
+++ b/sound/isa/gus/gus_synth.c
@@ -194,7 +194,9 @@ static int snd_gus_synth_create_port(struct snd_gus_card * gus, int idx)
194 &callbacks, 194 &callbacks,
195 SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE, 195 SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
196 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE | 196 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
197 SNDRV_SEQ_PORT_TYPE_SYNTH, 197 SNDRV_SEQ_PORT_TYPE_SYNTH |
198 SNDRV_SEQ_PORT_TYPE_HARDWARE |
199 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
198 16, 0, 200 16, 0,
199 name); 201 name);
200 if (p->chset->port < 0) { 202 if (p->chset->port < 0) {
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 4298d339e786..866300f2acbb 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -70,9 +70,9 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
70static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ 70static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
71static int joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29}; 71static int joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29};
72 /* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */ 72 /* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */
73static int midi[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 73static int midi[SNDRV_CARDS];
74static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; 74static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
75static int effect[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 75static int effect[SNDRV_CARDS];
76 76
77#ifdef SNDRV_STB 77#ifdef SNDRV_STB
78#define PFX "interwave-stb: " 78#define PFX "interwave-stb: "
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 6d889052c32c..647a996791e9 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -59,7 +59,7 @@ static long midi_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;/* 0x330,0x300 */
59static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 0,1,3,5,9,11,12,15 */ 59static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 0,1,3,5,9,11,12,15 */
60static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */ 60static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */
61static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */ 61static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */
62static int opl3sa3_ymode[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* 0,1,2,3 */ /*SL Added*/ 62static int opl3sa3_ymode[SNDRV_CARDS]; /* 0,1,2,3 */ /*SL Added*/
63 63
64module_param_array(index, int, NULL, 0444); 64module_param_array(index, int, NULL, 0444);
65MODULE_PARM_DESC(index, "Index value for OPL3-SA soundcard."); 65MODULE_PARM_DESC(index, "Index value for OPL3-SA soundcard.");
@@ -221,7 +221,7 @@ static void snd_opl3sa2_write(struct snd_opl3sa2 *chip, unsigned char reg, unsig
221 spin_unlock_irqrestore(&chip->reg_lock, flags); 221 spin_unlock_irqrestore(&chip->reg_lock, flags);
222} 222}
223 223
224static int __init snd_opl3sa2_detect(struct snd_opl3sa2 *chip) 224static int __devinit snd_opl3sa2_detect(struct snd_opl3sa2 *chip)
225{ 225{
226 struct snd_card *card; 226 struct snd_card *card;
227 unsigned long port; 227 unsigned long port;
@@ -489,7 +489,7 @@ static void snd_opl3sa2_master_free(struct snd_kcontrol *kcontrol)
489 chip->master_volume = NULL; 489 chip->master_volume = NULL;
490} 490}
491 491
492static int __init snd_opl3sa2_mixer(struct snd_opl3sa2 *chip) 492static int __devinit snd_opl3sa2_mixer(struct snd_opl3sa2 *chip)
493{ 493{
494 struct snd_card *card = chip->card; 494 struct snd_card *card = chip->card;
495 struct snd_ctl_elem_id id1, id2; 495 struct snd_ctl_elem_id id1, id2;
@@ -583,8 +583,8 @@ static int snd_opl3sa2_resume(struct snd_card *card)
583#endif /* CONFIG_PM */ 583#endif /* CONFIG_PM */
584 584
585#ifdef CONFIG_PNP 585#ifdef CONFIG_PNP
586static int __init snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip, 586static int __devinit snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip,
587 struct pnp_dev *pdev) 587 struct pnp_dev *pdev)
588{ 588{
589 struct pnp_resource_table * cfg; 589 struct pnp_resource_table * cfg;
590 int err; 590 int err;
@@ -862,7 +862,7 @@ static struct pnp_card_driver opl3sa2_pnpc_driver = {
862}; 862};
863#endif /* CONFIG_PNP */ 863#endif /* CONFIG_PNP */
864 864
865static int __init snd_opl3sa2_nonpnp_probe(struct platform_device *pdev) 865static int __devinit snd_opl3sa2_nonpnp_probe(struct platform_device *pdev)
866{ 866{
867 struct snd_card *card; 867 struct snd_card *card;
868 int err; 868 int err;
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index e6bfcf74c1c1..283817f2de75 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -967,7 +967,7 @@ static void __init snd_miro_proc_init(struct snd_miro * miro)
967 struct snd_info_entry *entry; 967 struct snd_info_entry *entry;
968 968
969 if (! snd_card_proc_new(miro->card, "miro", &entry)) 969 if (! snd_card_proc_new(miro->card, "miro", &entry))
970 snd_info_set_text_ops(entry, miro, 1024, snd_miro_proc_read); 970 snd_info_set_text_ops(entry, miro, snd_miro_proc_read);
971} 971}
972 972
973/* 973/*
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index c0b8d61b75e7..658179e86142 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -131,7 +131,7 @@ snd_emu8000_dma_chan(struct snd_emu8000 *emu, int ch, int mode)
131 131
132/* 132/*
133 */ 133 */
134static void __init 134static void __devinit
135snd_emu8000_read_wait(struct snd_emu8000 *emu) 135snd_emu8000_read_wait(struct snd_emu8000 *emu)
136{ 136{
137 while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) { 137 while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) {
@@ -143,7 +143,7 @@ snd_emu8000_read_wait(struct snd_emu8000 *emu)
143 143
144/* 144/*
145 */ 145 */
146static void __init 146static void __devinit
147snd_emu8000_write_wait(struct snd_emu8000 *emu) 147snd_emu8000_write_wait(struct snd_emu8000 *emu)
148{ 148{
149 while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) { 149 while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
@@ -156,7 +156,7 @@ snd_emu8000_write_wait(struct snd_emu8000 *emu)
156/* 156/*
157 * detect a card at the given port 157 * detect a card at the given port
158 */ 158 */
159static int __init 159static int __devinit
160snd_emu8000_detect(struct snd_emu8000 *emu) 160snd_emu8000_detect(struct snd_emu8000 *emu)
161{ 161{
162 /* Initialise */ 162 /* Initialise */
@@ -182,7 +182,7 @@ snd_emu8000_detect(struct snd_emu8000 *emu)
182/* 182/*
183 * intiailize audio channels 183 * intiailize audio channels
184 */ 184 */
185static void __init 185static void __devinit
186init_audio(struct snd_emu8000 *emu) 186init_audio(struct snd_emu8000 *emu)
187{ 187{
188 int ch; 188 int ch;
@@ -223,7 +223,7 @@ init_audio(struct snd_emu8000 *emu)
223/* 223/*
224 * initialize DMA address 224 * initialize DMA address
225 */ 225 */
226static void __init 226static void __devinit
227init_dma(struct snd_emu8000 *emu) 227init_dma(struct snd_emu8000 *emu)
228{ 228{
229 EMU8000_SMALR_WRITE(emu, 0); 229 EMU8000_SMALR_WRITE(emu, 0);
@@ -327,7 +327,7 @@ static unsigned short init4[128] /*__devinitdata*/ = {
327 * Taken from the oss driver, not obvious from the doc how this 327 * Taken from the oss driver, not obvious from the doc how this
328 * is meant to work 328 * is meant to work
329 */ 329 */
330static void __init 330static void __devinit
331send_array(struct snd_emu8000 *emu, unsigned short *data, int size) 331send_array(struct snd_emu8000 *emu, unsigned short *data, int size)
332{ 332{
333 int i; 333 int i;
@@ -349,7 +349,7 @@ send_array(struct snd_emu8000 *emu, unsigned short *data, int size)
349 * Send initialization arrays to start up, this just follows the 349 * Send initialization arrays to start up, this just follows the
350 * initialisation sequence in the adip. 350 * initialisation sequence in the adip.
351 */ 351 */
352static void __init 352static void __devinit
353init_arrays(struct snd_emu8000 *emu) 353init_arrays(struct snd_emu8000 *emu)
354{ 354{
355 send_array(emu, init1, ARRAY_SIZE(init1)/4); 355 send_array(emu, init1, ARRAY_SIZE(init1)/4);
@@ -375,7 +375,7 @@ init_arrays(struct snd_emu8000 *emu)
375 * seems that the only way to do this is to use the one channel and keep 375 * seems that the only way to do this is to use the one channel and keep
376 * reallocating between read and write. 376 * reallocating between read and write.
377 */ 377 */
378static void __init 378static void __devinit
379size_dram(struct snd_emu8000 *emu) 379size_dram(struct snd_emu8000 *emu)
380{ 380{
381 int i, size; 381 int i, size;
@@ -500,7 +500,7 @@ snd_emu8000_init_fm(struct snd_emu8000 *emu)
500/* 500/*
501 * The main initialization routine. 501 * The main initialization routine.
502 */ 502 */
503static void __init 503static void __devinit
504snd_emu8000_init_hw(struct snd_emu8000 *emu) 504snd_emu8000_init_hw(struct snd_emu8000 *emu)
505{ 505{
506 int i; 506 int i;
@@ -1019,7 +1019,7 @@ static struct snd_kcontrol_new *mixer_defs[EMU8000_NUM_CONTROLS] = {
1019/* 1019/*
1020 * create and attach mixer elements for WaveTable treble/bass controls 1020 * create and attach mixer elements for WaveTable treble/bass controls
1021 */ 1021 */
1022static int __init 1022static int __devinit
1023snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu) 1023snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
1024{ 1024{
1025 int i, err = 0; 1025 int i, err = 0;
@@ -1069,7 +1069,7 @@ static int snd_emu8000_dev_free(struct snd_device *device)
1069/* 1069/*
1070 * initialize and register emu8000 synth device. 1070 * initialize and register emu8000 synth device.
1071 */ 1071 */
1072int __init 1072int __devinit
1073snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports, 1073snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
1074 struct snd_seq_device **awe_ret) 1074 struct snd_seq_device **awe_ret)
1075{ 1075{
diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c
index 80b1cf84a1ae..1be16c9700f0 100644
--- a/sound/isa/sb/emu8000_patch.c
+++ b/sound/isa/sb/emu8000_patch.c
@@ -23,7 +23,7 @@
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
25 25
26static int emu8000_reset_addr = 0; 26static int emu8000_reset_addr;
27module_param(emu8000_reset_addr, int, 0444); 27module_param(emu8000_reset_addr, int, 0444);
28MODULE_PARM_DESC(emu8000_reset_addr, "reset write address at each time (makes slowdown)"); 28MODULE_PARM_DESC(emu8000_reset_addr, "reset write address at each time (makes slowdown)");
29 29
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 6333f900eaee..7f7f05fa518a 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -85,7 +85,7 @@ static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */
85static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 5,6,7 */ 85static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 5,6,7 */
86static int mic_agc[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; 86static int mic_agc[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
87#ifdef CONFIG_SND_SB16_CSP 87#ifdef CONFIG_SND_SB16_CSP
88static int csp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 88static int csp[SNDRV_CARDS];
89#endif 89#endif
90#ifdef SNDRV_SBAWE_EMU8000 90#ifdef SNDRV_SBAWE_EMU8000
91static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4}; 91static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4};
diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c
index 9703c68e4e08..fcd638090a9e 100644
--- a/sound/isa/sb/sb16_csp.c
+++ b/sound/isa/sb/sb16_csp.c
@@ -1101,7 +1101,7 @@ static int init_proc_entry(struct snd_sb_csp * p, int device)
1101 struct snd_info_entry *entry; 1101 struct snd_info_entry *entry;
1102 sprintf(name, "cspD%d", device); 1102 sprintf(name, "cspD%d", device);
1103 if (! snd_card_proc_new(p->chip->card, name, &entry)) 1103 if (! snd_card_proc_new(p->chip->card, name, &entry))
1104 snd_info_set_text_ops(entry, p, 1024, info_read); 1104 snd_info_set_text_ops(entry, p, info_read);
1105 return 0; 1105 return 0;
1106} 1106}
1107 1107
diff --git a/sound/isa/sb/sb8_midi.c b/sound/isa/sb/sb8_midi.c
index c549aceea294..0b67edd7ac6e 100644
--- a/sound/isa/sb/sb8_midi.c
+++ b/sound/isa/sb/sb8_midi.c
@@ -32,20 +32,22 @@
32#include <sound/core.h> 32#include <sound/core.h>
33#include <sound/sb.h> 33#include <sound/sb.h>
34 34
35/*
36
37 */
38 35
39irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb * chip) 36irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb *chip)
40{ 37{
41 struct snd_rawmidi *rmidi; 38 struct snd_rawmidi *rmidi;
42 int max = 64; 39 int max = 64;
43 char byte; 40 char byte;
44 41
45 if (chip == NULL || (rmidi = chip->rmidi) == NULL) { 42 if (!chip)
43 return IRQ_NONE;
44
45 rmidi = chip->rmidi;
46 if (!rmidi) {
46 inb(SBP(chip, DATA_AVAIL)); /* ack interrupt */ 47 inb(SBP(chip, DATA_AVAIL)); /* ack interrupt */
47 return IRQ_NONE; 48 return IRQ_NONE;
48 } 49 }
50
49 spin_lock(&chip->midi_input_lock); 51 spin_lock(&chip->midi_input_lock);
50 while (max-- > 0) { 52 while (max-- > 0) {
51 if (inb(SBP(chip, DATA_AVAIL)) & 0x80) { 53 if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
@@ -59,10 +61,6 @@ irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb * chip)
59 return IRQ_HANDLED; 61 return IRQ_HANDLED;
60} 62}
61 63
62/*
63
64 */
65
66static int snd_sb8dsp_midi_input_open(struct snd_rawmidi_substream *substream) 64static int snd_sb8dsp_midi_input_open(struct snd_rawmidi_substream *substream)
67{ 65{
68 unsigned long flags; 66 unsigned long flags;
@@ -252,10 +250,6 @@ static void snd_sb8dsp_midi_output_trigger(struct snd_rawmidi_substream *substre
252 snd_sb8dsp_midi_output_write(substream); 250 snd_sb8dsp_midi_output_write(substream);
253} 251}
254 252
255/*
256
257 */
258
259static struct snd_rawmidi_ops snd_sb8dsp_midi_output = 253static struct snd_rawmidi_ops snd_sb8dsp_midi_output =
260{ 254{
261 .open = snd_sb8dsp_midi_output_open, 255 .open = snd_sb8dsp_midi_output_open,
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index d2a856f0fde2..27271c9446dc 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -897,10 +897,9 @@ static int __devinit create_mpu401(struct snd_card *card, int devnum, unsigned l
897 struct snd_rawmidi *rawmidi; 897 struct snd_rawmidi *rawmidi;
898 int err; 898 int err;
899 899
900#define MPU401_SHARE_HARDWARE 1
901 if ((err = snd_mpu401_uart_new(card, devnum, 900 if ((err = snd_mpu401_uart_new(card, devnum,
902 MPU401_HW_MPU401, 901 MPU401_HW_MPU401,
903 port, MPU401_SHARE_HARDWARE, 902 port, MPU401_INFO_INTEGRATED,
904 irq, SA_INTERRUPT, 903 irq, SA_INTERRUPT,
905 &rawmidi)) == 0) { 904 &rawmidi)) == 0) {
906 struct snd_mpu401 *mpu = (struct snd_mpu401 *) rawmidi->private_data; 905 struct snd_mpu401 *mpu = (struct snd_mpu401 *) rawmidi->private_data;
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 7ae86f82c3fa..9eb27082c659 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -50,7 +50,7 @@ static int ics2115_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 2,9,11,12,15 */
50static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ 50static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
51static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ 51static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
52static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ 52static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
53static int use_cs4232_midi[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 53static int use_cs4232_midi[SNDRV_CARDS];
54 54
55module_param_array(index, int, NULL, 0444); 55module_param_array(index, int, NULL, 0444);
56MODULE_PARM_DESC(index, "Index value for WaveFront soundcard."); 56MODULE_PARM_DESC(index, "Index value for WaveFront soundcard.");
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index a2081803a827..d37346b12dc0 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -216,14 +216,19 @@ config SND_CS46XX_NEW_DSP
216 This works better than the old code, so say Y. 216 This works better than the old code, so say Y.
217 217
218config SND_CS5535AUDIO 218config SND_CS5535AUDIO
219 tristate "CS5535 Audio" 219 tristate "CS5535/CS5536 Audio"
220 depends on SND && X86 && !X86_64 220 depends on SND && X86 && !X86_64
221 select SND_PCM 221 select SND_PCM
222 select SND_AC97_CODEC 222 select SND_AC97_CODEC
223 help 223 help
224 Say Y here to include support for audio on CS5535 chips. It is 224 Say Y here to include support for audio on CS5535 chips. It is
225 referred to as NS CS5535 IO or AMD CS5535 IO companion in 225 referred to as NS CS5535 IO or AMD CS5535 IO companion in
226 various literature. 226 various literature. This driver also supports the CS5536 audio
227 device. However, for both chips, on certain boards, you may
228 need to use ac97_quirk=hp_only if your board has physically
229 mapped headphone out to master output. If that works for you,
230 send lspci -vvv output to the mailing list so that your board
231 can be identified in the quirks list.
227 232
228 To compile this driver as a module, choose M here: the module 233 To compile this driver as a module, choose M here: the module
229 will be called snd-cs5535audio. 234 will be called snd-cs5535audio.
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index d05200741ac3..0abf2808d59f 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -253,6 +253,8 @@ void snd_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short va
253 ac97->bus->ops->write(ac97, reg, value); 253 ac97->bus->ops->write(ac97, reg, value);
254} 254}
255 255
256EXPORT_SYMBOL(snd_ac97_write);
257
256/** 258/**
257 * snd_ac97_read - read a value from the given register 259 * snd_ac97_read - read a value from the given register
258 * 260 *
@@ -281,6 +283,8 @@ static inline unsigned short snd_ac97_read_cache(struct snd_ac97 *ac97, unsigned
281 return ac97->regs[reg]; 283 return ac97->regs[reg];
282} 284}
283 285
286EXPORT_SYMBOL(snd_ac97_read);
287
284/** 288/**
285 * snd_ac97_write_cache - write a value on the given register and update the cache 289 * snd_ac97_write_cache - write a value on the given register and update the cache
286 * @ac97: the ac97 instance 290 * @ac97: the ac97 instance
@@ -302,6 +306,8 @@ void snd_ac97_write_cache(struct snd_ac97 *ac97, unsigned short reg, unsigned sh
302 mutex_unlock(&ac97->reg_mutex); 306 mutex_unlock(&ac97->reg_mutex);
303} 307}
304 308
309EXPORT_SYMBOL(snd_ac97_write_cache);
310
305/** 311/**
306 * snd_ac97_update - update the value on the given register 312 * snd_ac97_update - update the value on the given register
307 * @ac97: the ac97 instance 313 * @ac97: the ac97 instance
@@ -331,6 +337,8 @@ int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short va
331 return change; 337 return change;
332} 338}
333 339
340EXPORT_SYMBOL(snd_ac97_update);
341
334/** 342/**
335 * snd_ac97_update_bits - update the bits on the given register 343 * snd_ac97_update_bits - update the bits on the given register
336 * @ac97: the ac97 instance 344 * @ac97: the ac97 instance
@@ -356,6 +364,8 @@ int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned sho
356 return change; 364 return change;
357} 365}
358 366
367EXPORT_SYMBOL(snd_ac97_update_bits);
368
359/* no lock version - see snd_ac97_updat_bits() */ 369/* no lock version - see snd_ac97_updat_bits() */
360int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg, 370int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg,
361 unsigned short mask, unsigned short value) 371 unsigned short mask, unsigned short value)
@@ -563,7 +573,7 @@ AC97_SINGLE("PC Speaker Playback Volume", AC97_PC_BEEP, 1, 15, 1)
563}; 573};
564 574
565static const struct snd_kcontrol_new snd_ac97_controls_mic_boost = 575static const struct snd_kcontrol_new snd_ac97_controls_mic_boost =
566 AC97_SINGLE("Mic Boost (+20dB)", AC97_MIC, 6, 1, 0); 576 AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_MIC, 6, 1, 0);
567 577
568 578
569static const char* std_rec_sel[] = {"Mic", "CD", "Video", "Aux", "Line", "Mix", "Mix Mono", "Phone"}; 579static const char* std_rec_sel[] = {"Mic", "CD", "Video", "Aux", "Line", "Mix", "Mix Mono", "Phone"};
@@ -605,7 +615,7 @@ AC97_SINGLE("Simulated Stereo Enhancement", AC97_GENERAL_PURPOSE, 14, 1, 0),
605AC97_SINGLE("3D Control - Switch", AC97_GENERAL_PURPOSE, 13, 1, 0), 615AC97_SINGLE("3D Control - Switch", AC97_GENERAL_PURPOSE, 13, 1, 0),
606AC97_SINGLE("Loudness (bass boost)", AC97_GENERAL_PURPOSE, 12, 1, 0), 616AC97_SINGLE("Loudness (bass boost)", AC97_GENERAL_PURPOSE, 12, 1, 0),
607AC97_ENUM("Mono Output Select", std_enum[2]), 617AC97_ENUM("Mono Output Select", std_enum[2]),
608AC97_ENUM("Mic Select", std_enum[3]), 618AC97_ENUM("Mic Select Capture Switch", std_enum[3]),
609AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0) 619AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0)
610}; 620};
611 621
@@ -1226,7 +1236,8 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1226 ac97->regs[AC97_CENTER_LFE_MASTER] = 0x8080; 1236 ac97->regs[AC97_CENTER_LFE_MASTER] = 0x8080;
1227 1237
1228 /* build center controls */ 1238 /* build center controls */
1229 if (snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER)) { 1239 if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER))
1240 && !(ac97->flags & AC97_AD_MULTI)) {
1230 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_center[0], ac97))) < 0) 1241 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_center[0], ac97))) < 0)
1231 return err; 1242 return err;
1232 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_center[1], ac97))) < 0) 1243 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_center[1], ac97))) < 0)
@@ -1238,7 +1249,8 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1238 } 1249 }
1239 1250
1240 /* build LFE controls */ 1251 /* build LFE controls */
1241 if (snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER+1)) { 1252 if ((snd_ac97_try_volume_mix(ac97, AC97_CENTER_LFE_MASTER+1))
1253 && !(ac97->flags & AC97_AD_MULTI)) {
1242 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_lfe[0], ac97))) < 0) 1254 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_lfe[0], ac97))) < 0)
1243 return err; 1255 return err;
1244 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_lfe[1], ac97))) < 0) 1256 if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_lfe[1], ac97))) < 0)
@@ -1250,7 +1262,8 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1250 } 1262 }
1251 1263
1252 /* build surround controls */ 1264 /* build surround controls */
1253 if (snd_ac97_try_volume_mix(ac97, AC97_SURROUND_MASTER)) { 1265 if ((snd_ac97_try_volume_mix(ac97, AC97_SURROUND_MASTER))
1266 && !(ac97->flags & AC97_AD_MULTI)) {
1254 /* Surround Master (0x38) is with stereo mutes */ 1267 /* Surround Master (0x38) is with stereo mutes */
1255 if ((err = snd_ac97_cmix_new_stereo(card, "Surround Playback", AC97_SURROUND_MASTER, 1, ac97)) < 0) 1268 if ((err = snd_ac97_cmix_new_stereo(card, "Surround Playback", AC97_SURROUND_MASTER, 1, ac97)) < 0)
1256 return err; 1269 return err;
@@ -1335,9 +1348,11 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
1335 } 1348 }
1336 1349
1337 /* build Aux controls */ 1350 /* build Aux controls */
1338 if (snd_ac97_try_volume_mix(ac97, AC97_AUX)) { 1351 if (!(ac97->flags & AC97_HAS_NO_AUX)) {
1339 if ((err = snd_ac97_cmix_new(card, "Aux Playback", AC97_AUX, ac97)) < 0) 1352 if (snd_ac97_try_volume_mix(ac97, AC97_AUX)) {
1340 return err; 1353 if ((err = snd_ac97_cmix_new(card, "Aux Playback", AC97_AUX, ac97)) < 0)
1354 return err;
1355 }
1341 } 1356 }
1342 1357
1343 /* build PCM controls */ 1358 /* build PCM controls */
@@ -1682,6 +1697,7 @@ const char *snd_ac97_get_short_name(struct snd_ac97 *ac97)
1682 return "unknown codec"; 1697 return "unknown codec";
1683} 1698}
1684 1699
1700EXPORT_SYMBOL(snd_ac97_get_short_name);
1685 1701
1686/* wait for a while until registers are accessible after RESET 1702/* wait for a while until registers are accessible after RESET
1687 * return 0 if ok, negative not ready 1703 * return 0 if ok, negative not ready
@@ -1774,6 +1790,8 @@ int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops,
1774 return 0; 1790 return 0;
1775} 1791}
1776 1792
1793EXPORT_SYMBOL(snd_ac97_bus);
1794
1777/* stop no dev release warning */ 1795/* stop no dev release warning */
1778static void ac97_device_release(struct device * dev) 1796static void ac97_device_release(struct device * dev)
1779{ 1797{
@@ -2117,6 +2135,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
2117 return 0; 2135 return 0;
2118} 2136}
2119 2137
2138EXPORT_SYMBOL(snd_ac97_mixer);
2120 2139
2121/* 2140/*
2122 * Power down the chip. 2141 * Power down the chip.
@@ -2166,6 +2185,8 @@ void snd_ac97_suspend(struct snd_ac97 *ac97)
2166 snd_ac97_powerdown(ac97); 2185 snd_ac97_powerdown(ac97);
2167} 2186}
2168 2187
2188EXPORT_SYMBOL(snd_ac97_suspend);
2189
2169/* 2190/*
2170 * restore ac97 status 2191 * restore ac97 status
2171 */ 2192 */
@@ -2267,6 +2288,8 @@ __reset_ready:
2267 snd_ac97_restore_iec958(ac97); 2288 snd_ac97_restore_iec958(ac97);
2268 } 2289 }
2269} 2290}
2291
2292EXPORT_SYMBOL(snd_ac97_resume);
2270#endif 2293#endif
2271 2294
2272 2295
@@ -2590,29 +2613,7 @@ int snd_ac97_tune_hardware(struct snd_ac97 *ac97, struct ac97_quirk *quirk, cons
2590 return 0; 2613 return 0;
2591} 2614}
2592 2615
2593
2594/*
2595 * Exported symbols
2596 */
2597
2598EXPORT_SYMBOL(snd_ac97_write);
2599EXPORT_SYMBOL(snd_ac97_read);
2600EXPORT_SYMBOL(snd_ac97_write_cache);
2601EXPORT_SYMBOL(snd_ac97_update);
2602EXPORT_SYMBOL(snd_ac97_update_bits);
2603EXPORT_SYMBOL(snd_ac97_get_short_name);
2604EXPORT_SYMBOL(snd_ac97_bus);
2605EXPORT_SYMBOL(snd_ac97_mixer);
2606EXPORT_SYMBOL(snd_ac97_pcm_assign);
2607EXPORT_SYMBOL(snd_ac97_pcm_open);
2608EXPORT_SYMBOL(snd_ac97_pcm_close);
2609EXPORT_SYMBOL(snd_ac97_pcm_double_rate_rules);
2610EXPORT_SYMBOL(snd_ac97_tune_hardware); 2616EXPORT_SYMBOL(snd_ac97_tune_hardware);
2611EXPORT_SYMBOL(snd_ac97_set_rate);
2612#ifdef CONFIG_PM
2613EXPORT_SYMBOL(snd_ac97_resume);
2614EXPORT_SYMBOL(snd_ac97_suspend);
2615#endif
2616 2617
2617/* 2618/*
2618 * INIT part 2619 * INIT part
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 4d9cf37300f7..7f197c780816 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -464,6 +464,10 @@ int patch_wolfson05(struct snd_ac97 * ac97)
464{ 464{
465 /* WM9705, WM9710 */ 465 /* WM9705, WM9710 */
466 ac97->build_ops = &patch_wolfson_wm9705_ops; 466 ac97->build_ops = &patch_wolfson_wm9705_ops;
467#ifdef CONFIG_TOUCHSCREEN_WM9705
468 /* WM9705 touchscreen uses AUX and VIDEO for touch */
469 ac97->flags |=3D AC97_HAS_NO_VIDEO | AC97_HAS_NO_AUX;
470#endif
467 return 0; 471 return 0;
468} 472}
469 473
@@ -1367,6 +1371,13 @@ static void ad18xx_resume(struct snd_ac97 *ac97)
1367 1371
1368 snd_ac97_restore_iec958(ac97); 1372 snd_ac97_restore_iec958(ac97);
1369} 1373}
1374
1375static void ad1888_resume(struct snd_ac97 *ac97)
1376{
1377 ad18xx_resume(ac97);
1378 snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x8080);
1379}
1380
1370#endif 1381#endif
1371 1382
1372int patch_ad1819(struct snd_ac97 * ac97) 1383int patch_ad1819(struct snd_ac97 * ac97)
@@ -1627,6 +1638,7 @@ static const struct snd_kcontrol_new snd_ac97_ad1981x_jack_sense[] = {
1627 * (SS vendor << 16 | device) 1638 * (SS vendor << 16 | device)
1628 */ 1639 */
1629static unsigned int ad1981_jacks_blacklist[] = { 1640static unsigned int ad1981_jacks_blacklist[] = {
1641 0x10140537, /* Thinkpad T41p */
1630 0x10140554, /* Thinkpad T42p/R50p */ 1642 0x10140554, /* Thinkpad T42p/R50p */
1631 0 /* end */ 1643 0 /* end */
1632}; 1644};
@@ -1839,7 +1851,7 @@ static struct snd_ac97_build_ops patch_ad1888_build_ops = {
1839 .build_post_spdif = patch_ad198x_post_spdif, 1851 .build_post_spdif = patch_ad198x_post_spdif,
1840 .build_specific = patch_ad1888_specific, 1852 .build_specific = patch_ad1888_specific,
1841#ifdef CONFIG_PM 1853#ifdef CONFIG_PM
1842 .resume = ad18xx_resume, 1854 .resume = ad1888_resume,
1843#endif 1855#endif
1844 .update_jacks = ad1888_update_jacks, 1856 .update_jacks = ad1888_update_jacks,
1845}; 1857};
@@ -2048,7 +2060,10 @@ int patch_alc650(struct snd_ac97 * ac97)
2048 /* Enable SPDIF-IN only on Rev.E and above */ 2060 /* Enable SPDIF-IN only on Rev.E and above */
2049 val = snd_ac97_read(ac97, AC97_ALC650_CLOCK); 2061 val = snd_ac97_read(ac97, AC97_ALC650_CLOCK);
2050 /* SPDIF IN with pin 47 */ 2062 /* SPDIF IN with pin 47 */
2051 if (ac97->spec.dev_flags) 2063 if (ac97->spec.dev_flags &&
2064 /* ASUS A6KM requires EAPD */
2065 ! (ac97->subsystem_vendor == 0x1043 &&
2066 ac97->subsystem_device == 0x1103))
2052 val |= 0x03; /* enable */ 2067 val |= 0x03; /* enable */
2053 else 2068 else
2054 val &= ~0x03; /* disable */ 2069 val &= ~0x03; /* disable */
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c
index 512a3583b0ce..f684aa2c0067 100644
--- a/sound/pci/ac97/ac97_pcm.c
+++ b/sound/pci/ac97/ac97_pcm.c
@@ -317,6 +317,8 @@ int snd_ac97_set_rate(struct snd_ac97 *ac97, int reg, unsigned int rate)
317 return 0; 317 return 0;
318} 318}
319 319
320EXPORT_SYMBOL(snd_ac97_set_rate);
321
320static unsigned short get_pslots(struct snd_ac97 *ac97, unsigned char *rate_table, unsigned short *spdif_slots) 322static unsigned short get_pslots(struct snd_ac97 *ac97, unsigned char *rate_table, unsigned short *spdif_slots)
321{ 323{
322 if (!ac97_is_audio(ac97)) 324 if (!ac97_is_audio(ac97))
@@ -550,6 +552,8 @@ int snd_ac97_pcm_assign(struct snd_ac97_bus *bus,
550 return 0; 552 return 0;
551} 553}
552 554
555EXPORT_SYMBOL(snd_ac97_pcm_assign);
556
553/** 557/**
554 * snd_ac97_pcm_open - opens the given AC97 pcm 558 * snd_ac97_pcm_open - opens the given AC97 pcm
555 * @pcm: the ac97 pcm instance 559 * @pcm: the ac97 pcm instance
@@ -633,6 +637,8 @@ int snd_ac97_pcm_open(struct ac97_pcm *pcm, unsigned int rate,
633 return err; 637 return err;
634} 638}
635 639
640EXPORT_SYMBOL(snd_ac97_pcm_open);
641
636/** 642/**
637 * snd_ac97_pcm_close - closes the given AC97 pcm 643 * snd_ac97_pcm_close - closes the given AC97 pcm
638 * @pcm: the ac97 pcm instance 644 * @pcm: the ac97 pcm instance
@@ -658,6 +664,8 @@ int snd_ac97_pcm_close(struct ac97_pcm *pcm)
658 return 0; 664 return 0;
659} 665}
660 666
667EXPORT_SYMBOL(snd_ac97_pcm_close);
668
661static int double_rate_hw_constraint_rate(struct snd_pcm_hw_params *params, 669static int double_rate_hw_constraint_rate(struct snd_pcm_hw_params *params,
662 struct snd_pcm_hw_rule *rule) 670 struct snd_pcm_hw_rule *rule)
663{ 671{
@@ -709,3 +717,5 @@ int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime)
709 SNDRV_PCM_HW_PARAM_RATE, -1); 717 SNDRV_PCM_HW_PARAM_RATE, -1);
710 return err; 718 return err;
711} 719}
720
721EXPORT_SYMBOL(snd_ac97_pcm_double_rate_rules);
diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c
index 4d523df79cc7..2118df50b9d6 100644
--- a/sound/pci/ac97/ac97_proc.c
+++ b/sound/pci/ac97/ac97_proc.c
@@ -433,7 +433,7 @@ void snd_ac97_proc_init(struct snd_ac97 * ac97)
433 prefix = ac97_is_audio(ac97) ? "ac97" : "mc97"; 433 prefix = ac97_is_audio(ac97) ? "ac97" : "mc97";
434 sprintf(name, "%s#%d-%d", prefix, ac97->addr, ac97->num); 434 sprintf(name, "%s#%d-%d", prefix, ac97->addr, ac97->num);
435 if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) { 435 if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) {
436 snd_info_set_text_ops(entry, ac97, 1024, snd_ac97_proc_read); 436 snd_info_set_text_ops(entry, ac97, snd_ac97_proc_read);
437 if (snd_info_register(entry) < 0) { 437 if (snd_info_register(entry) < 0) {
438 snd_info_free_entry(entry); 438 snd_info_free_entry(entry);
439 entry = NULL; 439 entry = NULL;
@@ -442,10 +442,9 @@ void snd_ac97_proc_init(struct snd_ac97 * ac97)
442 ac97->proc = entry; 442 ac97->proc = entry;
443 sprintf(name, "%s#%d-%d+regs", prefix, ac97->addr, ac97->num); 443 sprintf(name, "%s#%d-%d+regs", prefix, ac97->addr, ac97->num);
444 if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) { 444 if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) {
445 snd_info_set_text_ops(entry, ac97, 1024, snd_ac97_proc_regs_read); 445 snd_info_set_text_ops(entry, ac97, snd_ac97_proc_regs_read);
446#ifdef CONFIG_SND_DEBUG 446#ifdef CONFIG_SND_DEBUG
447 entry->mode |= S_IWUSR; 447 entry->mode |= S_IWUSR;
448 entry->c.text.write_size = 1024;
449 entry->c.text.write = snd_ac97_proc_regs_write; 448 entry->c.text.write = snd_ac97_proc_regs_write;
450#endif 449#endif
451 if (snd_info_register(entry) < 0) { 450 if (snd_info_register(entry) < 0) {
diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c
index 0fb7b3407312..94c26ec05882 100644
--- a/sound/pci/ac97/ak4531_codec.c
+++ b/sound/pci/ac97/ak4531_codec.c
@@ -453,7 +453,7 @@ static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak453
453 struct snd_info_entry *entry; 453 struct snd_info_entry *entry;
454 454
455 if (! snd_card_proc_new(card, "ak4531", &entry)) 455 if (! snd_card_proc_new(card, "ak4531", &entry))
456 snd_info_set_text_ops(entry, ak4531, 1024, snd_ak4531_proc_read); 456 snd_info_set_text_ops(entry, ak4531, snd_ak4531_proc_read);
457} 457}
458#endif 458#endif
459 459
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index eece1c7e55a0..d42bf4570367 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -753,7 +753,7 @@ snd_ad1889_proc_init(struct snd_ad1889 *chip)
753 struct snd_info_entry *entry; 753 struct snd_info_entry *entry;
754 754
755 if (!snd_card_proc_new(chip->card, chip->card->driver, &entry)) 755 if (!snd_card_proc_new(chip->card, chip->card->driver, &entry))
756 snd_info_set_text_ops(entry, chip, 1024, snd_ad1889_proc_read); 756 snd_info_set_text_ops(entry, chip, snd_ad1889_proc_read);
757} 757}
758 758
759static struct ac97_quirk ac97_quirks[] = { 759static struct ac97_quirk ac97_quirks[] = {
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index e2dbc2118902..5dfdbf6657f2 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -49,7 +49,7 @@ MODULE_SUPPORTED_DEVICE("{{ALI,M5451,pci},{ALI,M5451}}");
49static int index = SNDRV_DEFAULT_IDX1; /* Index */ 49static int index = SNDRV_DEFAULT_IDX1; /* Index */
50static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ 50static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
51static int pcm_channels = 32; 51static int pcm_channels = 32;
52static int spdif = 0; 52static int spdif;
53 53
54module_param(index, int, 0444); 54module_param(index, int, 0444);
55MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio."); 55MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio.");
@@ -2173,7 +2173,7 @@ static void __devinit snd_ali_proc_init(struct snd_ali *codec)
2173{ 2173{
2174 struct snd_info_entry *entry; 2174 struct snd_info_entry *entry;
2175 if(!snd_card_proc_new(codec->card, "ali5451", &entry)) 2175 if(!snd_card_proc_new(codec->card, "ali5451", &entry))
2176 snd_info_set_text_ops(entry, codec, 1024, snd_ali_proc_read); 2176 snd_info_set_text_ops(entry, codec, snd_ali_proc_read);
2177} 2177}
2178 2178
2179static int __devinit snd_ali_resources(struct snd_ali *codec) 2179static int __devinit snd_ali_resources(struct snd_ali *codec)
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 60423b1c678b..a9f08066459a 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -746,8 +746,8 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
746 card->shortname, chip->alt_port, chip->irq); 746 card->shortname, chip->alt_port, chip->irq);
747 747
748 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000, 748 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000,
749 gcr+0x30, 1, pci->irq, 0, 749 gcr+0x30, MPU401_INFO_INTEGRATED,
750 &chip->rmidi)) < 0) { 750 pci->irq, 0, &chip->rmidi)) < 0) {
751 printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", gcr+0x30); 751 printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", gcr+0x30);
752 goto out_err; 752 goto out_err;
753 } 753 }
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index d0f759d86d3d..f18a8c0e4688 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1504,7 +1504,7 @@ static void __devinit snd_atiixp_proc_init(struct atiixp *chip)
1504 struct snd_info_entry *entry; 1504 struct snd_info_entry *entry;
1505 1505
1506 if (! snd_card_proc_new(chip->card, "atiixp", &entry)) 1506 if (! snd_card_proc_new(chip->card, "atiixp", &entry))
1507 snd_info_set_text_ops(entry, chip, 1024, snd_atiixp_proc_read); 1507 snd_info_set_text_ops(entry, chip, snd_atiixp_proc_read);
1508} 1508}
1509#else /* !CONFIG_PROC_FS */ 1509#else /* !CONFIG_PROC_FS */
1510#define snd_atiixp_proc_init(chip) 1510#define snd_atiixp_proc_init(chip)
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 12a34c39caa7..40739057076b 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1177,7 +1177,7 @@ static void __devinit snd_atiixp_proc_init(struct atiixp_modem *chip)
1177 struct snd_info_entry *entry; 1177 struct snd_info_entry *entry;
1178 1178
1179 if (! snd_card_proc_new(chip->card, "atiixp-modem", &entry)) 1179 if (! snd_card_proc_new(chip->card, "atiixp-modem", &entry))
1180 snd_info_set_text_ops(entry, chip, 1024, snd_atiixp_proc_read); 1180 snd_info_set_text_ops(entry, chip, snd_atiixp_proc_read);
1181} 1181}
1182#else 1182#else
1183#define snd_atiixp_proc_init(chip) 1183#define snd_atiixp_proc_init(chip)
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 126870ec063a..8a3b118989bf 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -261,6 +261,13 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
261 return err; 261 return err;
262 } 262 }
263 snd_vortex_workaround(pci, pcifix[dev]); 263 snd_vortex_workaround(pci, pcifix[dev]);
264
265 // Card details needed in snd_vortex_midi
266 strcpy(card->driver, CARD_NAME_SHORT);
267 sprintf(card->shortname, "Aureal Vortex %s", CARD_NAME_SHORT);
268 sprintf(card->longname, "%s at 0x%lx irq %i",
269 card->shortname, chip->io, chip->irq);
270
264 // (4) Alloc components. 271 // (4) Alloc components.
265 // ADB pcm. 272 // ADB pcm.
266 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_ADB)) < 0) { 273 if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_ADB)) < 0) {
@@ -323,11 +330,6 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
323#endif 330#endif
324 331
325 // (5) 332 // (5)
326 strcpy(card->driver, CARD_NAME_SHORT);
327 strcpy(card->shortname, CARD_NAME_SHORT);
328 sprintf(card->longname, "%s at 0x%lx irq %i",
329 card->shortname, chip->io, chip->irq);
330
331 if ((err = pci_read_config_word(pci, PCI_DEVICE_ID, 333 if ((err = pci_read_config_word(pci, PCI_DEVICE_ID,
332 &(chip->device))) < 0) { 334 &(chip->device))) < 0) {
333 snd_card_free(card); 335 snd_card_free(card);
diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c
index 873f486b07b8..c75d368ea087 100644
--- a/sound/pci/au88x0/au88x0_mpu401.c
+++ b/sound/pci/au88x0/au88x0_mpu401.c
@@ -47,7 +47,7 @@ static int __devinit snd_vortex_midi(vortex_t * vortex)
47 struct snd_rawmidi *rmidi; 47 struct snd_rawmidi *rmidi;
48 int temp, mode; 48 int temp, mode;
49 struct snd_mpu401 *mpu; 49 struct snd_mpu401 *mpu;
50 int port; 50 unsigned long port;
51 51
52#ifdef VORTEX_MPU401_LEGACY 52#ifdef VORTEX_MPU401_LEGACY
53 /* EnableHardCodedMPU401Port() */ 53 /* EnableHardCodedMPU401Port() */
@@ -70,9 +70,6 @@ static int __devinit snd_vortex_midi(vortex_t * vortex)
70 temp |= (MIDI_CLOCK_DIV << 8) | ((mode >> 24) & 0xff) << 4; 70 temp |= (MIDI_CLOCK_DIV << 8) | ((mode >> 24) & 0xff) << 4;
71 hwwrite(vortex->mmio, VORTEX_CTRL2, temp); 71 hwwrite(vortex->mmio, VORTEX_CTRL2, temp);
72 hwwrite(vortex->mmio, VORTEX_MIDI_CMD, MPU401_RESET); 72 hwwrite(vortex->mmio, VORTEX_MIDI_CMD, MPU401_RESET);
73 /* Set some kind of mode */
74 if (mode)
75 hwwrite(vortex->mmio, VORTEX_MIDI_CMD, MPU401_ENTER_UART);
76 73
77 /* Check if anything is OK. */ 74 /* Check if anything is OK. */
78 temp = hwread(vortex->mmio, VORTEX_MIDI_DATA); 75 temp = hwread(vortex->mmio, VORTEX_MIDI_DATA);
@@ -98,7 +95,8 @@ static int __devinit snd_vortex_midi(vortex_t * vortex)
98 port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA); 95 port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA);
99 if ((temp = 96 if ((temp =
100 snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port, 97 snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port,
101 1, 0, 0, &rmidi)) != 0) { 98 MPU401_INFO_INTEGRATED | MPU401_INFO_MMIO,
99 0, 0, &rmidi)) != 0) {
102 hwwrite(vortex->mmio, VORTEX_CTRL, 100 hwwrite(vortex->mmio, VORTEX_CTRL,
103 (hwread(vortex->mmio, VORTEX_CTRL) & 101 (hwread(vortex->mmio, VORTEX_CTRL) &
104 ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN); 102 ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN);
@@ -107,6 +105,9 @@ static int __devinit snd_vortex_midi(vortex_t * vortex)
107 mpu = rmidi->private_data; 105 mpu = rmidi->private_data;
108 mpu->cport = (unsigned long)(vortex->mmio + VORTEX_MIDI_CMD); 106 mpu->cport = (unsigned long)(vortex->mmio + VORTEX_MIDI_CMD);
109#endif 107#endif
108 /* Overwrite MIDI name */
109 snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI %d", CARD_NAME_SHORT , vortex->card->number);
110
110 vortex->rmidi = rmidi; 111 vortex->rmidi = rmidi;
111 return 0; 112 return 0;
112} 113}
diff --git a/sound/pci/au88x0/au88x0_xtalk.c b/sound/pci/au88x0/au88x0_xtalk.c
index 4534e1882ada..b4151e208b71 100644
--- a/sound/pci/au88x0/au88x0_xtalk.c
+++ b/sound/pci/au88x0/au88x0_xtalk.c
@@ -66,31 +66,20 @@ static xtalk_gains_t const asXtalkGainsAllChan = {
66 0 66 0
67 //0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff 67 //0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff
68}; 68};
69static xtalk_gains_t const asXtalkGainsZeros = { 69static xtalk_gains_t const asXtalkGainsZeros;
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
71};
72 70
73static xtalk_dline_t const alXtalkDlineZeros = { 71static xtalk_dline_t const alXtalkDlineZeros;
74 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0
77};
78static xtalk_dline_t const alXtalkDlineTest = { 72static xtalk_dline_t const alXtalkDlineTest = {
79 0xFC18, 0x03E8FFFF, 0x186A0, 0x7960FFFE, 1, 0xFFFFFFFF, 73 0xFC18, 0x03E8FFFF, 0x186A0, 0x7960FFFE, 1, 0xFFFFFFFF,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0 75 0, 0, 0, 0
82}; 76};
83 77
84static xtalk_instate_t const asXtalkInStateZeros = { 0, 0, 0, 0 }; 78static xtalk_instate_t const asXtalkInStateZeros;
85static xtalk_instate_t const asXtalkInStateTest = 79static xtalk_instate_t const asXtalkInStateTest =
86 { 0xFF80, 0x0080, 0xFFFF, 0x0001 }; 80 { 0xFF80, 0x0080, 0xFFFF, 0x0001 };
87static xtalk_state_t const asXtalkOutStateZeros = { 81static xtalk_state_t const asXtalkOutStateZeros;
88 {0, 0, 0, 0}, 82
89 {0, 0, 0, 0},
90 {0, 0, 0, 0},
91 {0, 0, 0, 0},
92 {0, 0, 0, 0}
93};
94static short const sDiamondKLeftEq = 0x401d; 83static short const sDiamondKLeftEq = 0x401d;
95static short const sDiamondKRightEq = 0x401d; 84static short const sDiamondKRightEq = 0x401d;
96static short const sDiamondKLeftXt = 0xF90E; 85static short const sDiamondKLeftXt = 0xF90E;
@@ -162,13 +151,7 @@ static xtalk_coefs_t const asXtalkNarrowCoefsRightXt = {
162 {0, 0, 0, 0, 0} 151 {0, 0, 0, 0, 0}
163}; 152};
164 153
165static xtalk_coefs_t const asXtalkCoefsZeros = { 154static xtalk_coefs_t const asXtalkCoefsZeros;
166 {0, 0, 0, 0, 0},
167 {0, 0, 0, 0, 0},
168 {0, 0, 0, 0, 0},
169 {0, 0, 0, 0, 0},
170 {0, 0, 0, 0, 0}
171};
172static xtalk_coefs_t const asXtalkCoefsPipe = { 155static xtalk_coefs_t const asXtalkCoefsPipe = {
173 {0, 0, 0x0FA0, 0, 0}, 156 {0, 0, 0x0FA0, 0, 0},
174 {0, 0, 0x0FA0, 0, 0}, 157 {0, 0, 0x0FA0, 0, 0},
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 52a364524262..6e62dafb66cd 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -33,14 +33,21 @@
33 * in the first place >:-P}), 33 * in the first place >:-P}),
34 * I was forced to base this driver on reverse engineering 34 * I was forced to base this driver on reverse engineering
35 * (3 weeks' worth of evenings filled with driver work). 35 * (3 weeks' worth of evenings filled with driver work).
36 * (and no, I did NOT go the easy way: to pick up a PCI128 for 9 Euros) 36 * (and no, I did NOT go the easy way: to pick up a SB PCI128 for 9 Euros)
37 * 37 *
38 * The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name 38 * The AZF3328 chip (note: AZF3328, *not* AZT3328, that's just the driver name
39 * for compatibility reasons) has the following features: 39 * for compatibility reasons) has the following features:
40 * 40 *
41 * - builtin AC97 conformant codec (SNR over 80dB) 41 * - builtin AC97 conformant codec (SNR over 80dB)
42 * (really AC97 compliant?? I really doubt it when looking 42 * Note that "conformant" != "compliant"!! this chip's mixer register layout
43 * at the mixer register layout) 43 * *differs* from the standard AC97 layout:
44 * they chose to not implement the headphone register (which is not a
45 * problem since it's merely optional), yet when doing this, they committed
46 * the grave sin of letting other registers follow immediately instead of
47 * keeping a headphone dummy register, thereby shifting the mixer register
48 * addresses illegally. So far unfortunately it looks like the very flexible
49 * ALSA AC97 support is still not enough to easily compensate for such a
50 * grave layout violation despite all tweaks and quirks mechanisms it offers.
44 * - builtin genuine OPL3 51 * - builtin genuine OPL3
45 * - full duplex 16bit playback/record at independent sampling rate 52 * - full duplex 16bit playback/record at independent sampling rate
46 * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr?? 53 * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr??
@@ -90,10 +97,15 @@
90 * 97 *
91 * TODO 98 * TODO
92 * - test MPU401 MIDI playback etc. 99 * - test MPU401 MIDI playback etc.
93 * - power management. See e.g. intel8x0 or cs4281. 100 * - add some power micro-management (disable various units of the card
94 * This would be nice since the chip runs a bit hot, and it's *required* 101 * as long as they're unused). However this requires I/O ports which I
95 * anyway for proper ACPI power management. 102 * haven't figured out yet and which thus might not even exist...
103 * The standard suspend/resume functionality could probably make use of
104 * some improvement, too...
96 * - figure out what all unknown port bits are responsible for 105 * - figure out what all unknown port bits are responsible for
106 * - figure out some cleverly evil scheme to possibly make ALSA AC97 code
107 * fully accept our quite incompatible ""AC97"" mixer and thus save some
108 * code (but I'm not too optimistic that doing this is possible at all)
97 */ 109 */
98 110
99#include <sound/driver.h> 111#include <sound/driver.h>
@@ -214,6 +226,16 @@ struct snd_azf3328 {
214 226
215 struct pci_dev *pci; 227 struct pci_dev *pci;
216 int irq; 228 int irq;
229
230#ifdef CONFIG_PM
231 /* register value containers for power management
232 * Note: not always full I/O range preserved (just like Win driver!) */
233 u16 saved_regs_codec [AZF_IO_SIZE_CODEC_PM / 2];
234 u16 saved_regs_io2 [AZF_IO_SIZE_IO2_PM / 2];
235 u16 saved_regs_mpu [AZF_IO_SIZE_MPU_PM / 2];
236 u16 saved_regs_synth[AZF_IO_SIZE_SYNTH_PM / 2];
237 u16 saved_regs_mixer[AZF_IO_SIZE_MIXER_PM / 2];
238#endif
217}; 239};
218 240
219static const struct pci_device_id snd_azf3328_ids[] __devinitdata = { 241static const struct pci_device_id snd_azf3328_ids[] __devinitdata = {
@@ -317,10 +339,8 @@ snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg
317 else 339 else
318 dst_vol_left &= ~0x80; 340 dst_vol_left &= ~0x80;
319 341
320 do 342 do {
321 { 343 if (!left_done) {
322 if (!left_done)
323 {
324 if (curr_vol_left > dst_vol_left) 344 if (curr_vol_left > dst_vol_left)
325 curr_vol_left--; 345 curr_vol_left--;
326 else 346 else
@@ -330,8 +350,7 @@ snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg
330 left_done = 1; 350 left_done = 1;
331 outb(curr_vol_left, portbase + 1); 351 outb(curr_vol_left, portbase + 1);
332 } 352 }
333 if (!right_done) 353 if (!right_done) {
334 {
335 if (curr_vol_right > dst_vol_right) 354 if (curr_vol_right > dst_vol_right)
336 curr_vol_right--; 355 curr_vol_right--;
337 else 356 else
@@ -346,8 +365,7 @@ snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg
346 } 365 }
347 if (delay) 366 if (delay)
348 mdelay(delay); 367 mdelay(delay);
349 } 368 } while ((!left_done) || (!right_done));
350 while ((!left_done) || (!right_done));
351 snd_azf3328_dbgcallleave(); 369 snd_azf3328_dbgcallleave();
352} 370}
353 371
@@ -514,15 +532,18 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
514 struct snd_ctl_elem_info *uinfo) 532 struct snd_ctl_elem_info *uinfo)
515{ 533{
516 static const char * const texts1[] = { 534 static const char * const texts1[] = {
517 "ModemOut1", "ModemOut2" 535 "Mic1", "Mic2"
518 }; 536 };
519 static const char * const texts2[] = { 537 static const char * const texts2[] = {
520 "MonoSelectSource1", "MonoSelectSource2" 538 "Mix", "Mic"
521 }; 539 };
522 static const char * const texts3[] = { 540 static const char * const texts3[] = {
523 "Mic", "CD", "Video", "Aux", 541 "Mic", "CD", "Video", "Aux",
524 "Line", "Mix", "Mix Mono", "Phone" 542 "Line", "Mix", "Mix Mono", "Phone"
525 }; 543 };
544 static const char * const texts4[] = {
545 "pre 3D", "post 3D"
546 };
526 struct azf3328_mixer_reg reg; 547 struct azf3328_mixer_reg reg;
527 548
528 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 549 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
@@ -531,14 +552,19 @@ snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
531 uinfo->value.enumerated.items = reg.enum_c; 552 uinfo->value.enumerated.items = reg.enum_c;
532 if (uinfo->value.enumerated.item > reg.enum_c - 1U) 553 if (uinfo->value.enumerated.item > reg.enum_c - 1U)
533 uinfo->value.enumerated.item = reg.enum_c - 1U; 554 uinfo->value.enumerated.item = reg.enum_c - 1U;
534 if (reg.reg == IDX_MIXER_ADVCTL2) 555 if (reg.reg == IDX_MIXER_ADVCTL2) {
535 { 556 switch(reg.lchan_shift) {
536 if (reg.lchan_shift == 8) /* modem out sel */ 557 case 8: /* modem out sel */
537 strcpy(uinfo->value.enumerated.name, texts1[uinfo->value.enumerated.item]); 558 strcpy(uinfo->value.enumerated.name, texts1[uinfo->value.enumerated.item]);
538 else /* mono sel source */ 559 break;
560 case 9: /* mono sel source */
539 strcpy(uinfo->value.enumerated.name, texts2[uinfo->value.enumerated.item]); 561 strcpy(uinfo->value.enumerated.name, texts2[uinfo->value.enumerated.item]);
540 } 562 break;
541 else 563 case 15: /* PCM Out Path */
564 strcpy(uinfo->value.enumerated.name, texts4[uinfo->value.enumerated.item]);
565 break;
566 }
567 } else
542 strcpy(uinfo->value.enumerated.name, texts3[uinfo->value.enumerated.item] 568 strcpy(uinfo->value.enumerated.name, texts3[uinfo->value.enumerated.item]
543); 569);
544 return 0; 570 return 0;
@@ -554,12 +580,10 @@ snd_azf3328_get_mixer_enum(struct snd_kcontrol *kcontrol,
554 580
555 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 581 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
556 val = snd_azf3328_mixer_inw(chip, reg.reg); 582 val = snd_azf3328_mixer_inw(chip, reg.reg);
557 if (reg.reg == IDX_MIXER_REC_SELECT) 583 if (reg.reg == IDX_MIXER_REC_SELECT) {
558 {
559 ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1); 584 ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
560 ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1); 585 ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1);
561 } 586 } else
562 else
563 ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1); 587 ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
564 588
565 snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n", 589 snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n",
@@ -579,16 +603,13 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
579 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 603 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
580 oreg = snd_azf3328_mixer_inw(chip, reg.reg); 604 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
581 val = oreg; 605 val = oreg;
582 if (reg.reg == IDX_MIXER_REC_SELECT) 606 if (reg.reg == IDX_MIXER_REC_SELECT) {
583 {
584 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U || 607 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U ||
585 ucontrol->value.enumerated.item[1] > reg.enum_c - 1U) 608 ucontrol->value.enumerated.item[1] > reg.enum_c - 1U)
586 return -EINVAL; 609 return -EINVAL;
587 val = (ucontrol->value.enumerated.item[0] << 8) | 610 val = (ucontrol->value.enumerated.item[0] << 8) |
588 (ucontrol->value.enumerated.item[1] << 0); 611 (ucontrol->value.enumerated.item[1] << 0);
589 } 612 } else {
590 else
591 {
592 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U) 613 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U)
593 return -EINVAL; 614 return -EINVAL;
594 val &= ~((reg.enum_c - 1) << reg.lchan_shift); 615 val &= ~((reg.enum_c - 1) << reg.lchan_shift);
@@ -629,13 +650,14 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata
629 AZF3328_MIXER_VOL_MONO("Modem Playback Volume", IDX_MIXER_MODEMOUT, 0x1f, 1), 650 AZF3328_MIXER_VOL_MONO("Modem Playback Volume", IDX_MIXER_MODEMOUT, 0x1f, 1),
630 AZF3328_MIXER_SWITCH("Modem Capture Switch", IDX_MIXER_MODEMIN, 15, 1), 651 AZF3328_MIXER_SWITCH("Modem Capture Switch", IDX_MIXER_MODEMIN, 15, 1),
631 AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1), 652 AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1),
632 AZF3328_MIXER_ENUM("Modem Out Select", IDX_MIXER_ADVCTL2, 2, 8), 653 AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8),
633 AZF3328_MIXER_ENUM("Mono Select Source", IDX_MIXER_ADVCTL2, 2, 9), 654 AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
655 AZF3328_MIXER_ENUM("PCM", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
634 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0), 656 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
635 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0), 657 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
636 AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0), 658 AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
637 AZF3328_MIXER_VOL_SPECIAL("3D Control - Wide", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */ 659 AZF3328_MIXER_VOL_SPECIAL("3D Control - Width", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
638 AZF3328_MIXER_VOL_SPECIAL("3D Control - Space", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */ 660 AZF3328_MIXER_VOL_SPECIAL("3D Control - Depth", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
639#if MIXER_TESTING 661#if MIXER_TESTING
640 AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0), 662 AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0),
641 AZF3328_MIXER_SWITCH("1", IDX_MIXER_ADVCTL2, 1, 0), 663 AZF3328_MIXER_SWITCH("1", IDX_MIXER_ADVCTL2, 1, 0),
@@ -813,22 +835,18 @@ snd_azf3328_setdmaa(struct snd_azf3328 *chip,
813 unsigned int is_running; 835 unsigned int is_running;
814 836
815 snd_azf3328_dbgcallenter(); 837 snd_azf3328_dbgcallenter();
816 if (do_recording) 838 if (do_recording) {
817 {
818 /* access capture registers, i.e. skip playback reg section */ 839 /* access capture registers, i.e. skip playback reg section */
819 portbase = chip->codec_port + 0x20; 840 portbase = chip->codec_port + 0x20;
820 is_running = chip->is_recording; 841 is_running = chip->is_recording;
821 } 842 } else {
822 else
823 {
824 /* access the playback register section */ 843 /* access the playback register section */
825 portbase = chip->codec_port + 0x00; 844 portbase = chip->codec_port + 0x00;
826 is_running = chip->is_playing; 845 is_running = chip->is_playing;
827 } 846 }
828 847
829 /* AZF3328 uses a two buffer pointer DMA playback approach */ 848 /* AZF3328 uses a two buffer pointer DMA playback approach */
830 if (!is_running) 849 if (!is_running) {
831 {
832 unsigned long addr_area2; 850 unsigned long addr_area2;
833 unsigned long count_areas, count_tmp; /* width 32bit -- overflow!! */ 851 unsigned long count_areas, count_tmp; /* width 32bit -- overflow!! */
834 count_areas = size/2; 852 count_areas = size/2;
@@ -961,6 +979,13 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
961 chip->is_playing = 1; 979 chip->is_playing = 1;
962 snd_azf3328_dbgplay("STARTED PLAYBACK\n"); 980 snd_azf3328_dbgplay("STARTED PLAYBACK\n");
963 break; 981 break;
982 case SNDRV_PCM_TRIGGER_RESUME:
983 snd_azf3328_dbgplay("RESUME PLAYBACK\n");
984 /* resume playback if we were active */
985 if (chip->is_playing)
986 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
987 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) | DMA_RESUME);
988 break;
964 case SNDRV_PCM_TRIGGER_STOP: 989 case SNDRV_PCM_TRIGGER_STOP:
965 snd_azf3328_dbgplay("STOP PLAYBACK\n"); 990 snd_azf3328_dbgplay("STOP PLAYBACK\n");
966 991
@@ -988,6 +1013,12 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
988 chip->is_playing = 0; 1013 chip->is_playing = 0;
989 snd_azf3328_dbgplay("STOPPED PLAYBACK\n"); 1014 snd_azf3328_dbgplay("STOPPED PLAYBACK\n");
990 break; 1015 break;
1016 case SNDRV_PCM_TRIGGER_SUSPEND:
1017 snd_azf3328_dbgplay("SUSPEND PLAYBACK\n");
1018 /* make sure playback is stopped */
1019 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
1020 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) & ~DMA_RESUME);
1021 break;
991 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1022 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
992 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n"); 1023 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
993 break; 1024 break;
@@ -995,6 +1026,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
995 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n"); 1026 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
996 break; 1027 break;
997 default: 1028 default:
1029 printk(KERN_ERR "FIXME: unknown trigger mode!\n");
998 return -EINVAL; 1030 return -EINVAL;
999 } 1031 }
1000 1032
@@ -1068,6 +1100,13 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1068 chip->is_recording = 1; 1100 chip->is_recording = 1;
1069 snd_azf3328_dbgplay("STARTED CAPTURE\n"); 1101 snd_azf3328_dbgplay("STARTED CAPTURE\n");
1070 break; 1102 break;
1103 case SNDRV_PCM_TRIGGER_RESUME:
1104 snd_azf3328_dbgplay("RESUME CAPTURE\n");
1105 /* resume recording if we were active */
1106 if (chip->is_recording)
1107 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1108 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) | DMA_RESUME);
1109 break;
1071 case SNDRV_PCM_TRIGGER_STOP: 1110 case SNDRV_PCM_TRIGGER_STOP:
1072 snd_azf3328_dbgplay("STOP CAPTURE\n"); 1111 snd_azf3328_dbgplay("STOP CAPTURE\n");
1073 1112
@@ -1088,6 +1127,12 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1088 chip->is_recording = 0; 1127 chip->is_recording = 0;
1089 snd_azf3328_dbgplay("STOPPED CAPTURE\n"); 1128 snd_azf3328_dbgplay("STOPPED CAPTURE\n");
1090 break; 1129 break;
1130 case SNDRV_PCM_TRIGGER_SUSPEND:
1131 snd_azf3328_dbgplay("SUSPEND CAPTURE\n");
1132 /* make sure recording is stopped */
1133 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1134 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) & ~DMA_RESUME);
1135 break;
1091 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1136 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1092 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n"); 1137 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
1093 break; 1138 break;
@@ -1095,6 +1140,7 @@ snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1095 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n"); 1140 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1096 break; 1141 break;
1097 default: 1142 default:
1143 printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1098 return -EINVAL; 1144 return -EINVAL;
1099 } 1145 }
1100 1146
@@ -1163,8 +1209,7 @@ snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1163 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE), 1209 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
1164 status); 1210 status);
1165 1211
1166 if (status & IRQ_TIMER) 1212 if (status & IRQ_TIMER) {
1167 {
1168 /* snd_azf3328_dbgplay("timer %ld\n", inl(chip->codec_port+IDX_IO_TIMER_VALUE) & TIMER_VALUE_MASK); */ 1213 /* snd_azf3328_dbgplay("timer %ld\n", inl(chip->codec_port+IDX_IO_TIMER_VALUE) & TIMER_VALUE_MASK); */
1169 if (chip->timer) 1214 if (chip->timer)
1170 snd_timer_interrupt(chip->timer, chip->timer->sticks); 1215 snd_timer_interrupt(chip->timer, chip->timer->sticks);
@@ -1174,50 +1219,43 @@ snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1174 spin_unlock(&chip->reg_lock); 1219 spin_unlock(&chip->reg_lock);
1175 snd_azf3328_dbgplay("azt3328: timer IRQ\n"); 1220 snd_azf3328_dbgplay("azt3328: timer IRQ\n");
1176 } 1221 }
1177 if (status & IRQ_PLAYBACK) 1222 if (status & IRQ_PLAYBACK) {
1178 {
1179 spin_lock(&chip->reg_lock); 1223 spin_lock(&chip->reg_lock);
1180 which = snd_azf3328_codec_inb(chip, IDX_IO_PLAY_IRQTYPE); 1224 which = snd_azf3328_codec_inb(chip, IDX_IO_PLAY_IRQTYPE);
1181 /* ack all IRQ types immediately */ 1225 /* ack all IRQ types immediately */
1182 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which); 1226 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which);
1183 spin_unlock(&chip->reg_lock); 1227 spin_unlock(&chip->reg_lock);
1184 1228
1185 if (chip->pcm && chip->playback_substream) 1229 if (chip->pcm && chip->playback_substream) {
1186 {
1187 snd_pcm_period_elapsed(chip->playback_substream); 1230 snd_pcm_period_elapsed(chip->playback_substream);
1188 snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n", 1231 snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n",
1189 which, 1232 which,
1190 inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS)); 1233 inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
1191 } 1234 } else
1192 else
1193 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n"); 1235 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
1194 if (which & IRQ_PLAY_SOMETHING) 1236 if (which & IRQ_PLAY_SOMETHING)
1195 snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n"); 1237 snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n");
1196 } 1238 }
1197 if (status & IRQ_RECORDING) 1239 if (status & IRQ_RECORDING) {
1198 {
1199 spin_lock(&chip->reg_lock); 1240 spin_lock(&chip->reg_lock);
1200 which = snd_azf3328_codec_inb(chip, IDX_IO_REC_IRQTYPE); 1241 which = snd_azf3328_codec_inb(chip, IDX_IO_REC_IRQTYPE);
1201 /* ack all IRQ types immediately */ 1242 /* ack all IRQ types immediately */
1202 snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which); 1243 snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which);
1203 spin_unlock(&chip->reg_lock); 1244 spin_unlock(&chip->reg_lock);
1204 1245
1205 if (chip->pcm && chip->capture_substream) 1246 if (chip->pcm && chip->capture_substream) {
1206 {
1207 snd_pcm_period_elapsed(chip->capture_substream); 1247 snd_pcm_period_elapsed(chip->capture_substream);
1208 snd_azf3328_dbgplay("REC period done (#%x), @ %x\n", 1248 snd_azf3328_dbgplay("REC period done (#%x), @ %x\n",
1209 which, 1249 which,
1210 inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS)); 1250 inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
1211 } 1251 } else
1212 else
1213 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n"); 1252 snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
1214 if (which & IRQ_REC_SOMETHING) 1253 if (which & IRQ_REC_SOMETHING)
1215 snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n"); 1254 snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n");
1216 } 1255 }
1217 /* MPU401 has less critical IRQ requirements 1256 /* MPU401 has less critical IRQ requirements
1218 * than timer and playback/recording, right? */ 1257 * than timer and playback/recording, right? */
1219 if (status & IRQ_MPU401) 1258 if (status & IRQ_MPU401) {
1220 {
1221 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); 1259 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
1222 1260
1223 /* hmm, do we have to ack the IRQ here somehow? 1261 /* hmm, do we have to ack the IRQ here somehow?
@@ -1511,8 +1549,7 @@ snd_azf3328_timer_start(struct snd_timer *timer)
1511 snd_azf3328_dbgcallenter(); 1549 snd_azf3328_dbgcallenter();
1512 chip = snd_timer_chip(timer); 1550 chip = snd_timer_chip(timer);
1513 delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK; 1551 delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
1514 if (delay < 49) 1552 if (delay < 49) {
1515 {
1516 /* uhoh, that's not good, since user-space won't know about 1553 /* uhoh, that's not good, since user-space won't know about
1517 * this timing tweak 1554 * this timing tweak
1518 * (we need to do it to avoid a lockup, though) */ 1555 * (we need to do it to avoid a lockup, though) */
@@ -1766,9 +1803,11 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
1766 goto out_err; 1803 goto out_err;
1767 } 1804 }
1768 1805
1806 card->private_data = chip;
1807
1769 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401, 1808 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401,
1770 chip->mpu_port, 1, pci->irq, 0, 1809 chip->mpu_port, MPU401_INFO_INTEGRATED,
1771 &chip->rmidi)) < 0) { 1810 pci->irq, 0, &chip->rmidi)) < 0) {
1772 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port); 1811 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);
1773 goto out_err; 1812 goto out_err;
1774 } 1813 }
@@ -1791,6 +1830,8 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
1791 } 1830 }
1792 } 1831 }
1793 1832
1833 opl3->private_data = chip;
1834
1794 sprintf(card->longname, "%s at 0x%lx, irq %i", 1835 sprintf(card->longname, "%s at 0x%lx, irq %i",
1795 card->shortname, chip->codec_port, chip->irq); 1836 card->shortname, chip->codec_port, chip->irq);
1796 1837
@@ -1834,11 +1875,80 @@ snd_azf3328_remove(struct pci_dev *pci)
1834 snd_azf3328_dbgcallleave(); 1875 snd_azf3328_dbgcallleave();
1835} 1876}
1836 1877
1878#ifdef CONFIG_PM
1879static int
1880snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
1881{
1882 struct snd_card *card = pci_get_drvdata(pci);
1883 struct snd_azf3328 *chip = card->private_data;
1884 int reg;
1885
1886 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1887
1888 snd_pcm_suspend_all(chip->pcm);
1889
1890 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++)
1891 chip->saved_regs_mixer[reg] = inw(chip->mixer_port + reg * 2);
1892
1893 /* make sure to disable master volume etc. to prevent looping sound */
1894 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
1895 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
1896
1897 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++)
1898 chip->saved_regs_codec[reg] = inw(chip->codec_port + reg * 2);
1899 for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++)
1900 chip->saved_regs_io2[reg] = inw(chip->io2_port + reg * 2);
1901 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++)
1902 chip->saved_regs_mpu[reg] = inw(chip->mpu_port + reg * 2);
1903 for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++)
1904 chip->saved_regs_synth[reg] = inw(chip->synth_port + reg * 2);
1905
1906 pci_set_power_state(pci, PCI_D3hot);
1907 pci_disable_device(pci);
1908 pci_save_state(pci);
1909 return 0;
1910}
1911
1912static int
1913snd_azf3328_resume(struct pci_dev *pci)
1914{
1915 struct snd_card *card = pci_get_drvdata(pci);
1916 struct snd_azf3328 *chip = card->private_data;
1917 int reg;
1918
1919 pci_restore_state(pci);
1920 pci_enable_device(pci);
1921 pci_set_power_state(pci, PCI_D0);
1922 pci_set_master(pci);
1923
1924 for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++)
1925 outw(chip->saved_regs_io2[reg], chip->io2_port + reg * 2);
1926 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; reg++)
1927 outw(chip->saved_regs_mpu[reg], chip->mpu_port + reg * 2);
1928 for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++)
1929 outw(chip->saved_regs_synth[reg], chip->synth_port + reg * 2);
1930 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; reg++)
1931 outw(chip->saved_regs_mixer[reg], chip->mixer_port + reg * 2);
1932 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; reg++)
1933 outw(chip->saved_regs_codec[reg], chip->codec_port + reg * 2);
1934
1935 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1936 return 0;
1937}
1938#endif
1939
1940
1941
1942
1837static struct pci_driver driver = { 1943static struct pci_driver driver = {
1838 .name = "AZF3328", 1944 .name = "AZF3328",
1839 .id_table = snd_azf3328_ids, 1945 .id_table = snd_azf3328_ids,
1840 .probe = snd_azf3328_probe, 1946 .probe = snd_azf3328_probe,
1841 .remove = __devexit_p(snd_azf3328_remove), 1947 .remove = __devexit_p(snd_azf3328_remove),
1948#ifdef CONFIG_PM
1949 .suspend = snd_azf3328_suspend,
1950 .resume = snd_azf3328_resume,
1951#endif
1842}; 1952};
1843 1953
1844static int __init 1954static int __init
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h
index f489bdaf6d40..b4f3e3cd006b 100644
--- a/sound/pci/azt3328.h
+++ b/sound/pci/azt3328.h
@@ -5,6 +5,9 @@
5 5
6/*** main I/O area port indices ***/ 6/*** main I/O area port indices ***/
7/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */ 7/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */
8#define AZF_IO_SIZE_CODEC 0x80
9#define AZF_IO_SIZE_CODEC_PM 0x70
10
8/* the driver initialisation suggests a layout of 4 main areas: 11/* the driver initialisation suggests a layout of 4 main areas:
9 * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe MPU401??). 12 * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe MPU401??).
10 * And another area from 0x60 to 0x6f (DirectX timer, IRQ management, 13 * And another area from 0x60 to 0x6f (DirectX timer, IRQ management,
@@ -87,7 +90,7 @@
87#define IDX_IO_REC_DMA_CURROFS 0x34 /* PU:0x00000000 */ 90#define IDX_IO_REC_DMA_CURROFS 0x34 /* PU:0x00000000 */
88#define IDX_IO_REC_SOUNDFORMAT 0x36 /* PU:0x0000 */ 91#define IDX_IO_REC_SOUNDFORMAT 0x36 /* PU:0x0000 */
89 92
90/** hmm, what is this I/O area for? MPU401?? (after playback, recording, ???, timer) **/ 93/** hmm, what is this I/O area for? MPU401?? or external DAC via I2S?? (after playback, recording, ???, timer) **/
91#define IDX_IO_SOMETHING_FLAGS 0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init, PU:0x0000 */ 94#define IDX_IO_SOMETHING_FLAGS 0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init, PU:0x0000 */
92/* general */ 95/* general */
93#define IDX_IO_42H 0x42 /* PU:0x0001 */ 96#define IDX_IO_42H 0x42 /* PU:0x0001 */
@@ -107,7 +110,8 @@
107 #define IRQ_UNKNOWN2 0x0080 /* probably unused */ 110 #define IRQ_UNKNOWN2 0x0080 /* probably unused */
108#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */ 111#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
109#define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */ 112#define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */
110#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated; actually inhibits PCM playback!!! maybe power management?? */ 113#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */
114 #define IO_6A_PAUSE_PLAYBACK 0x0200 /* bit 9; sure, this pauses playback, but what the heck is this really about?? */
111#define IDX_IO_6CH 0x6C 115#define IDX_IO_6CH 0x6C
112#define IDX_IO_6EH 0x6E /* writing 0xffff returns 0x83fe */ 116#define IDX_IO_6EH 0x6E /* writing 0xffff returns 0x83fe */
113/* further I/O indices not saved/restored, so probably not used */ 117/* further I/O indices not saved/restored, so probably not used */
@@ -115,15 +119,25 @@
115 119
116/*** I/O 2 area port indices ***/ 120/*** I/O 2 area port indices ***/
117/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */ 121/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
122#define AZF_IO_SIZE_IO2 0x08
123#define AZF_IO_SIZE_IO2_PM 0x06
124
118#define IDX_IO2_LEGACY_ADDR 0x04 125#define IDX_IO2_LEGACY_ADDR 0x04
119 #define LEGACY_SOMETHING 0x01 /* OPL3?? */ 126 #define LEGACY_SOMETHING 0x01 /* OPL3?? */
120 #define LEGACY_JOY 0x08 127 #define LEGACY_JOY 0x08
121 128
129#define AZF_IO_SIZE_MPU 0x04
130#define AZF_IO_SIZE_MPU_PM 0x04
131
132#define AZF_IO_SIZE_SYNTH 0x08
133#define AZF_IO_SIZE_SYNTH_PM 0x06
122 134
123/*** mixer I/O area port indices ***/ 135/*** mixer I/O area port indices ***/
124/* (only 0x22 of 0x40 bytes saved/restored by Windows driver) 136/* (only 0x22 of 0x40 bytes saved/restored by Windows driver)
125 * generally spoken: AC97 register index = AZF3328 mixer reg index + 2 137 * UNFORTUNATELY azf3328 is NOT truly AC97 compliant: see main file intro */
126 * (in other words: AZF3328 NOT fully AC97 compliant) */ 138#define AZF_IO_SIZE_MIXER 0x40
139#define AZF_IO_SIZE_MIXER_PM 0x22
140
127 #define MIXER_VOLUME_RIGHT_MASK 0x001f 141 #define MIXER_VOLUME_RIGHT_MASK 0x001f
128 #define MIXER_VOLUME_LEFT_MASK 0x1f00 142 #define MIXER_VOLUME_LEFT_MASK 0x1f00
129 #define MIXER_MUTE_MASK 0x8000 143 #define MIXER_MUTE_MASK 0x8000
@@ -156,14 +170,14 @@
156#define IDX_MIXER_ADVCTL1 0x1e 170#define IDX_MIXER_ADVCTL1 0x1e
157 /* unlisted bits are unmodifiable */ 171 /* unlisted bits are unmodifiable */
158 #define MIXER_ADVCTL1_3DWIDTH_MASK 0x000e 172 #define MIXER_ADVCTL1_3DWIDTH_MASK 0x000e
159 #define MIXER_ADVCTL1_HIFI3D_MASK 0x0300 173 #define MIXER_ADVCTL1_HIFI3D_MASK 0x0300 /* yup, this is missing the high bit that official AC97 contains, plus it doesn't have linear bit value range behaviour but instead acts weirdly (possibly we're dealing with two *different* 3D settings here??) */
160#define IDX_MIXER_ADVCTL2 0x20 /* resembles AC97_GENERAL_PURPOSE reg! */ 174#define IDX_MIXER_ADVCTL2 0x20 /* subset of AC97_GENERAL_PURPOSE reg! */
161 /* unlisted bits are unmodifiable */ 175 /* unlisted bits are unmodifiable */
162 #define MIXER_ADVCTL2_BIT7 0x0080 /* WaveOut 3D Bypass? mutes WaveOut at LineOut */ 176 #define MIXER_ADVCTL2_LPBK 0x0080 /* Loopback mode -- Win driver: "WaveOut3DBypass"? mutes WaveOut at LineOut */
163 #define MIXER_ADVCTL2_BIT8 0x0100 /* is this Modem Out Select? */ 177 #define MIXER_ADVCTL2_MS 0x0100 /* Mic Select 0=Mic1, 1=Mic2 -- Win driver: "ModemOutSelect"?? */
164 #define MIXER_ADVCTL2_BIT9 0x0200 /* Mono Select Source? */ 178 #define MIXER_ADVCTL2_MIX 0x0200 /* Mono output select 0=Mix, 1=Mic; Win driver: "MonoSelectSource"?? */
165 #define MIXER_ADVCTL2_BIT13 0x2000 /* 3D enable? */ 179 #define MIXER_ADVCTL2_3D 0x2000 /* 3D Enhancement 1=on */
166 #define MIXER_ADVCTL2_BIT15 0x8000 /* unknown */ 180 #define MIXER_ADVCTL2_POP 0x8000 /* Pcm Out Path, 0=pre 3D, 1=post 3D */
167 181
168#define IDX_MIXER_SOMETHING30H 0x30 /* used, but unknown??? */ 182#define IDX_MIXER_SOMETHING30H 0x30 /* used, but unknown??? */
169 183
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 9ee07d4aac1e..c33642d8d9a1 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -44,7 +44,7 @@ MODULE_SUPPORTED_DEVICE("{{Brooktree,Bt878},"
44static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */ 44static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
45static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 45static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
46static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 46static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
47static int digital_rate[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* digital input rate */ 47static int digital_rate[SNDRV_CARDS]; /* digital input rate */
48static int load_all; /* allow to load the non-whitelisted cards */ 48static int load_all; /* allow to load the non-whitelisted cards */
49 49
50module_param_array(index, int, NULL, 0444); 50module_param_array(index, int, NULL, 0444);
@@ -781,10 +781,12 @@ static struct pci_device_id snd_bt87x_ids[] __devinitdata = {
781 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000), 781 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000),
782 /* Viewcast Osprey 200 */ 782 /* Viewcast Osprey 200 */
783 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), 783 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100),
784 /* AVerMedia Studio No. 103, 203, ...? */
785 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000),
786 /* Leadtek Winfast tv 2000xp delux */ 784 /* Leadtek Winfast tv 2000xp delux */
787 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000), 785 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000),
786 /* Voodoo TV 200 */
787 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, 32000),
788 /* AVerMedia Studio No. 103, 203, ...? */
789 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000),
788 { } 790 { }
789}; 791};
790MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); 792MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index c8131ea92ed6..9cb66c59f523 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -537,9 +537,9 @@
537#endif 537#endif
538 538
539#define ADC_MUX_MASK 0x0000000f //Mask for ADC Mux 539#define ADC_MUX_MASK 0x0000000f //Mask for ADC Mux
540#define ADC_MUX_PHONE 0x00000001 //Value to select TAD at ADC Mux (Not used)
540#define ADC_MUX_MIC 0x00000002 //Value to select Mic at ADC Mux 541#define ADC_MUX_MIC 0x00000002 //Value to select Mic at ADC Mux
541#define ADC_MUX_LINEIN 0x00000004 //Value to select LineIn at ADC Mux 542#define ADC_MUX_LINEIN 0x00000004 //Value to select LineIn at ADC Mux
542#define ADC_MUX_PHONE 0x00000001 //Value to select TAD at ADC Mux (Not used)
543#define ADC_MUX_AUX 0x00000008 //Value to select Aux at ADC Mux 543#define ADC_MUX_AUX 0x00000008 //Value to select Aux at ADC Mux
544 544
545#define SET_CHANNEL 0 /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */ 545#define SET_CHANNEL 0 /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
@@ -604,6 +604,8 @@ struct snd_ca0106 {
604 u32 spdif_bits[4]; /* s/pdif out setup */ 604 u32 spdif_bits[4]; /* s/pdif out setup */
605 int spdif_enable; 605 int spdif_enable;
606 int capture_source; 606 int capture_source;
607 int i2c_capture_source;
608 u8 i2c_capture_volume[4][2];
607 int capture_mic_line_in; 609 int capture_mic_line_in;
608 610
609 struct snd_dma_buffer buffer; 611 struct snd_dma_buffer buffer;
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index fd8bfebfbd54..59bf9bd02534 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -186,8 +186,8 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
186 /* New Audigy SE. Has a different DAC. */ 186 /* New Audigy SE. Has a different DAC. */
187 /* SB0570: 187 /* SB0570:
188 * CTRL:CA0106-DAT 188 * CTRL:CA0106-DAT
189 * ADC: WM8768GEDS 189 * ADC: WM8775EDS
190 * DAC: WM8775EDS 190 * DAC: WM8768GEDS
191 */ 191 */
192 { .serial = 0x100a1102, 192 { .serial = 0x100a1102,
193 .name = "Audigy SE [SB0570]", 193 .name = "Audigy SE [SB0570]",
@@ -195,9 +195,14 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
195 .i2c_adc = 1, 195 .i2c_adc = 1,
196 .spi_dac = 1 } , 196 .spi_dac = 1 } ,
197 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */ 197 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */
198 /* SB0438
199 * CTRL:CA0106-DAT
200 * ADC: WM8775SEDS
201 * DAC: CS4382-KQZ
202 */
198 { .serial = 0x10091462, 203 { .serial = 0x10091462,
199 .name = "MSI K8N Diamond MB [SB0438]", 204 .name = "MSI K8N Diamond MB [SB0438]",
200 .gpio_type = 1, 205 .gpio_type = 2,
201 .i2c_adc = 1 } , 206 .i2c_adc = 1 } ,
202 /* Shuttle XPC SD31P which has an onboard Creative Labs 207 /* Shuttle XPC SD31P which has an onboard Creative Labs
203 * Sound Blaster Live! 24-bit EAX 208 * Sound Blaster Live! 24-bit EAX
@@ -326,6 +331,7 @@ int snd_ca0106_spi_write(struct snd_ca0106 * emu,
326 return 0; 331 return 0;
327} 332}
328 333
334/* The ADC does not support i2c read, so only write is implemented */
329int snd_ca0106_i2c_write(struct snd_ca0106 *emu, 335int snd_ca0106_i2c_write(struct snd_ca0106 *emu,
330 u32 reg, 336 u32 reg,
331 u32 value) 337 u32 value)
@@ -340,6 +346,7 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu,
340 } 346 }
341 347
342 tmp = reg << 25 | value << 16; 348 tmp = reg << 25 | value << 16;
349 // snd_printk("I2C-write:reg=0x%x, value=0x%x\n", reg, value);
343 /* Not sure what this I2C channel controls. */ 350 /* Not sure what this I2C channel controls. */
344 /* snd_ca0106_ptr_write(emu, I2C_D0, 0, tmp); */ 351 /* snd_ca0106_ptr_write(emu, I2C_D0, 0, tmp); */
345 352
@@ -348,8 +355,9 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu,
348 355
349 for (retry = 0; retry < 10; retry++) { 356 for (retry = 0; retry < 10; retry++) {
350 /* Send the data to i2c */ 357 /* Send the data to i2c */
351 tmp = snd_ca0106_ptr_read(emu, I2C_A, 0); 358 //tmp = snd_ca0106_ptr_read(emu, I2C_A, 0);
352 tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK); 359 //tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK);
360 tmp = 0;
353 tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD); 361 tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD);
354 snd_ca0106_ptr_write(emu, I2C_A, 0, tmp); 362 snd_ca0106_ptr_write(emu, I2C_A, 0, tmp);
355 363
@@ -1181,7 +1189,7 @@ static unsigned int spi_dac_init[] = {
1181 0x02ff, 1189 0x02ff,
1182 0x0400, 1190 0x0400,
1183 0x0520, 1191 0x0520,
1184 0x0600, 1192 0x0620, /* Set 24 bit. Was 0x0600 */
1185 0x08ff, 1193 0x08ff,
1186 0x0aff, 1194 0x0aff,
1187 0x0cff, 1195 0x0cff,
@@ -1200,6 +1208,22 @@ static unsigned int spi_dac_init[] = {
1200 0x1400, 1208 0x1400,
1201}; 1209};
1202 1210
1211static unsigned int i2c_adc_init[][2] = {
1212 { 0x17, 0x00 }, /* Reset */
1213 { 0x07, 0x00 }, /* Timeout */
1214 { 0x0b, 0x22 }, /* Interface control */
1215 { 0x0c, 0x22 }, /* Master mode control */
1216 { 0x0d, 0x08 }, /* Powerdown control */
1217 { 0x0e, 0xcf }, /* Attenuation Left 0x01 = -103dB, 0xff = 24dB */
1218 { 0x0f, 0xcf }, /* Attenuation Right 0.5dB steps */
1219 { 0x10, 0x7b }, /* ALC Control 1 */
1220 { 0x11, 0x00 }, /* ALC Control 2 */
1221 { 0x12, 0x32 }, /* ALC Control 3 */
1222 { 0x13, 0x00 }, /* Noise gate control */
1223 { 0x14, 0xa6 }, /* Limiter control */
1224 { 0x15, ADC_MUX_LINEIN }, /* ADC Mixer control */
1225};
1226
1203static int __devinit snd_ca0106_create(struct snd_card *card, 1227static int __devinit snd_ca0106_create(struct snd_card *card,
1204 struct pci_dev *pci, 1228 struct pci_dev *pci,
1205 struct snd_ca0106 **rchip) 1229 struct snd_ca0106 **rchip)
@@ -1361,7 +1385,12 @@ static int __devinit snd_ca0106_create(struct snd_card *card,
1361 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC, Line in, TAD in, AUX in */ 1385 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC, Line in, TAD in, AUX in */
1362 chip->capture_source = 3; /* Set CAPTURE_SOURCE */ 1386 chip->capture_source = 3; /* Set CAPTURE_SOURCE */
1363 1387
1364 if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */ 1388 if (chip->details->gpio_type == 2) { /* The SB0438 use GPIO differently. */
1389 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */
1390 outl(0x0, chip->port+GPIO);
1391 //outl(0x00f0e000, chip->port+GPIO); /* Analog */
1392 outl(0x005f5301, chip->port+GPIO); /* Analog */
1393 } else if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */
1365 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ 1394 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */
1366 outl(0x0, chip->port+GPIO); 1395 outl(0x0, chip->port+GPIO);
1367 //outl(0x00f0e000, chip->port+GPIO); /* Analog */ 1396 //outl(0x00f0e000, chip->port+GPIO); /* Analog */
@@ -1379,7 +1408,19 @@ static int __devinit snd_ca0106_create(struct snd_card *card,
1379 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */ 1408 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */
1380 1409
1381 if (chip->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */ 1410 if (chip->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */
1382 snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */ 1411 int size, n;
1412
1413 size = ARRAY_SIZE(i2c_adc_init);
1414 //snd_printk("I2C:array size=0x%x\n", size);
1415 for (n=0; n < size; n++) {
1416 snd_ca0106_i2c_write(chip, i2c_adc_init[n][0], i2c_adc_init[n][1]);
1417 }
1418 for (n=0; n < 4; n++) {
1419 chip->i2c_capture_volume[n][0]= 0xcf;
1420 chip->i2c_capture_volume[n][1]= 0xcf;
1421 }
1422 chip->i2c_capture_source=2; /* Line in */
1423 //snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */
1383 } 1424 }
1384 if (chip->details->spi_dac == 1) { /* The SB0570 use SPI to control DAC. */ 1425 if (chip->details->spi_dac == 1) { /* The SB0570 use SPI to control DAC. */
1385 int size, n; 1426 int size, n;
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 06fe055674fb..146eed70dce6 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -171,6 +171,76 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
171 return change; 171 return change;
172} 172}
173 173
174static int snd_ca0106_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
175 struct snd_ctl_elem_info *uinfo)
176{
177 static char *texts[6] = {
178 "Phone", "Mic", "Line in", "Aux"
179 };
180
181 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
182 uinfo->count = 1;
183 uinfo->value.enumerated.items = 4;
184 if (uinfo->value.enumerated.item > 3)
185 uinfo->value.enumerated.item = 3;
186 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
187 return 0;
188}
189
190static int snd_ca0106_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
191 struct snd_ctl_elem_value *ucontrol)
192{
193 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
194
195 ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
196 return 0;
197}
198
199static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
200 struct snd_ctl_elem_value *ucontrol)
201{
202 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
203 unsigned int source_id;
204 unsigned int ngain, ogain;
205 int change = 0;
206 u32 source;
207 /* If the capture source has changed,
208 * update the capture volume from the cached value
209 * for the particular source.
210 */
211 source_id = ucontrol->value.enumerated.item[0] ;
212 change = (emu->i2c_capture_source != source_id);
213 if (change) {
214 snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
215 ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
216 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
217 if (ngain != ogain)
218 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff));
219 ngain = emu->i2c_capture_volume[source_id][1]; /* Left */
220 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Left */
221 if (ngain != ogain)
222 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
223 source = 1 << source_id;
224 snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
225 emu->i2c_capture_source = source_id;
226 }
227 return change;
228}
229
230static int snd_ca0106_capture_line_in_side_out_info(struct snd_kcontrol *kcontrol,
231 struct snd_ctl_elem_info *uinfo)
232{
233 static char *texts[2] = { "Side out", "Line in" };
234
235 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
236 uinfo->count = 1;
237 uinfo->value.enumerated.items = 2;
238 if (uinfo->value.enumerated.item > 1)
239 uinfo->value.enumerated.item = 1;
240 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
241 return 0;
242}
243
174static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol, 244static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol,
175 struct snd_ctl_elem_info *uinfo) 245 struct snd_ctl_elem_info *uinfo)
176{ 246{
@@ -207,16 +277,16 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
207 if (change) { 277 if (change) {
208 emu->capture_mic_line_in = val; 278 emu->capture_mic_line_in = val;
209 if (val) { 279 if (val) {
210 snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_PHONE); /* Mute input */ 280 //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
211 tmp = inl(emu->port+GPIO) & ~0x400; 281 tmp = inl(emu->port+GPIO) & ~0x400;
212 tmp = tmp | 0x400; 282 tmp = tmp | 0x400;
213 outl(tmp, emu->port+GPIO); 283 outl(tmp, emu->port+GPIO);
214 snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); 284 //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC);
215 } else { 285 } else {
216 snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_PHONE); /* Mute input */ 286 //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
217 tmp = inl(emu->port+GPIO) & ~0x400; 287 tmp = inl(emu->port+GPIO) & ~0x400;
218 outl(tmp, emu->port+GPIO); 288 outl(tmp, emu->port+GPIO);
219 snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); 289 //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN);
220 } 290 }
221 } 291 }
222 return change; 292 return change;
@@ -225,12 +295,22 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
225static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in __devinitdata = 295static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in __devinitdata =
226{ 296{
227 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 297 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
228 .name = "Mic/Line in Capture", 298 .name = "Shared Mic/Line in Capture Switch",
229 .info = snd_ca0106_capture_mic_line_in_info, 299 .info = snd_ca0106_capture_mic_line_in_info,
230 .get = snd_ca0106_capture_mic_line_in_get, 300 .get = snd_ca0106_capture_mic_line_in_get,
231 .put = snd_ca0106_capture_mic_line_in_put 301 .put = snd_ca0106_capture_mic_line_in_put
232}; 302};
233 303
304static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out __devinitdata =
305{
306 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
307 .name = "Shared Line in/Side out Capture Switch",
308 .info = snd_ca0106_capture_line_in_side_out_info,
309 .get = snd_ca0106_capture_mic_line_in_get,
310 .put = snd_ca0106_capture_mic_line_in_put
311};
312
313
234static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol, 314static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
235 struct snd_ctl_elem_info *uinfo) 315 struct snd_ctl_elem_info *uinfo)
236{ 316{
@@ -329,15 +409,81 @@ static int snd_ca0106_volume_put(struct snd_kcontrol *kcontrol,
329 return 1; 409 return 1;
330} 410}
331 411
412static int snd_ca0106_i2c_volume_info(struct snd_kcontrol *kcontrol,
413 struct snd_ctl_elem_info *uinfo)
414{
415 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
416 uinfo->count = 2;
417 uinfo->value.integer.min = 0;
418 uinfo->value.integer.max = 255;
419 return 0;
420}
421
422static int snd_ca0106_i2c_volume_get(struct snd_kcontrol *kcontrol,
423 struct snd_ctl_elem_value *ucontrol)
424{
425 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
426 int source_id;
427
428 source_id = kcontrol->private_value;
429
430 ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
431 ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
432 return 0;
433}
434
435static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
436 struct snd_ctl_elem_value *ucontrol)
437{
438 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
439 unsigned int ogain;
440 unsigned int ngain;
441 int source_id;
442 int change = 0;
443
444 source_id = kcontrol->private_value;
445 ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
446 ngain = ucontrol->value.integer.value[0];
447 if (ngain > 0xff)
448 return 0;
449 if (ogain != ngain) {
450 if (emu->i2c_capture_source == source_id)
451 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
452 emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0];
453 change = 1;
454 }
455 ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
456 ngain = ucontrol->value.integer.value[1];
457 if (ngain > 0xff)
458 return 0;
459 if (ogain != ngain) {
460 if (emu->i2c_capture_source == source_id)
461 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
462 emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1];
463 change = 1;
464 }
465
466 return change;
467}
468
332#define CA_VOLUME(xname,chid,reg) \ 469#define CA_VOLUME(xname,chid,reg) \
333{ \ 470{ \
334 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 471 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
335 .info = snd_ca0106_volume_info, \ 472 .info = snd_ca0106_volume_info, \
336 .get = snd_ca0106_volume_get, \ 473 .get = snd_ca0106_volume_get, \
337 .put = snd_ca0106_volume_put, \ 474 .put = snd_ca0106_volume_put, \
338 .private_value = ((chid) << 8) | (reg) \ 475 .private_value = ((chid) << 8) | (reg) \
339} 476}
340 477
478#define I2C_VOLUME(xname,chid) \
479{ \
480 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
481 .info = snd_ca0106_i2c_volume_info, \
482 .get = snd_ca0106_i2c_volume_get, \
483 .put = snd_ca0106_i2c_volume_put, \
484 .private_value = chid \
485}
486
341 487
342static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = { 488static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
343 CA_VOLUME("Analog Front Playback Volume", 489 CA_VOLUME("Analog Front Playback Volume",
@@ -361,6 +507,11 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
361 CA_VOLUME("CAPTURE feedback Playback Volume", 507 CA_VOLUME("CAPTURE feedback Playback Volume",
362 1, CAPTURE_CONTROL), 508 1, CAPTURE_CONTROL),
363 509
510 I2C_VOLUME("Phone Capture Volume", 0),
511 I2C_VOLUME("Mic Capture Volume", 1),
512 I2C_VOLUME("Line in Capture Volume", 2),
513 I2C_VOLUME("Aux Capture Volume", 3),
514
364 { 515 {
365 .access = SNDRV_CTL_ELEM_ACCESS_READ, 516 .access = SNDRV_CTL_ELEM_ACCESS_READ,
366 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 517 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -378,12 +529,19 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
378 }, 529 },
379 { 530 {
380 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
381 .name = "Capture Source", 532 .name = "Digital Capture Source",
382 .info = snd_ca0106_capture_source_info, 533 .info = snd_ca0106_capture_source_info,
383 .get = snd_ca0106_capture_source_get, 534 .get = snd_ca0106_capture_source_get,
384 .put = snd_ca0106_capture_source_put 535 .put = snd_ca0106_capture_source_put
385 }, 536 },
386 { 537 {
538 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
539 .name = "Capture Source",
540 .info = snd_ca0106_i2c_capture_source_info,
541 .get = snd_ca0106_i2c_capture_source_get,
542 .put = snd_ca0106_i2c_capture_source_put
543 },
544 {
387 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 545 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
388 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 546 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
389 .count = 4, 547 .count = 4,
@@ -477,7 +635,10 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
477 return err; 635 return err;
478 } 636 }
479 if (emu->details->i2c_adc == 1) { 637 if (emu->details->i2c_adc == 1) {
480 err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu)); 638 if (emu->details->gpio_type == 1)
639 err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
640 else /* gpio_type == 2 */
641 err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_line_in_side_out, emu));
481 if (err < 0) 642 if (err < 0)
482 return err; 643 return err;
483 } 644 }
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
index 63757273bfb7..75ca421eb3a1 100644
--- a/sound/pci/ca0106/ca0106_proc.c
+++ b/sound/pci/ca0106/ca0106_proc.c
@@ -431,33 +431,30 @@ int __devinit snd_ca0106_proc_init(struct snd_ca0106 * emu)
431 struct snd_info_entry *entry; 431 struct snd_info_entry *entry;
432 432
433 if(! snd_card_proc_new(emu->card, "iec958", &entry)) 433 if(! snd_card_proc_new(emu->card, "iec958", &entry))
434 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_iec958); 434 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_iec958);
435 if(! snd_card_proc_new(emu->card, "ca0106_reg32", &entry)) { 435 if(! snd_card_proc_new(emu->card, "ca0106_reg32", &entry)) {
436 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read32); 436 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read32);
437 entry->c.text.write_size = 64;
438 entry->c.text.write = snd_ca0106_proc_reg_write32; 437 entry->c.text.write = snd_ca0106_proc_reg_write32;
439 entry->mode |= S_IWUSR; 438 entry->mode |= S_IWUSR;
440 } 439 }
441 if(! snd_card_proc_new(emu->card, "ca0106_reg16", &entry)) 440 if(! snd_card_proc_new(emu->card, "ca0106_reg16", &entry))
442 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read16); 441 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read16);
443 if(! snd_card_proc_new(emu->card, "ca0106_reg8", &entry)) 442 if(! snd_card_proc_new(emu->card, "ca0106_reg8", &entry))
444 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read8); 443 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read8);
445 if(! snd_card_proc_new(emu->card, "ca0106_regs1", &entry)) { 444 if(! snd_card_proc_new(emu->card, "ca0106_regs1", &entry)) {
446 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read1); 445 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read1);
447 entry->c.text.write_size = 64;
448 entry->c.text.write = snd_ca0106_proc_reg_write; 446 entry->c.text.write = snd_ca0106_proc_reg_write;
449 entry->mode |= S_IWUSR; 447 entry->mode |= S_IWUSR;
450// entry->private_data = emu; 448// entry->private_data = emu;
451 } 449 }
452 if(! snd_card_proc_new(emu->card, "ca0106_i2c", &entry)) { 450 if(! snd_card_proc_new(emu->card, "ca0106_i2c", &entry)) {
453 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_i2c_write); 451 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_i2c_write);
454 entry->c.text.write_size = 64;
455 entry->c.text.write = snd_ca0106_proc_i2c_write; 452 entry->c.text.write = snd_ca0106_proc_i2c_write;
456 entry->mode |= S_IWUSR; 453 entry->mode |= S_IWUSR;
457// entry->private_data = emu; 454// entry->private_data = emu;
458 } 455 }
459 if(! snd_card_proc_new(emu->card, "ca0106_regs2", &entry)) 456 if(! snd_card_proc_new(emu->card, "ca0106_regs2", &entry))
460 snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read2); 457 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read2);
461 return 0; 458 return 0;
462} 459}
463 460
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index e5ce2dabd081..0938c158b5c9 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -2121,7 +2121,7 @@ static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = {
2121 CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7), 2121 CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7),
2122 CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7), 2122 CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7),
2123 CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0), 2123 CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0),
2124 CMIPCI_DOUBLE("PC Speaker Playnack Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0), 2124 CMIPCI_DOUBLE("PC Speaker Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0),
2125 CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0), 2125 CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0),
2126}; 2126};
2127 2127
@@ -2602,7 +2602,7 @@ static void __devinit snd_cmipci_proc_init(struct cmipci *cm)
2602 struct snd_info_entry *entry; 2602 struct snd_info_entry *entry;
2603 2603
2604 if (! snd_card_proc_new(cm->card, "cmipci", &entry)) 2604 if (! snd_card_proc_new(cm->card, "cmipci", &entry))
2605 snd_info_set_text_ops(entry, cm, 1024, snd_cmipci_proc_read); 2605 snd_info_set_text_ops(entry, cm, snd_cmipci_proc_read);
2606} 2606}
2607#else /* !CONFIG_PROC_FS */ 2607#else /* !CONFIG_PROC_FS */
2608static inline void snd_cmipci_proc_init(struct cmipci *cm) {} 2608static inline void snd_cmipci_proc_init(struct cmipci *cm) {}
@@ -2932,7 +2932,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
2932 } 2932 }
2933 2933
2934 integrated_midi = snd_cmipci_read_b(cm, CM_REG_MPU_PCI) != 0xff; 2934 integrated_midi = snd_cmipci_read_b(cm, CM_REG_MPU_PCI) != 0xff;
2935 if (integrated_midi) 2935 if (integrated_midi && mpu_port[dev] == 1)
2936 iomidi = cm->iobase + CM_REG_MPU_PCI; 2936 iomidi = cm->iobase + CM_REG_MPU_PCI;
2937 else { 2937 else {
2938 iomidi = mpu_port[dev]; 2938 iomidi = mpu_port[dev];
@@ -2981,7 +2981,9 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
2981 2981
2982 if (iomidi > 0) { 2982 if (iomidi > 0) {
2983 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, 2983 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
2984 iomidi, integrated_midi, 2984 iomidi,
2985 (integrated_midi ?
2986 MPU401_INFO_INTEGRATED : 0),
2985 cm->irq, 0, &cm->rmidi)) < 0) { 2987 cm->irq, 0, &cm->rmidi)) < 0) {
2986 printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi); 2988 printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi);
2987 } 2989 }
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index b3c94d83450a..e77a4ce314b7 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1184,7 +1184,7 @@ static void __devinit snd_cs4281_proc_init(struct cs4281 * chip)
1184 struct snd_info_entry *entry; 1184 struct snd_info_entry *entry;
1185 1185
1186 if (! snd_card_proc_new(chip->card, "cs4281", &entry)) 1186 if (! snd_card_proc_new(chip->card, "cs4281", &entry))
1187 snd_info_set_text_ops(entry, chip, 1024, snd_cs4281_proc_read); 1187 snd_info_set_text_ops(entry, chip, snd_cs4281_proc_read);
1188 if (! snd_card_proc_new(chip->card, "cs4281_BA0", &entry)) { 1188 if (! snd_card_proc_new(chip->card, "cs4281_BA0", &entry)) {
1189 entry->content = SNDRV_INFO_CONTENT_DATA; 1189 entry->content = SNDRV_INFO_CONTENT_DATA;
1190 entry->private_data = chip; 1190 entry->private_data = chip;
@@ -1379,6 +1379,13 @@ static int __devinit snd_cs4281_create(struct snd_card *card,
1379 chip->ba0_addr = pci_resource_start(pci, 0); 1379 chip->ba0_addr = pci_resource_start(pci, 0);
1380 chip->ba1_addr = pci_resource_start(pci, 1); 1380 chip->ba1_addr = pci_resource_start(pci, 1);
1381 1381
1382 chip->ba0 = ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0));
1383 chip->ba1 = ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1));
1384 if (!chip->ba0 || !chip->ba1) {
1385 snd_cs4281_free(chip);
1386 return -ENOMEM;
1387 }
1388
1382 if (request_irq(pci->irq, snd_cs4281_interrupt, SA_INTERRUPT|SA_SHIRQ, 1389 if (request_irq(pci->irq, snd_cs4281_interrupt, SA_INTERRUPT|SA_SHIRQ,
1383 "CS4281", chip)) { 1390 "CS4281", chip)) {
1384 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1391 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
@@ -1387,13 +1394,6 @@ static int __devinit snd_cs4281_create(struct snd_card *card,
1387 } 1394 }
1388 chip->irq = pci->irq; 1395 chip->irq = pci->irq;
1389 1396
1390 chip->ba0 = ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0));
1391 chip->ba1 = ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1));
1392 if (!chip->ba0 || !chip->ba1) {
1393 snd_cs4281_free(chip);
1394 return -ENOMEM;
1395 }
1396
1397 tmp = snd_cs4281_chip_init(chip); 1397 tmp = snd_cs4281_chip_init(chip);
1398 if (tmp) { 1398 if (tmp) {
1399 snd_cs4281_free(chip); 1399 snd_cs4281_free(chip);
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 848d772ae3c6..772dc52bfeb2 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -48,8 +48,8 @@ MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,Sound Fusion (CS4280)},"
48static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 48static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
49static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 49static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
50static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 50static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
51static int external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 51static int external_amp[SNDRV_CARDS];
52static int thinkpad[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 52static int thinkpad[SNDRV_CARDS];
53static int mmap_valid[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; 53static int mmap_valid[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
54 54
55module_param_array(index, int, NULL, 0444); 55module_param_array(index, int, NULL, 0444);
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 69dbf542a6de..5c2114439204 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -2877,14 +2877,15 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
2877 if (chip->region.idx[0].resource) 2877 if (chip->region.idx[0].resource)
2878 snd_cs46xx_hw_stop(chip); 2878 snd_cs46xx_hw_stop(chip);
2879 2879
2880 if (chip->irq >= 0)
2881 free_irq(chip->irq, chip);
2882
2880 for (idx = 0; idx < 5; idx++) { 2883 for (idx = 0; idx < 5; idx++) {
2881 struct snd_cs46xx_region *region = &chip->region.idx[idx]; 2884 struct snd_cs46xx_region *region = &chip->region.idx[idx];
2882 if (region->remap_addr) 2885 if (region->remap_addr)
2883 iounmap(region->remap_addr); 2886 iounmap(region->remap_addr);
2884 release_and_free_resource(region->resource); 2887 release_and_free_resource(region->resource);
2885 } 2888 }
2886 if (chip->irq >= 0)
2887 free_irq(chip->irq, chip);
2888 2889
2889 if (chip->active_ctrl) 2890 if (chip->active_ctrl)
2890 chip->active_ctrl(chip, -chip->amplifier); 2891 chip->active_ctrl(chip, -chip->amplifier);
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index f407d2a5ce3b..5c9711c0265c 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -767,7 +767,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
767 if ((entry = snd_info_create_card_entry(card, "dsp", card->proc_root)) != NULL) { 767 if ((entry = snd_info_create_card_entry(card, "dsp", card->proc_root)) != NULL) {
768 entry->content = SNDRV_INFO_CONTENT_TEXT; 768 entry->content = SNDRV_INFO_CONTENT_TEXT;
769 entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; 769 entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
770 entry->c.text.read_size = 512;
771 770
772 if (snd_info_register(entry) < 0) { 771 if (snd_info_register(entry) < 0) {
773 snd_info_free_entry(entry); 772 snd_info_free_entry(entry);
@@ -784,7 +783,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
784 entry->content = SNDRV_INFO_CONTENT_TEXT; 783 entry->content = SNDRV_INFO_CONTENT_TEXT;
785 entry->private_data = chip; 784 entry->private_data = chip;
786 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 785 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
787 entry->c.text.read_size = 512;
788 entry->c.text.read = cs46xx_dsp_proc_symbol_table_read; 786 entry->c.text.read = cs46xx_dsp_proc_symbol_table_read;
789 if (snd_info_register(entry) < 0) { 787 if (snd_info_register(entry) < 0) {
790 snd_info_free_entry(entry); 788 snd_info_free_entry(entry);
@@ -797,7 +795,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
797 entry->content = SNDRV_INFO_CONTENT_TEXT; 795 entry->content = SNDRV_INFO_CONTENT_TEXT;
798 entry->private_data = chip; 796 entry->private_data = chip;
799 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 797 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
800 entry->c.text.read_size = 512;
801 entry->c.text.read = cs46xx_dsp_proc_modules_read; 798 entry->c.text.read = cs46xx_dsp_proc_modules_read;
802 if (snd_info_register(entry) < 0) { 799 if (snd_info_register(entry) < 0) {
803 snd_info_free_entry(entry); 800 snd_info_free_entry(entry);
@@ -810,7 +807,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
810 entry->content = SNDRV_INFO_CONTENT_TEXT; 807 entry->content = SNDRV_INFO_CONTENT_TEXT;
811 entry->private_data = chip; 808 entry->private_data = chip;
812 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 809 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
813 entry->c.text.read_size = 512;
814 entry->c.text.read = cs46xx_dsp_proc_parameter_dump_read; 810 entry->c.text.read = cs46xx_dsp_proc_parameter_dump_read;
815 if (snd_info_register(entry) < 0) { 811 if (snd_info_register(entry) < 0) {
816 snd_info_free_entry(entry); 812 snd_info_free_entry(entry);
@@ -823,7 +819,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
823 entry->content = SNDRV_INFO_CONTENT_TEXT; 819 entry->content = SNDRV_INFO_CONTENT_TEXT;
824 entry->private_data = chip; 820 entry->private_data = chip;
825 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 821 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
826 entry->c.text.read_size = 512;
827 entry->c.text.read = cs46xx_dsp_proc_sample_dump_read; 822 entry->c.text.read = cs46xx_dsp_proc_sample_dump_read;
828 if (snd_info_register(entry) < 0) { 823 if (snd_info_register(entry) < 0) {
829 snd_info_free_entry(entry); 824 snd_info_free_entry(entry);
@@ -836,7 +831,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
836 entry->content = SNDRV_INFO_CONTENT_TEXT; 831 entry->content = SNDRV_INFO_CONTENT_TEXT;
837 entry->private_data = chip; 832 entry->private_data = chip;
838 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 833 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
839 entry->c.text.read_size = 512;
840 entry->c.text.read = cs46xx_dsp_proc_task_tree_read; 834 entry->c.text.read = cs46xx_dsp_proc_task_tree_read;
841 if (snd_info_register(entry) < 0) { 835 if (snd_info_register(entry) < 0) {
842 snd_info_free_entry(entry); 836 snd_info_free_entry(entry);
@@ -849,7 +843,6 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
849 entry->content = SNDRV_INFO_CONTENT_TEXT; 843 entry->content = SNDRV_INFO_CONTENT_TEXT;
850 entry->private_data = chip; 844 entry->private_data = chip;
851 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 845 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
852 entry->c.text.read_size = 1024;
853 entry->c.text.read = cs46xx_dsp_proc_scb_read; 846 entry->c.text.read = cs46xx_dsp_proc_scb_read;
854 if (snd_info_register(entry) < 0) { 847 if (snd_info_register(entry) < 0) {
855 snd_info_free_entry(entry); 848 snd_info_free_entry(entry);
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index 2c4ee45fe10c..3844d18af19c 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -267,7 +267,6 @@ void cs46xx_dsp_proc_register_scb_desc (struct snd_cs46xx *chip,
267 entry->private_data = scb_info; 267 entry->private_data = scb_info;
268 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 268 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
269 269
270 entry->c.text.read_size = 512;
271 entry->c.text.read = cs46xx_dsp_proc_scb_info_read; 270 entry->c.text.read = cs46xx_dsp_proc_scb_info_read;
272 271
273 if (snd_info_register(entry) < 0) { 272 if (snd_info_register(entry) < 0) {
diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile
index 08d8ee6547d3..2911a8adc1f2 100644
--- a/sound/pci/cs5535audio/Makefile
+++ b/sound/pci/cs5535audio/Makefile
@@ -4,5 +4,9 @@
4 4
5snd-cs5535audio-objs := cs5535audio.o cs5535audio_pcm.o 5snd-cs5535audio-objs := cs5535audio.o cs5535audio_pcm.o
6 6
7ifdef CONFIG_PM
8snd-cs5535audio-objs += cs5535audio_pm.o
9endif
10
7# Toplevel Module Dependency 11# Toplevel Module Dependency
8obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o 12obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 2c1213a35dcc..91c18a11fe87 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Driver for audio on multifunction CS5535 companion device 2 * Driver for audio on multifunction CS5535/6 companion device
3 * Copyright (C) Jaya Kumar 3 * Copyright (C) Jaya Kumar
4 * 4 *
5 * Based on Jaroslav Kysela and Takashi Iwai's examples. 5 * Based on Jaroslav Kysela and Takashi Iwai's examples.
@@ -40,16 +40,36 @@
40 40
41#define DRIVER_NAME "cs5535audio" 41#define DRIVER_NAME "cs5535audio"
42 42
43static char *ac97_quirk;
44module_param(ac97_quirk, charp, 0444);
45MODULE_PARM_DESC(ac97_quirk, "AC'97 board specific workarounds.");
46
47static struct ac97_quirk ac97_quirks[] __devinitdata = {
48#if 0 /* Not yet confirmed if all 5536 boards are HP only */
49 {
50 .subvendor = PCI_VENDOR_ID_AMD,
51 .subdevice = PCI_DEVICE_ID_AMD_CS5536_AUDIO,
52 .name = "AMD RDK",
53 .type = AC97_TUNE_HP_ONLY
54 },
55#endif
56 {}
57};
43 58
44static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 59static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
45static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 60static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
46static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 61static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
47 62
63module_param_array(index, int, NULL, 0444);
64MODULE_PARM_DESC(index, "Index value for " DRIVER_NAME);
65module_param_array(id, charp, NULL, 0444);
66MODULE_PARM_DESC(id, "ID string for " DRIVER_NAME);
67module_param_array(enable, bool, NULL, 0444);
68MODULE_PARM_DESC(enable, "Enable " DRIVER_NAME);
69
48static struct pci_device_id snd_cs5535audio_ids[] __devinitdata = { 70static struct pci_device_id snd_cs5535audio_ids[] __devinitdata = {
49 { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO, 71 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO) },
50 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, 72 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO) },
51 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO,
52 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
53 {} 73 {}
54}; 74};
55 75
@@ -90,7 +110,8 @@ static unsigned short snd_cs5535audio_codec_read(struct cs5535audio *cs5535au,
90 udelay(1); 110 udelay(1);
91 } while (--timeout); 111 } while (--timeout);
92 if (!timeout) 112 if (!timeout)
93 snd_printk(KERN_ERR "Failure reading cs5535 codec\n"); 113 snd_printk(KERN_ERR "Failure reading codec reg 0x%x,"
114 "Last value=0x%x\n", reg, val);
94 115
95 return (unsigned short) val; 116 return (unsigned short) val;
96} 117}
@@ -148,6 +169,8 @@ static int snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
148 return err; 169 return err;
149 } 170 }
150 171
172 snd_ac97_tune_hardware(cs5535au->ac97, ac97_quirks, ac97_quirk);
173
151 return 0; 174 return 0;
152} 175}
153 176
@@ -347,6 +370,8 @@ static int __devinit snd_cs5535audio_probe(struct pci_dev *pci,
347 if ((err = snd_cs5535audio_create(card, pci, &cs5535au)) < 0) 370 if ((err = snd_cs5535audio_create(card, pci, &cs5535au)) < 0)
348 goto probefail_out; 371 goto probefail_out;
349 372
373 card->private_data = cs5535au;
374
350 if ((err = snd_cs5535audio_mixer(cs5535au)) < 0) 375 if ((err = snd_cs5535audio_mixer(cs5535au)) < 0)
351 goto probefail_out; 376 goto probefail_out;
352 377
@@ -383,6 +408,10 @@ static struct pci_driver driver = {
383 .id_table = snd_cs5535audio_ids, 408 .id_table = snd_cs5535audio_ids,
384 .probe = snd_cs5535audio_probe, 409 .probe = snd_cs5535audio_probe,
385 .remove = __devexit_p(snd_cs5535audio_remove), 410 .remove = __devexit_p(snd_cs5535audio_remove),
411#ifdef CONFIG_PM
412 .suspend = snd_cs5535audio_suspend,
413 .resume = snd_cs5535audio_resume,
414#endif
386}; 415};
387 416
388static int __init alsa_card_cs5535audio_init(void) 417static int __init alsa_card_cs5535audio_init(void)
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index 5e55a1a1ed65..4fd1f31a6cf9 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -74,6 +74,8 @@
74#define PRM_RDY_STS 0x00800000 74#define PRM_RDY_STS 0x00800000
75#define ACC_CODEC_CNTL_WR_CMD (~0x80000000) 75#define ACC_CODEC_CNTL_WR_CMD (~0x80000000)
76#define ACC_CODEC_CNTL_RD_CMD 0x80000000 76#define ACC_CODEC_CNTL_RD_CMD 0x80000000
77#define ACC_CODEC_CNTL_LNK_SHUTDOWN 0x00040000
78#define ACC_CODEC_CNTL_LNK_WRM_RST 0x00020000
77#define PRD_JMP 0x2000 79#define PRD_JMP 0x2000
78#define PRD_EOP 0x4000 80#define PRD_EOP 0x4000
79#define PRD_EOT 0x8000 81#define PRD_EOT 0x8000
@@ -88,6 +90,7 @@ struct cs5535audio_dma_ops {
88 void (*disable_dma)(struct cs5535audio *cs5535au); 90 void (*disable_dma)(struct cs5535audio *cs5535au);
89 void (*pause_dma)(struct cs5535audio *cs5535au); 91 void (*pause_dma)(struct cs5535audio *cs5535au);
90 void (*setup_prd)(struct cs5535audio *cs5535au, u32 prd_addr); 92 void (*setup_prd)(struct cs5535audio *cs5535au, u32 prd_addr);
93 u32 (*read_prd)(struct cs5535audio *cs5535au);
91 u32 (*read_dma_pntr)(struct cs5535audio *cs5535au); 94 u32 (*read_dma_pntr)(struct cs5535audio *cs5535au);
92}; 95};
93 96
@@ -103,11 +106,14 @@ struct cs5535audio_dma {
103 struct snd_pcm_substream *substream; 106 struct snd_pcm_substream *substream;
104 unsigned int buf_addr, buf_bytes; 107 unsigned int buf_addr, buf_bytes;
105 unsigned int period_bytes, periods; 108 unsigned int period_bytes, periods;
109 int suspended;
110 u32 saved_prd;
106}; 111};
107 112
108struct cs5535audio { 113struct cs5535audio {
109 struct snd_card *card; 114 struct snd_card *card;
110 struct snd_ac97 *ac97; 115 struct snd_ac97 *ac97;
116 struct snd_pcm *pcm;
111 int irq; 117 int irq;
112 struct pci_dev *pci; 118 struct pci_dev *pci;
113 unsigned long port; 119 unsigned long port;
@@ -117,6 +123,8 @@ struct cs5535audio {
117 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS]; 123 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS];
118}; 124};
119 125
126int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state);
127int snd_cs5535audio_resume(struct pci_dev *pci);
120int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio); 128int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio);
121 129
122#endif /* __SOUND_CS5535AUDIO_H */ 130#endif /* __SOUND_CS5535AUDIO_H */
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index 60bb82b2ff47..f0a48693d687 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -43,7 +43,8 @@ static struct snd_pcm_hardware snd_cs5535audio_playback =
43 SNDRV_PCM_INFO_BLOCK_TRANSFER | 43 SNDRV_PCM_INFO_BLOCK_TRANSFER |
44 SNDRV_PCM_INFO_MMAP_VALID | 44 SNDRV_PCM_INFO_MMAP_VALID |
45 SNDRV_PCM_INFO_PAUSE | 45 SNDRV_PCM_INFO_PAUSE |
46 SNDRV_PCM_INFO_SYNC_START 46 SNDRV_PCM_INFO_SYNC_START |
47 SNDRV_PCM_INFO_RESUME
47 ), 48 ),
48 .formats = ( 49 .formats = (
49 SNDRV_PCM_FMTBIT_S16_LE 50 SNDRV_PCM_FMTBIT_S16_LE
@@ -193,6 +194,11 @@ static void cs5535audio_playback_setup_prd(struct cs5535audio *cs5535au,
193 cs_writel(cs5535au, ACC_BM0_PRD, prd_addr); 194 cs_writel(cs5535au, ACC_BM0_PRD, prd_addr);
194} 195}
195 196
197static u32 cs5535audio_playback_read_prd(struct cs5535audio *cs5535au)
198{
199 return cs_readl(cs5535au, ACC_BM0_PRD);
200}
201
196static u32 cs5535audio_playback_read_dma_pntr(struct cs5535audio *cs5535au) 202static u32 cs5535audio_playback_read_dma_pntr(struct cs5535audio *cs5535au)
197{ 203{
198 return cs_readl(cs5535au, ACC_BM0_PNTR); 204 return cs_readl(cs5535au, ACC_BM0_PNTR);
@@ -219,6 +225,11 @@ static void cs5535audio_capture_setup_prd(struct cs5535audio *cs5535au,
219 cs_writel(cs5535au, ACC_BM1_PRD, prd_addr); 225 cs_writel(cs5535au, ACC_BM1_PRD, prd_addr);
220} 226}
221 227
228static u32 cs5535audio_capture_read_prd(struct cs5535audio *cs5535au)
229{
230 return cs_readl(cs5535au, ACC_BM1_PRD);
231}
232
222static u32 cs5535audio_capture_read_dma_pntr(struct cs5535audio *cs5535au) 233static u32 cs5535audio_capture_read_dma_pntr(struct cs5535audio *cs5535au)
223{ 234{
224 return cs_readl(cs5535au, ACC_BM1_PNTR); 235 return cs_readl(cs5535au, ACC_BM1_PNTR);
@@ -285,9 +296,17 @@ static int snd_cs5535audio_trigger(struct snd_pcm_substream *substream, int cmd)
285 case SNDRV_PCM_TRIGGER_START: 296 case SNDRV_PCM_TRIGGER_START:
286 dma->ops->enable_dma(cs5535au); 297 dma->ops->enable_dma(cs5535au);
287 break; 298 break;
299 case SNDRV_PCM_TRIGGER_RESUME:
300 dma->ops->enable_dma(cs5535au);
301 dma->suspended = 0;
302 break;
288 case SNDRV_PCM_TRIGGER_STOP: 303 case SNDRV_PCM_TRIGGER_STOP:
289 dma->ops->disable_dma(cs5535au); 304 dma->ops->disable_dma(cs5535au);
290 break; 305 break;
306 case SNDRV_PCM_TRIGGER_SUSPEND:
307 dma->ops->disable_dma(cs5535au);
308 dma->suspended = 1;
309 break;
291 default: 310 default:
292 snd_printk(KERN_ERR "unhandled trigger\n"); 311 snd_printk(KERN_ERR "unhandled trigger\n");
293 err = -EINVAL; 312 err = -EINVAL;
@@ -375,6 +394,7 @@ static struct cs5535audio_dma_ops snd_cs5535audio_playback_dma_ops = {
375 .enable_dma = cs5535audio_playback_enable_dma, 394 .enable_dma = cs5535audio_playback_enable_dma,
376 .disable_dma = cs5535audio_playback_disable_dma, 395 .disable_dma = cs5535audio_playback_disable_dma,
377 .setup_prd = cs5535audio_playback_setup_prd, 396 .setup_prd = cs5535audio_playback_setup_prd,
397 .read_prd = cs5535audio_playback_read_prd,
378 .pause_dma = cs5535audio_playback_pause_dma, 398 .pause_dma = cs5535audio_playback_pause_dma,
379 .read_dma_pntr = cs5535audio_playback_read_dma_pntr, 399 .read_dma_pntr = cs5535audio_playback_read_dma_pntr,
380}; 400};
@@ -384,6 +404,7 @@ static struct cs5535audio_dma_ops snd_cs5535audio_capture_dma_ops = {
384 .enable_dma = cs5535audio_capture_enable_dma, 404 .enable_dma = cs5535audio_capture_enable_dma,
385 .disable_dma = cs5535audio_capture_disable_dma, 405 .disable_dma = cs5535audio_capture_disable_dma,
386 .setup_prd = cs5535audio_capture_setup_prd, 406 .setup_prd = cs5535audio_capture_setup_prd,
407 .read_prd = cs5535audio_capture_read_prd,
387 .pause_dma = cs5535audio_capture_pause_dma, 408 .pause_dma = cs5535audio_capture_pause_dma,
388 .read_dma_pntr = cs5535audio_capture_read_dma_pntr, 409 .read_dma_pntr = cs5535audio_capture_read_dma_pntr,
389}; 410};
@@ -413,6 +434,7 @@ int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535au)
413 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 434 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
414 snd_dma_pci_data(cs5535au->pci), 435 snd_dma_pci_data(cs5535au->pci),
415 64*1024, 128*1024); 436 64*1024, 128*1024);
437 cs5535au->pcm = pcm;
416 438
417 return 0; 439 return 0;
418} 440}
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
new file mode 100644
index 000000000000..aad0e69db9c1
--- /dev/null
+++ b/sound/pci/cs5535audio/cs5535audio_pm.c
@@ -0,0 +1,123 @@
1/*
2 * Power management for audio on multifunction CS5535 companion device
3 * Copyright (C) Jaya Kumar
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <linux/init.h>
22#include <linux/slab.h>
23#include <linux/pci.h>
24#include <linux/delay.h>
25#include <sound/driver.h>
26#include <sound/core.h>
27#include <sound/control.h>
28#include <sound/initval.h>
29#include <sound/asoundef.h>
30#include <sound/pcm.h>
31#include <sound/ac97_codec.h>
32#include "cs5535audio.h"
33
34static void snd_cs5535audio_stop_hardware(struct cs5535audio *cs5535au)
35{
36 /*
37 we depend on snd_ac97_suspend to tell the
38 AC97 codec to shutdown. the amd spec suggests
39 that the LNK_SHUTDOWN be done at the same time
40 that the codec power-down is issued. instead,
41 we do it just after rather than at the same
42 time. excluding codec specific build_ops->suspend
43 ac97 powerdown hits:
44 0x8000 EAPD
45 0x4000 Headphone amplifier
46 0x0300 ADC & DAC
47 0x0400 Analog Mixer powerdown (Vref on)
48 I am not sure if this is the best that we can do.
49 The remainder to be investigated are:
50 - analog mixer (vref off) 0x0800
51 - AC-link powerdown 0x1000
52 - codec internal clock 0x2000
53 */
54
55 /* set LNK_SHUTDOWN to shutdown AC link */
56 cs_writel(cs5535au, ACC_CODEC_CNTL, ACC_CODEC_CNTL_LNK_SHUTDOWN);
57
58}
59
60int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state)
61{
62 struct snd_card *card = pci_get_drvdata(pci);
63 struct cs5535audio *cs5535au = card->private_data;
64 int i;
65
66 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
67 for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
68 struct cs5535audio_dma *dma = &cs5535au->dmas[i];
69 if (dma && dma->substream && !dma->suspended)
70 dma->saved_prd = dma->ops->read_prd(cs5535au);
71 }
72 snd_pcm_suspend_all(cs5535au->pcm);
73 snd_ac97_suspend(cs5535au->ac97);
74 /* save important regs, then disable aclink in hw */
75 snd_cs5535audio_stop_hardware(cs5535au);
76 pci_disable_device(pci);
77 pci_save_state(pci);
78
79 return 0;
80}
81
82int snd_cs5535audio_resume(struct pci_dev *pci)
83{
84 struct snd_card *card = pci_get_drvdata(pci);
85 struct cs5535audio *cs5535au = card->private_data;
86 u32 tmp;
87 int timeout;
88 int i;
89
90 pci_restore_state(pci);
91 pci_enable_device(pci);
92 pci_set_master(pci);
93
94 /* set LNK_WRM_RST to reset AC link */
95 cs_writel(cs5535au, ACC_CODEC_CNTL, ACC_CODEC_CNTL_LNK_WRM_RST);
96
97 timeout = 50;
98 do {
99 tmp = cs_readl(cs5535au, ACC_CODEC_STATUS);
100 if (tmp & PRM_RDY_STS)
101 break;
102 udelay(1);
103 } while (--timeout);
104
105 if (!timeout)
106 snd_printk(KERN_ERR "Failure getting AC Link ready\n");
107
108 /* we depend on ac97 to perform the codec power up */
109 snd_ac97_resume(cs5535au->ac97);
110 /* set up rate regs, dma. actual initiation is done in trig */
111 for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
112 struct cs5535audio_dma *dma = &cs5535au->dmas[i];
113 if (dma && dma->substream && dma->suspended) {
114 dma->substream->ops->prepare(dma->substream);
115 dma->ops->setup_prd(cs5535au, dma->saved_prd);
116 }
117 }
118
119 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
120
121 return 0;
122}
123
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 42b11ba1d210..549673ea14a9 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -46,13 +46,13 @@ MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB Live!/PCI512/E-mu APS},"
46static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 46static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
47static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 47static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
48static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 48static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
49static int extin[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 49static int extin[SNDRV_CARDS];
50static int extout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 50static int extout[SNDRV_CARDS];
51static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4}; 51static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4};
52static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64}; 52static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64};
53static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128}; 53static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
54static int enable_ir[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 54static int enable_ir[SNDRV_CARDS];
55static uint subsystem[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* Force card subsystem model */ 55static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
56 56
57module_param_array(index, int, NULL, 0444); 57module_param_array(index, int, NULL, 0444);
58MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard."); 58MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard.");
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 6bfa08436efa..42a358f989c3 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -777,14 +777,6 @@ static int snd_emu10k1_dev_free(struct snd_device *device)
777 777
778static struct snd_emu_chip_details emu_chip_details[] = { 778static struct snd_emu_chip_details emu_chip_details[] = {
779 /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/ 779 /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/
780 /* Audigy4 SB0400 */
781 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102,
782 .driver = "Audigy2", .name = "Audigy 4 [SB0400]",
783 .id = "Audigy2",
784 .emu10k2_chip = 1,
785 .ca0108_chip = 1,
786 .spk71 = 1,
787 .ac97_chip = 1} ,
788 /* Tested by James@superbug.co.uk 3rd July 2005 */ 780 /* Tested by James@superbug.co.uk 3rd July 2005 */
789 /* DSP: CA0108-IAT 781 /* DSP: CA0108-IAT
790 * DAC: CS4382-KQ 782 * DAC: CS4382-KQ
@@ -799,13 +791,59 @@ static struct snd_emu_chip_details emu_chip_details[] = {
799 .ca0108_chip = 1, 791 .ca0108_chip = 1,
800 .spk71 = 1, 792 .spk71 = 1,
801 .ac97_chip = 1} , 793 .ac97_chip = 1} ,
794 /* Audigy4 (Not PRO) SB0610 */
795 /* Tested by James@superbug.co.uk 4th April 2006 */
796 /* A_IOCFG bits
797 * Output
798 * 0: ?
799 * 1: ?
800 * 2: ?
801 * 3: 0 - Digital Out, 1 - Line in
802 * 4: ?
803 * 5: ?
804 * 6: ?
805 * 7: ?
806 * Input
807 * 8: ?
808 * 9: ?
809 * A: Green jack sense (Front)
810 * B: ?
811 * C: Black jack sense (Rear/Side Right)
812 * D: Yellow jack sense (Center/LFE/Side Left)
813 * E: ?
814 * F: ?
815 *
816 * Digital Out/Line in switch using A_IOCFG bit 3 (0x08)
817 * 0 - Digital Out
818 * 1 - Line in
819 */
820 /* Mic input not tested.
821 * Analog CD input not tested
822 * Digital Out not tested.
823 * Line in working.
824 * Audio output 5.1 working. Side outputs not working.
825 */
826 /* DSP: CA10300-IAT LF
827 * DAC: Cirrus Logic CS4382-KQZ
828 * ADC: Philips 1361T
829 * AC97: Sigmatel STAC9750
830 * CA0151: None
831 */
832 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102,
833 .driver = "Audigy2", .name = "Audigy 4 [SB0610]",
834 .id = "Audigy2",
835 .emu10k2_chip = 1,
836 .ca0108_chip = 1,
837 .spk71 = 1,
838 .adc_1361t = 1, /* 24 bit capture instead of 16bit */
839 .ac97_chip = 1} ,
802 /* Audigy 2 ZS Notebook Cardbus card.*/ 840 /* Audigy 2 ZS Notebook Cardbus card.*/
803 /* Tested by James@superbug.co.uk 22th December 2005 */ 841 /* Tested by James@superbug.co.uk 22th December 2005 */
804 /* Audio output 7.1/Headphones working. 842 /* Audio output 7.1/Headphones working.
805 * Digital output working. (AC3 not checked, only PCM) 843 * Digital output working. (AC3 not checked, only PCM)
806 * Audio inputs not tested. 844 * Audio inputs not tested.
807 */ 845 */
808 /* DSP: Tiny2 846 /* DSP: Tina2
809 * DAC: Wolfson WM8768/WM8568 847 * DAC: Wolfson WM8768/WM8568
810 * ADC: Wolfson WM8775 848 * ADC: Wolfson WM8775
811 * AC97: None 849 * AC97: None
@@ -1421,16 +1459,3 @@ void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
1421 } 1459 }
1422} 1460}
1423#endif 1461#endif
1424
1425/* memory.c */
1426EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
1427EXPORT_SYMBOL(snd_emu10k1_synth_free);
1428EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
1429EXPORT_SYMBOL(snd_emu10k1_synth_copy_from_user);
1430EXPORT_SYMBOL(snd_emu10k1_memblk_map);
1431/* voice.c */
1432EXPORT_SYMBOL(snd_emu10k1_voice_alloc);
1433EXPORT_SYMBOL(snd_emu10k1_voice_free);
1434/* io.c */
1435EXPORT_SYMBOL(snd_emu10k1_ptr_read);
1436EXPORT_SYMBOL(snd_emu10k1_ptr_write);
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index d51290c18167..0fb27e4be07b 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -1055,8 +1055,7 @@ static int __devinit snd_emu10k1x_proc_init(struct emu10k1x * emu)
1055 struct snd_info_entry *entry; 1055 struct snd_info_entry *entry;
1056 1056
1057 if(! snd_card_proc_new(emu->card, "emu10k1x_regs", &entry)) { 1057 if(! snd_card_proc_new(emu->card, "emu10k1x_regs", &entry)) {
1058 snd_info_set_text_ops(entry, emu, 1024, snd_emu10k1x_proc_reg_read); 1058 snd_info_set_text_ops(entry, emu, snd_emu10k1x_proc_reg_read);
1059 entry->c.text.write_size = 64;
1060 entry->c.text.write = snd_emu10k1x_proc_reg_write; 1059 entry->c.text.write = snd_emu10k1x_proc_reg_write;
1061 entry->mode |= S_IWUSR; 1060 entry->mode |= S_IWUSR;
1062 entry->private_data = emu; 1061 entry->private_data = emu;
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 2a9d12d10680..c31f3d0877fa 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -777,6 +777,8 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
777 }; 777 };
778 static char *audigy_remove_ctls[] = { 778 static char *audigy_remove_ctls[] = {
779 /* Master/PCM controls on ac97 of Audigy has no effect */ 779 /* Master/PCM controls on ac97 of Audigy has no effect */
780 /* On the Audigy2 the AC97 playback is piped into
781 * the Philips ADC for 24bit capture */
780 "PCM Playback Switch", 782 "PCM Playback Switch",
781 "PCM Playback Volume", 783 "PCM Playback Volume",
782 "Master Mono Playback Switch", 784 "Master Mono Playback Switch",
@@ -804,6 +806,47 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
804 "AMic Playback Volume", "Mic Playback Volume", 806 "AMic Playback Volume", "Mic Playback Volume",
805 NULL 807 NULL
806 }; 808 };
809 static char *audigy_remove_ctls_1361t_adc[] = {
810 /* On the Audigy2 the AC97 playback is piped into
811 * the Philips ADC for 24bit capture */
812 "PCM Playback Switch",
813 "PCM Playback Volume",
814 "Master Mono Playback Switch",
815 "Master Mono Playback Volume",
816 "Capture Source",
817 "Capture Switch",
818 "Capture Volume",
819 "Mic Capture Volume",
820 "Headphone Playback Switch",
821 "Headphone Playback Volume",
822 "3D Control - Center",
823 "3D Control - Depth",
824 "3D Control - Switch",
825 "Line2 Playback Volume",
826 "Line2 Capture Volume",
827 NULL
828 };
829 static char *audigy_rename_ctls_1361t_adc[] = {
830 "Master Playback Switch", "Master Capture Switch",
831 "Master Playback Volume", "Master Capture Volume",
832 "Wave Master Playback Volume", "Master Playback Volume",
833 "PC Speaker Playback Switch", "PC Speaker Capture Switch",
834 "PC Speaker Playback Volume", "PC Speaker Capture Volume",
835 "Phone Playback Switch", "Phone Capture Switch",
836 "Phone Playback Volume", "Phone Capture Volume",
837 "Mic Playback Switch", "Mic Capture Switch",
838 "Mic Playback Volume", "Mic Capture Volume",
839 "Line Playback Switch", "Line Capture Switch",
840 "Line Playback Volume", "Line Capture Volume",
841 "CD Playback Switch", "CD Capture Switch",
842 "CD Playback Volume", "CD Capture Volume",
843 "Aux Playback Switch", "Aux Capture Switch",
844 "Aux Playback Volume", "Aux Capture Volume",
845 "Video Playback Switch", "Video Capture Switch",
846 "Video Playback Volume", "Video Capture Volume",
847
848 NULL
849 };
807 850
808 if (emu->card_capabilities->ac97_chip) { 851 if (emu->card_capabilities->ac97_chip) {
809 struct snd_ac97_bus *pbus; 852 struct snd_ac97_bus *pbus;
@@ -834,7 +877,10 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
834 snd_ac97_write_cache(emu->ac97, AC97_MASTER, 0x0000); 877 snd_ac97_write_cache(emu->ac97, AC97_MASTER, 0x0000);
835 /* set capture source to mic */ 878 /* set capture source to mic */
836 snd_ac97_write_cache(emu->ac97, AC97_REC_SEL, 0x0000); 879 snd_ac97_write_cache(emu->ac97, AC97_REC_SEL, 0x0000);
837 c = audigy_remove_ctls; 880 if (emu->card_capabilities->adc_1361t)
881 c = audigy_remove_ctls_1361t_adc;
882 else
883 c = audigy_remove_ctls;
838 } else { 884 } else {
839 /* 885 /*
840 * Credits for cards based on STAC9758: 886 * Credits for cards based on STAC9758:
@@ -863,11 +909,15 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
863 } 909 }
864 910
865 if (emu->audigy) 911 if (emu->audigy)
866 c = audigy_rename_ctls; 912 if (emu->card_capabilities->adc_1361t)
913 c = audigy_rename_ctls_1361t_adc;
914 else
915 c = audigy_rename_ctls;
867 else 916 else
868 c = emu10k1_rename_ctls; 917 c = emu10k1_rename_ctls;
869 for (; *c; c += 2) 918 for (; *c; c += 2)
870 rename_ctl(card, c[0], c[1]); 919 rename_ctl(card, c[0], c[1]);
920
871 if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */ 921 if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */
872 rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume"); 922 rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume");
873 rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume"); 923 rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume");
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index 90f1c52703a1..b939e03aaedf 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -532,57 +532,51 @@ int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu)
532 struct snd_info_entry *entry; 532 struct snd_info_entry *entry;
533#ifdef CONFIG_SND_DEBUG 533#ifdef CONFIG_SND_DEBUG
534 if (! snd_card_proc_new(emu->card, "io_regs", &entry)) { 534 if (! snd_card_proc_new(emu->card, "io_regs", &entry)) {
535 snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_io_reg_read); 535 snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read);
536 entry->c.text.write_size = 64;
537 entry->c.text.write = snd_emu_proc_io_reg_write; 536 entry->c.text.write = snd_emu_proc_io_reg_write;
538 entry->mode |= S_IWUSR; 537 entry->mode |= S_IWUSR;
539 } 538 }
540 if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) { 539 if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) {
541 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00a); 540 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read00a);
542 entry->c.text.write_size = 64;
543 entry->c.text.write = snd_emu_proc_ptr_reg_write00; 541 entry->c.text.write = snd_emu_proc_ptr_reg_write00;
544 entry->mode |= S_IWUSR; 542 entry->mode |= S_IWUSR;
545 } 543 }
546 if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) { 544 if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) {
547 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00b); 545 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read00b);
548 entry->c.text.write_size = 64;
549 entry->c.text.write = snd_emu_proc_ptr_reg_write00; 546 entry->c.text.write = snd_emu_proc_ptr_reg_write00;
550 entry->mode |= S_IWUSR; 547 entry->mode |= S_IWUSR;
551 } 548 }
552 if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) { 549 if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) {
553 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20a); 550 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20a);
554 entry->c.text.write_size = 64;
555 entry->c.text.write = snd_emu_proc_ptr_reg_write20; 551 entry->c.text.write = snd_emu_proc_ptr_reg_write20;
556 entry->mode |= S_IWUSR; 552 entry->mode |= S_IWUSR;
557 } 553 }
558 if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) { 554 if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) {
559 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20b); 555 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20b);
560 entry->c.text.write_size = 64;
561 entry->c.text.write = snd_emu_proc_ptr_reg_write20; 556 entry->c.text.write = snd_emu_proc_ptr_reg_write20;
562 entry->mode |= S_IWUSR; 557 entry->mode |= S_IWUSR;
563 } 558 }
564 if (! snd_card_proc_new(emu->card, "ptr_regs20c", &entry)) { 559 if (! snd_card_proc_new(emu->card, "ptr_regs20c", &entry)) {
565 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20c); 560 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20c);
566 entry->c.text.write_size = 64;
567 entry->c.text.write = snd_emu_proc_ptr_reg_write20; 561 entry->c.text.write = snd_emu_proc_ptr_reg_write20;
568 entry->mode |= S_IWUSR; 562 entry->mode |= S_IWUSR;
569 } 563 }
570#endif 564#endif
571 565
572 if (! snd_card_proc_new(emu->card, "emu10k1", &entry)) 566 if (! snd_card_proc_new(emu->card, "emu10k1", &entry))
573 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_read); 567 snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_read);
574 568
575 if (emu->card_capabilities->emu10k2_chip) { 569 if (emu->card_capabilities->emu10k2_chip) {
576 if (! snd_card_proc_new(emu->card, "spdif-in", &entry)) 570 if (! snd_card_proc_new(emu->card, "spdif-in", &entry))
577 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_spdif_read); 571 snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_spdif_read);
578 } 572 }
579 if (emu->card_capabilities->ca0151_chip) { 573 if (emu->card_capabilities->ca0151_chip) {
580 if (! snd_card_proc_new(emu->card, "capture-rates", &entry)) 574 if (! snd_card_proc_new(emu->card, "capture-rates", &entry))
581 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_rates_read); 575 snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_rates_read);
582 } 576 }
583 577
584 if (! snd_card_proc_new(emu->card, "voices", &entry)) 578 if (! snd_card_proc_new(emu->card, "voices", &entry))
585 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_voices_read); 579 snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_voices_read);
586 580
587 if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) { 581 if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) {
588 entry->content = SNDRV_INFO_CONTENT_DATA; 582 entry->content = SNDRV_INFO_CONTENT_DATA;
@@ -616,7 +610,6 @@ int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu)
616 entry->content = SNDRV_INFO_CONTENT_TEXT; 610 entry->content = SNDRV_INFO_CONTENT_TEXT;
617 entry->private_data = emu; 611 entry->private_data = emu;
618 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; 612 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
619 entry->c.text.read_size = 128*1024;
620 entry->c.text.read = snd_emu10k1_proc_acode_read; 613 entry->c.text.read = snd_emu10k1_proc_acode_read;
621 } 614 }
622 return 0; 615 return 0;
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index ef5304df8c11..029e7856c43b 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -62,6 +62,8 @@ unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, un
62 } 62 }
63} 63}
64 64
65EXPORT_SYMBOL(snd_emu10k1_ptr_read);
66
65void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data) 67void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data)
66{ 68{
67 unsigned int regptr; 69 unsigned int regptr;
@@ -92,6 +94,8 @@ void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned i
92 } 94 }
93} 95}
94 96
97EXPORT_SYMBOL(snd_emu10k1_ptr_write);
98
95unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, 99unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu,
96 unsigned int reg, 100 unsigned int reg,
97 unsigned int chn) 101 unsigned int chn)
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index e7ec98649f04..4fcaefe5a3c5 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -287,6 +287,8 @@ int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *b
287 return err; 287 return err;
288} 288}
289 289
290EXPORT_SYMBOL(snd_emu10k1_memblk_map);
291
290/* 292/*
291 * page allocation for DMA 293 * page allocation for DMA
292 */ 294 */
@@ -387,6 +389,7 @@ snd_emu10k1_synth_alloc(struct snd_emu10k1 *hw, unsigned int size)
387 return (struct snd_util_memblk *)blk; 389 return (struct snd_util_memblk *)blk;
388} 390}
389 391
392EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
390 393
391/* 394/*
392 * free a synth sample area 395 * free a synth sample area
@@ -409,6 +412,7 @@ snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *memblk)
409 return 0; 412 return 0;
410} 413}
411 414
415EXPORT_SYMBOL(snd_emu10k1_synth_free);
412 416
413/* check new allocation range */ 417/* check new allocation range */
414static void get_single_page_range(struct snd_util_memhdr *hdr, 418static void get_single_page_range(struct snd_util_memhdr *hdr,
@@ -540,6 +544,8 @@ int snd_emu10k1_synth_bzero(struct snd_emu10k1 *emu, struct snd_util_memblk *blk
540 return 0; 544 return 0;
541} 545}
542 546
547EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
548
543/* 549/*
544 * copy_from_user(blk + offset, data, size) 550 * copy_from_user(blk + offset, data, size)
545 */ 551 */
@@ -568,3 +574,5 @@ int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_me
568 } while (offset < end_offset); 574 } while (offset < end_offset);
569 return 0; 575 return 0;
570} 576}
577
578EXPORT_SYMBOL(snd_emu10k1_synth_copy_from_user);
diff --git a/sound/pci/emu10k1/p17v.h b/sound/pci/emu10k1/p17v.h
new file mode 100644
index 000000000000..7ddb5be632cf
--- /dev/null
+++ b/sound/pci/emu10k1/p17v.h
@@ -0,0 +1,111 @@
1/*
2 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver p17v chips
4 * Version: 0.01
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22/******************************************************************************/
23/* Audigy2Value Tina (P17V) pointer-offset register set,
24 * accessed through the PTR20 and DATA24 registers */
25/******************************************************************************/
26
27/* 00 - 07: Not used */
28#define P17V_PLAYBACK_FIFO_PTR 0x08 /* Current playback fifo pointer
29 * and number of sound samples in cache.
30 */
31/* 09 - 12: Not used */
32#define P17V_CAPTURE_FIFO_PTR 0x13 /* Current capture fifo pointer
33 * and number of sound samples in cache.
34 */
35/* 14 - 17: Not used */
36#define P17V_PB_CHN_SEL 0x18 /* P17v playback channel select */
37#define P17V_SE_SLOT_SEL_L 0x19 /* Sound Engine slot select low */
38#define P17V_SE_SLOT_SEL_H 0x1a /* Sound Engine slot select high */
39/* 1b - 1f: Not used */
40/* 20 - 2f: Not used */
41/* 30 - 3b: Not used */
42#define P17V_SPI 0x3c /* SPI interface register */
43#define P17V_I2C_ADDR 0x3d /* I2C Address */
44#define P17V_I2C_0 0x3e /* I2C Data */
45#define P17V_I2C_1 0x3f /* I2C Data */
46
47#define P17V_START_AUDIO 0x40 /* Start Audio bit */
48/* 41 - 47: Reserved */
49#define P17V_START_CAPTURE 0x48 /* Start Capture bit */
50#define P17V_CAPTURE_FIFO_BASE 0x49 /* Record FIFO base address */
51#define P17V_CAPTURE_FIFO_SIZE 0x4a /* Record FIFO buffer size */
52#define P17V_CAPTURE_FIFO_INDEX 0x4b /* Record FIFO capture index */
53#define P17V_CAPTURE_VOL_H 0x4c /* P17v capture volume control */
54#define P17V_CAPTURE_VOL_L 0x4d /* P17v capture volume control */
55/* 4e - 4f: Not used */
56/* 50 - 5f: Not used */
57#define P17V_SRCSel 0x60 /* SRC48 and SRCMulti sample rate select
58 * and output select
59 */
60#define P17V_MIXER_AC97_10K1_VOL_L 0x61 /* 10K to Mixer_AC97 input volume control */
61#define P17V_MIXER_AC97_10K1_VOL_H 0x62 /* 10K to Mixer_AC97 input volume control */
62#define P17V_MIXER_AC97_P17V_VOL_L 0x63 /* P17V to Mixer_AC97 input volume control */
63#define P17V_MIXER_AC97_P17V_VOL_H 0x64 /* P17V to Mixer_AC97 input volume control */
64#define P17V_MIXER_AC97_SRP_REC_VOL_L 0x65 /* SRP Record to Mixer_AC97 input volume control */
65#define P17V_MIXER_AC97_SRP_REC_VOL_H 0x66 /* SRP Record to Mixer_AC97 input volume control */
66/* 67 - 68: Reserved */
67#define P17V_MIXER_Spdif_10K1_VOL_L 0x69 /* 10K to Mixer_Spdif input volume control */
68#define P17V_MIXER_Spdif_10K1_VOL_H 0x6A /* 10K to Mixer_Spdif input volume control */
69#define P17V_MIXER_Spdif_P17V_VOL_L 0x6B /* P17V to Mixer_Spdif input volume control */
70#define P17V_MIXER_Spdif_P17V_VOL_H 0x6C /* P17V to Mixer_Spdif input volume control */
71#define P17V_MIXER_Spdif_SRP_REC_VOL_L 0x6D /* SRP Record to Mixer_Spdif input volume control */
72#define P17V_MIXER_Spdif_SRP_REC_VOL_H 0x6E /* SRP Record to Mixer_Spdif input volume control */
73/* 6f - 70: Reserved */
74#define P17V_MIXER_I2S_10K1_VOL_L 0x71 /* 10K to Mixer_I2S input volume control */
75#define P17V_MIXER_I2S_10K1_VOL_H 0x72 /* 10K to Mixer_I2S input volume control */
76#define P17V_MIXER_I2S_P17V_VOL_L 0x73 /* P17V to Mixer_I2S input volume control */
77#define P17V_MIXER_I2S_P17V_VOL_H 0x74 /* P17V to Mixer_I2S input volume control */
78#define P17V_MIXER_I2S_SRP_REC_VOL_L 0x75 /* SRP Record to Mixer_I2S input volume control */
79#define P17V_MIXER_I2S_SRP_REC_VOL_H 0x76 /* SRP Record to Mixer_I2S input volume control */
80/* 77 - 78: Reserved */
81#define P17V_MIXER_AC97_ENABLE 0x79 /* Mixer AC97 input audio enable */
82#define P17V_MIXER_SPDIF_ENABLE 0x7A /* Mixer SPDIF input audio enable */
83#define P17V_MIXER_I2S_ENABLE 0x7B /* Mixer I2S input audio enable */
84#define P17V_AUDIO_OUT_ENABLE 0x7C /* Audio out enable */
85#define P17V_MIXER_ATT 0x7D /* SRP Mixer Attenuation Select */
86#define P17V_SRP_RECORD_SRR 0x7E /* SRP Record channel source Select */
87#define P17V_SOFT_RESET_SRP_MIXER 0x7F /* SRP and mixer soft reset */
88
89#define P17V_AC97_OUT_MASTER_VOL_L 0x80 /* AC97 Output master volume control */
90#define P17V_AC97_OUT_MASTER_VOL_H 0x81 /* AC97 Output master volume control */
91#define P17V_SPDIF_OUT_MASTER_VOL_L 0x82 /* SPDIF Output master volume control */
92#define P17V_SPDIF_OUT_MASTER_VOL_H 0x83 /* SPDIF Output master volume control */
93#define P17V_I2S_OUT_MASTER_VOL_L 0x84 /* I2S Output master volume control */
94#define P17V_I2S_OUT_MASTER_VOL_H 0x85 /* I2S Output master volume control */
95/* 86 - 87: Not used */
96#define P17V_I2S_CHANNEL_SWAP_PHASE_INVERSE 0x88 /* I2S out mono channel swap
97 * and phase inverse */
98#define P17V_SPDIF_CHANNEL_SWAP_PHASE_INVERSE 0x89 /* SPDIF out mono channel swap
99 * and phase inverse */
100/* 8A: Not used */
101#define P17V_SRP_P17V_ESR 0x8B /* SRP_P17V estimated sample rate and rate lock */
102#define P17V_SRP_REC_ESR 0x8C /* SRP_REC estimated sample rate and rate lock */
103#define P17V_SRP_BYPASS 0x8D /* srps channel bypass and srps bypass */
104/* 8E - 92: Not used */
105#define P17V_I2S_SRC_SEL 0x93 /* I2SIN mode sel */
106
107
108
109
110
111
diff --git a/sound/pci/emu10k1/tina2.h b/sound/pci/emu10k1/tina2.h
index 5c43abf03e89..f2d8eb6c89e1 100644
--- a/sound/pci/emu10k1/tina2.h
+++ b/sound/pci/emu10k1/tina2.h
@@ -1,11 +1,7 @@
1/* 1/*
2 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk> 2 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver p16v chips 3 * Driver tina2 chips
4 * Version: 0.21 4 * Version: 0.1
5 *
6 *
7 * This code was initally based on code from ALSA's emu10k1x.c which is:
8 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
9 * 5 *
10 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c
index 56ffb7dc3ee2..94eca82dd4fc 100644
--- a/sound/pci/emu10k1/voice.c
+++ b/sound/pci/emu10k1/voice.c
@@ -139,6 +139,8 @@ int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int number,
139 return result; 139 return result;
140} 140}
141 141
142EXPORT_SYMBOL(snd_emu10k1_voice_alloc);
143
142int snd_emu10k1_voice_free(struct snd_emu10k1 *emu, 144int snd_emu10k1_voice_free(struct snd_emu10k1 *emu,
143 struct snd_emu10k1_voice *pvoice) 145 struct snd_emu10k1_voice *pvoice)
144{ 146{
@@ -153,3 +155,5 @@ int snd_emu10k1_voice_free(struct snd_emu10k1 *emu,
153 spin_unlock_irqrestore(&emu->voice_lock, flags); 155 spin_unlock_irqrestore(&emu->voice_lock, flags);
154 return 0; 156 return 0;
155} 157}
158
159EXPORT_SYMBOL(snd_emu10k1_voice_free);
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index ca9e34e88f62..9d46bbee2a40 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -1915,7 +1915,7 @@ static void __devinit snd_ensoniq_proc_init(struct ensoniq * ensoniq)
1915 struct snd_info_entry *entry; 1915 struct snd_info_entry *entry;
1916 1916
1917 if (! snd_card_proc_new(ensoniq->card, "audiopci", &entry)) 1917 if (! snd_card_proc_new(ensoniq->card, "audiopci", &entry))
1918 snd_info_set_text_ops(entry, ensoniq, 1024, snd_ensoniq_proc_read); 1918 snd_info_set_text_ops(entry, ensoniq, snd_ensoniq_proc_read);
1919} 1919}
1920 1920
1921/* 1921/*
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 6f9094ca4fb4..ca6603fe0b11 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1756,7 +1756,8 @@ static int __devinit snd_es1938_probe(struct pci_dev *pci,
1756 } 1756 }
1757 } 1757 }
1758 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 1758 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
1759 chip->mpu_port, 1, chip->irq, 0, &chip->rmidi) < 0) { 1759 chip->mpu_port, MPU401_INFO_INTEGRATED,
1760 chip->irq, 0, &chip->rmidi) < 0) {
1760 printk(KERN_ERR "es1938: unable to initialize MPU-401\n"); 1761 printk(KERN_ERR "es1938: unable to initialize MPU-401\n");
1761 } else { 1762 } else {
1762 // this line is vital for MIDI interrupt handling on ess-solo1 1763 // this line is vital for MIDI interrupt handling on ess-solo1
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 5ff4175c7b6d..bfa0876e715e 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -132,7 +132,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
132static int total_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1024 }; 132static int total_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1024 };
133static int pcm_substreams_p[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4 }; 133static int pcm_substreams_p[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4 };
134static int pcm_substreams_c[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1 }; 134static int pcm_substreams_c[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1 };
135static int clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 135static int clock[SNDRV_CARDS];
136static int use_pm[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; 136static int use_pm[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
137static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; 137static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
138#ifdef SUPPORT_JOYSTICK 138#ifdef SUPPORT_JOYSTICK
@@ -2727,7 +2727,8 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci,
2727 } 2727 }
2728 if (enable_mpu[dev]) { 2728 if (enable_mpu[dev]) {
2729 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 2729 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
2730 chip->io_port + ESM_MPU401_PORT, 1, 2730 chip->io_port + ESM_MPU401_PORT,
2731 MPU401_INFO_INTEGRATED,
2731 chip->irq, 0, &chip->rmidi)) < 0) { 2732 chip->irq, 0, &chip->rmidi)) < 0) {
2732 printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n"); 2733 printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n");
2733 } 2734 }
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index d72fc28c580e..0afa573dd244 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -56,7 +56,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
56 * 3 = MediaForte 64-PCR 56 * 3 = MediaForte 64-PCR
57 * High 16-bits are video (radio) device number + 1 57 * High 16-bits are video (radio) device number + 1
58 */ 58 */
59static int tea575x_tuner[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; 59static int tea575x_tuner[SNDRV_CARDS];
60 60
61module_param_array(index, int, NULL, 0444); 61module_param_array(index, int, NULL, 0444);
62MODULE_PARM_DESC(index, "Index value for the FM801 soundcard."); 62MODULE_PARM_DESC(index, "Index value for the FM801 soundcard.");
@@ -1448,7 +1448,8 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
1448 return err; 1448 return err;
1449 } 1449 }
1450 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801, 1450 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801,
1451 FM801_REG(chip, MPU401_DATA), 1, 1451 FM801_REG(chip, MPU401_DATA),
1452 MPU401_INFO_INTEGRATED,
1452 chip->irq, 0, &chip->rmidi)) < 0) { 1453 chip->irq, 0, &chip->rmidi)) < 0) {
1453 snd_card_free(card); 1454 snd_card_free(card);
1454 return err; 1455 return err;
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index ddfb5ff7fb8f..dbacba6177db 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,5 +1,5 @@
1snd-hda-intel-objs := hda_intel.o 1snd-hda-intel-objs := hda_intel.o
2snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o patch_si3054.o 2snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o patch_si3054.o patch_atihdmi.o
3ifdef CONFIG_PROC_FS 3ifdef CONFIG_PROC_FS
4snd-hda-codec-objs += hda_proc.o 4snd-hda-codec-objs += hda_proc.o
5endif 5endif
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 5bee3b536478..8c2a8174ece1 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -86,6 +86,8 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int dire
86 return res; 86 return res;
87} 87}
88 88
89EXPORT_SYMBOL(snd_hda_codec_read);
90
89/** 91/**
90 * snd_hda_codec_write - send a single command without waiting for response 92 * snd_hda_codec_write - send a single command without waiting for response
91 * @codec: the HDA codec 93 * @codec: the HDA codec
@@ -108,6 +110,8 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
108 return err; 110 return err;
109} 111}
110 112
113EXPORT_SYMBOL(snd_hda_codec_write);
114
111/** 115/**
112 * snd_hda_sequence_write - sequence writes 116 * snd_hda_sequence_write - sequence writes
113 * @codec: the HDA codec 117 * @codec: the HDA codec
@@ -122,6 +126,8 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
122 snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param); 126 snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
123} 127}
124 128
129EXPORT_SYMBOL(snd_hda_sequence_write);
130
125/** 131/**
126 * snd_hda_get_sub_nodes - get the range of sub nodes 132 * snd_hda_get_sub_nodes - get the range of sub nodes
127 * @codec: the HDA codec 133 * @codec: the HDA codec
@@ -140,6 +146,8 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *sta
140 return (int)(parm & 0x7fff); 146 return (int)(parm & 0x7fff);
141} 147}
142 148
149EXPORT_SYMBOL(snd_hda_get_sub_nodes);
150
143/** 151/**
144 * snd_hda_get_connections - get connection list 152 * snd_hda_get_connections - get connection list
145 * @codec: the HDA codec 153 * @codec: the HDA codec
@@ -256,6 +264,8 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
256 return 0; 264 return 0;
257} 265}
258 266
267EXPORT_SYMBOL(snd_hda_queue_unsol_event);
268
259/* 269/*
260 * process queueud unsolicited events 270 * process queueud unsolicited events
261 */ 271 */
@@ -384,6 +394,7 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
384 return 0; 394 return 0;
385} 395}
386 396
397EXPORT_SYMBOL(snd_hda_bus_new);
387 398
388/* 399/*
389 * find a matching codec preset 400 * find a matching codec preset
@@ -587,6 +598,8 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
587 return 0; 598 return 0;
588} 599}
589 600
601EXPORT_SYMBOL(snd_hda_codec_new);
602
590/** 603/**
591 * snd_hda_codec_setup_stream - set up the codec for streaming 604 * snd_hda_codec_setup_stream - set up the codec for streaming
592 * @codec: the CODEC to set up 605 * @codec: the CODEC to set up
@@ -609,6 +622,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stre
609 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format); 622 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format);
610} 623}
611 624
625EXPORT_SYMBOL(snd_hda_codec_setup_stream);
612 626
613/* 627/*
614 * amp access functions 628 * amp access functions
@@ -1294,6 +1308,7 @@ int snd_hda_build_controls(struct hda_bus *bus)
1294 return 0; 1308 return 0;
1295} 1309}
1296 1310
1311EXPORT_SYMBOL(snd_hda_build_controls);
1297 1312
1298/* 1313/*
1299 * stream formats 1314 * stream formats
@@ -1382,6 +1397,8 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
1382 return val; 1397 return val;
1383} 1398}
1384 1399
1400EXPORT_SYMBOL(snd_hda_calc_stream_format);
1401
1385/** 1402/**
1386 * snd_hda_query_supported_pcm - query the supported PCM rates and formats 1403 * snd_hda_query_supported_pcm - query the supported PCM rates and formats
1387 * @codec: the HDA codec 1404 * @codec: the HDA codec
@@ -1663,6 +1680,7 @@ int snd_hda_build_pcms(struct hda_bus *bus)
1663 return 0; 1680 return 0;
1664} 1681}
1665 1682
1683EXPORT_SYMBOL(snd_hda_build_pcms);
1666 1684
1667/** 1685/**
1668 * snd_hda_check_board_config - compare the current codec with the config table 1686 * snd_hda_check_board_config - compare the current codec with the config table
@@ -2165,6 +2183,8 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
2165 return 0; 2183 return 0;
2166} 2184}
2167 2185
2186EXPORT_SYMBOL(snd_hda_suspend);
2187
2168/** 2188/**
2169 * snd_hda_resume - resume the codecs 2189 * snd_hda_resume - resume the codecs
2170 * @bus: the HDA bus 2190 * @bus: the HDA bus
@@ -2187,6 +2207,8 @@ int snd_hda_resume(struct hda_bus *bus)
2187 return 0; 2207 return 0;
2188} 2208}
2189 2209
2210EXPORT_SYMBOL(snd_hda_resume);
2211
2190/** 2212/**
2191 * snd_hda_resume_ctls - resume controls in the new control list 2213 * snd_hda_resume_ctls - resume controls in the new control list
2192 * @codec: the HDA codec 2214 * @codec: the HDA codec
@@ -2247,25 +2269,6 @@ int snd_hda_resume_spdif_in(struct hda_codec *codec)
2247#endif 2269#endif
2248 2270
2249/* 2271/*
2250 * symbols exported for controller modules
2251 */
2252EXPORT_SYMBOL(snd_hda_codec_read);
2253EXPORT_SYMBOL(snd_hda_codec_write);
2254EXPORT_SYMBOL(snd_hda_sequence_write);
2255EXPORT_SYMBOL(snd_hda_get_sub_nodes);
2256EXPORT_SYMBOL(snd_hda_queue_unsol_event);
2257EXPORT_SYMBOL(snd_hda_bus_new);
2258EXPORT_SYMBOL(snd_hda_codec_new);
2259EXPORT_SYMBOL(snd_hda_codec_setup_stream);
2260EXPORT_SYMBOL(snd_hda_calc_stream_format);
2261EXPORT_SYMBOL(snd_hda_build_pcms);
2262EXPORT_SYMBOL(snd_hda_build_controls);
2263#ifdef CONFIG_PM
2264EXPORT_SYMBOL(snd_hda_suspend);
2265EXPORT_SYMBOL(snd_hda_resume);
2266#endif
2267
2268/*
2269 * INIT part 2272 * INIT part
2270 */ 2273 */
2271 2274
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index e821d65afa11..4070b5cd9b6b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -82,6 +82,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
82 "{Intel, ICH8}," 82 "{Intel, ICH8},"
83 "{ATI, SB450}," 83 "{ATI, SB450},"
84 "{ATI, SB600}," 84 "{ATI, SB600},"
85 "{ATI, RS600},"
85 "{VIA, VT8251}," 86 "{VIA, VT8251},"
86 "{VIA, VT8237A}," 87 "{VIA, VT8237A},"
87 "{SiS, SIS966}," 88 "{SiS, SIS966},"
@@ -167,6 +168,12 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
167#define ULI_PLAYBACK_INDEX 5 168#define ULI_PLAYBACK_INDEX 5
168#define ULI_NUM_PLAYBACK 6 169#define ULI_NUM_PLAYBACK 6
169 170
171/* ATI HDMI has 1 playback and 0 capture */
172#define ATIHDMI_CAPTURE_INDEX 0
173#define ATIHDMI_NUM_CAPTURE 0
174#define ATIHDMI_PLAYBACK_INDEX 0
175#define ATIHDMI_NUM_PLAYBACK 1
176
170/* this number is statically defined for simplicity */ 177/* this number is statically defined for simplicity */
171#define MAX_AZX_DEV 16 178#define MAX_AZX_DEV 16
172 179
@@ -331,6 +338,7 @@ struct azx {
331enum { 338enum {
332 AZX_DRIVER_ICH, 339 AZX_DRIVER_ICH,
333 AZX_DRIVER_ATI, 340 AZX_DRIVER_ATI,
341 AZX_DRIVER_ATIHDMI,
334 AZX_DRIVER_VIA, 342 AZX_DRIVER_VIA,
335 AZX_DRIVER_SIS, 343 AZX_DRIVER_SIS,
336 AZX_DRIVER_ULI, 344 AZX_DRIVER_ULI,
@@ -340,6 +348,7 @@ enum {
340static char *driver_short_names[] __devinitdata = { 348static char *driver_short_names[] __devinitdata = {
341 [AZX_DRIVER_ICH] = "HDA Intel", 349 [AZX_DRIVER_ICH] = "HDA Intel",
342 [AZX_DRIVER_ATI] = "HDA ATI SB", 350 [AZX_DRIVER_ATI] = "HDA ATI SB",
351 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
343 [AZX_DRIVER_VIA] = "HDA VIA VT82xx", 352 [AZX_DRIVER_VIA] = "HDA VIA VT82xx",
344 [AZX_DRIVER_SIS] = "HDA SIS966", 353 [AZX_DRIVER_SIS] = "HDA SIS966",
345 [AZX_DRIVER_ULI] = "HDA ULI M5461", 354 [AZX_DRIVER_ULI] = "HDA ULI M5461",
@@ -1393,10 +1402,10 @@ static int azx_free(struct azx *chip)
1393 msleep(1); 1402 msleep(1);
1394 } 1403 }
1395 1404
1396 if (chip->remap_addr)
1397 iounmap(chip->remap_addr);
1398 if (chip->irq >= 0) 1405 if (chip->irq >= 0)
1399 free_irq(chip->irq, (void*)chip); 1406 free_irq(chip->irq, (void*)chip);
1407 if (chip->remap_addr)
1408 iounmap(chip->remap_addr);
1400 1409
1401 if (chip->bdl.area) 1410 if (chip->bdl.area)
1402 snd_dma_free_pages(&chip->bdl); 1411 snd_dma_free_pages(&chip->bdl);
@@ -1495,6 +1504,12 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
1495 chip->playback_index_offset = ULI_PLAYBACK_INDEX; 1504 chip->playback_index_offset = ULI_PLAYBACK_INDEX;
1496 chip->capture_index_offset = ULI_CAPTURE_INDEX; 1505 chip->capture_index_offset = ULI_CAPTURE_INDEX;
1497 break; 1506 break;
1507 case AZX_DRIVER_ATIHDMI:
1508 chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
1509 chip->capture_streams = ATIHDMI_NUM_CAPTURE;
1510 chip->playback_index_offset = ATIHDMI_PLAYBACK_INDEX;
1511 chip->capture_index_offset = ATIHDMI_CAPTURE_INDEX;
1512 break;
1498 default: 1513 default:
1499 chip->playback_streams = ICH6_NUM_PLAYBACK; 1514 chip->playback_streams = ICH6_NUM_PLAYBACK;
1500 chip->capture_streams = ICH6_NUM_CAPTURE; 1515 chip->capture_streams = ICH6_NUM_CAPTURE;
@@ -1621,6 +1636,7 @@ static struct pci_device_id azx_ids[] __devinitdata = {
1621 { 0x8086, 0x284b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH8 */ 1636 { 0x8086, 0x284b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH8 */
1622 { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */ 1637 { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */
1623 { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */ 1638 { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */
1639 { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */
1624 { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ 1640 { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
1625 { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ 1641 { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
1626 { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ 1642 { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h
index acaef3c811b8..0b668793face 100644
--- a/sound/pci/hda/hda_patch.h
+++ b/sound/pci/hda/hda_patch.h
@@ -12,6 +12,8 @@ extern struct hda_codec_preset snd_hda_preset_analog[];
12extern struct hda_codec_preset snd_hda_preset_sigmatel[]; 12extern struct hda_codec_preset snd_hda_preset_sigmatel[];
13/* SiLabs 3054/3055 modem codecs */ 13/* SiLabs 3054/3055 modem codecs */
14extern struct hda_codec_preset snd_hda_preset_si3054[]; 14extern struct hda_codec_preset snd_hda_preset_si3054[];
15/* ATI HDMI codecs */
16extern struct hda_codec_preset snd_hda_preset_atihdmi[];
15 17
16static const struct hda_codec_preset *hda_preset_tables[] = { 18static const struct hda_codec_preset *hda_preset_tables[] = {
17 snd_hda_preset_realtek, 19 snd_hda_preset_realtek,
@@ -19,5 +21,6 @@ static const struct hda_codec_preset *hda_preset_tables[] = {
19 snd_hda_preset_analog, 21 snd_hda_preset_analog,
20 snd_hda_preset_sigmatel, 22 snd_hda_preset_sigmatel,
21 snd_hda_preset_si3054, 23 snd_hda_preset_si3054,
24 snd_hda_preset_atihdmi,
22 NULL 25 NULL
23}; 26};
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index ca514a6a5875..c2f0fe85bf35 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -182,6 +182,10 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
182 snd_iprintf(buffer, " OUT"); 182 snd_iprintf(buffer, " OUT");
183 if (caps & AC_PINCAP_HP_DRV) 183 if (caps & AC_PINCAP_HP_DRV)
184 snd_iprintf(buffer, " HP"); 184 snd_iprintf(buffer, " HP");
185 if (caps & AC_PINCAP_EAPD)
186 snd_iprintf(buffer, " EAPD");
187 if (caps & AC_PINCAP_PRES_DETECT)
188 snd_iprintf(buffer, " Detect");
185 snd_iprintf(buffer, "\n"); 189 snd_iprintf(buffer, "\n");
186 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); 190 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
187 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps, 191 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
@@ -318,7 +322,7 @@ int snd_hda_codec_proc_new(struct hda_codec *codec)
318 if (err < 0) 322 if (err < 0)
319 return err; 323 return err;
320 324
321 snd_info_set_text_ops(entry, codec, 32 * 1024, print_codec_info); 325 snd_info_set_text_ops(entry, codec, print_codec_info);
322 return 0; 326 return 0;
323} 327}
324 328
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 40f000ba1362..dd4e00a82b55 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -789,6 +789,8 @@ static struct hda_board_config ad1986a_cfg_tbl[] = {
789 { .modelname = "3stack", .config = AD1986A_3STACK }, 789 { .modelname = "3stack", .config = AD1986A_3STACK },
790 { .pci_subvendor = 0x10de, .pci_subdevice = 0xcb84, 790 { .pci_subvendor = 0x10de, .pci_subdevice = 0xcb84,
791 .config = AD1986A_3STACK }, /* ASUS A8N-VM CSM */ 791 .config = AD1986A_3STACK }, /* ASUS A8N-VM CSM */
792 { .pci_subvendor = 0x1043, .pci_subdevice = 0x81b3,
793 .config = AD1986A_3STACK }, /* ASUS P5RD2-VM / P5GPL-X SE */
792 { .modelname = "laptop", .config = AD1986A_LAPTOP }, 794 { .modelname = "laptop", .config = AD1986A_LAPTOP },
793 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc01e, 795 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc01e,
794 .config = AD1986A_LAPTOP }, /* FSC V2060 */ 796 .config = AD1986A_LAPTOP }, /* FSC V2060 */
@@ -809,6 +811,8 @@ static struct hda_board_config ad1986a_cfg_tbl[] = {
809 .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */ 811 .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */
810 { .pci_subvendor = 0x103c, .pci_subdevice = 0x30af, 812 { .pci_subvendor = 0x103c, .pci_subdevice = 0x30af,
811 .config = AD1986A_LAPTOP_EAPD }, /* HP Compaq Presario B2800 */ 813 .config = AD1986A_LAPTOP_EAPD }, /* HP Compaq Presario B2800 */
814 { .pci_subvendor = 0x17aa, .pci_subdevice = 0x2066,
815 .config = AD1986A_LAPTOP_EAPD }, /* Lenovo 3000 N100-07684JU */
812 {} 816 {}
813}; 817};
814 818
@@ -963,7 +967,7 @@ static struct snd_kcontrol_new ad1983_mixers[] = {
963 }, 967 },
964 { 968 {
965 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 969 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
966 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", 970 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
967 .info = ad1983_spdif_route_info, 971 .info = ad1983_spdif_route_info,
968 .get = ad1983_spdif_route_get, 972 .get = ad1983_spdif_route_get,
969 .put = ad1983_spdif_route_put, 973 .put = ad1983_spdif_route_put,
@@ -1103,7 +1107,7 @@ static struct snd_kcontrol_new ad1981_mixers[] = {
1103 /* identical with AD1983 */ 1107 /* identical with AD1983 */
1104 { 1108 {
1105 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1109 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1106 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", 1110 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1107 .info = ad1983_spdif_route_info, 1111 .info = ad1983_spdif_route_info,
1108 .get = ad1983_spdif_route_get, 1112 .get = ad1983_spdif_route_get,
1109 .put = ad1983_spdif_route_put, 1113 .put = ad1983_spdif_route_put,
@@ -1329,13 +1333,60 @@ static int ad1981_hp_init(struct hda_codec *codec)
1329 return 0; 1333 return 0;
1330} 1334}
1331 1335
1336/* configuration for Lenovo Thinkpad T60 */
1337static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1338 HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1339 HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1340 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1341 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1342 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1343 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1344 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1345 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1346 HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT),
1347 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1348 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1349 {
1350 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1351 .name = "Capture Source",
1352 .info = ad198x_mux_enum_info,
1353 .get = ad198x_mux_enum_get,
1354 .put = ad198x_mux_enum_put,
1355 },
1356 /* identical with AD1983 */
1357 {
1358 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1359 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1360 .info = ad1983_spdif_route_info,
1361 .get = ad1983_spdif_route_get,
1362 .put = ad1983_spdif_route_put,
1363 },
1364 { } /* end */
1365};
1366
1367static struct hda_input_mux ad1981_thinkpad_capture_source = {
1368 .num_items = 3,
1369 .items = {
1370 { "Mic", 0x0 },
1371 { "Mix", 0x2 },
1372 { "CD", 0x4 },
1373 },
1374};
1375
1332/* models */ 1376/* models */
1333enum { AD1981_BASIC, AD1981_HP }; 1377enum { AD1981_BASIC, AD1981_HP, AD1981_THINKPAD };
1334 1378
1335static struct hda_board_config ad1981_cfg_tbl[] = { 1379static struct hda_board_config ad1981_cfg_tbl[] = {
1336 { .modelname = "hp", .config = AD1981_HP }, 1380 { .modelname = "hp", .config = AD1981_HP },
1337 /* All HP models */ 1381 /* All HP models */
1338 { .pci_subvendor = 0x103c, .config = AD1981_HP }, 1382 { .pci_subvendor = 0x103c, .config = AD1981_HP },
1383 { .pci_subvendor = 0x30b0, .pci_subdevice = 0x103c,
1384 .config = AD1981_HP }, /* HP nx6320 (reversed SSID, H/W bug) */
1385 { .modelname = "thinkpad", .config = AD1981_THINKPAD },
1386 /* Lenovo Thinkpad T60/X60/Z6xx */
1387 { .pci_subvendor = 0x17aa, .config = AD1981_THINKPAD },
1388 { .pci_subvendor = 0x1014, .pci_subdevice = 0x0597,
1389 .config = AD1981_THINKPAD }, /* Z60m/t */
1339 { .modelname = "basic", .config = AD1981_BASIC }, 1390 { .modelname = "basic", .config = AD1981_BASIC },
1340 {} 1391 {}
1341}; 1392};
@@ -1381,6 +1432,10 @@ static int patch_ad1981(struct hda_codec *codec)
1381 codec->patch_ops.init = ad1981_hp_init; 1432 codec->patch_ops.init = ad1981_hp_init;
1382 codec->patch_ops.unsol_event = ad1981_hp_unsol_event; 1433 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1383 break; 1434 break;
1435 case AD1981_THINKPAD:
1436 spec->mixers[0] = ad1981_thinkpad_mixers;
1437 spec->input_mux = &ad1981_thinkpad_capture_source;
1438 break;
1384 } 1439 }
1385 1440
1386 return 0; 1441 return 0;
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
new file mode 100644
index 000000000000..a27440ffd1c8
--- /dev/null
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -0,0 +1,165 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ATI HDMI codecs
5 *
6 * Copyright (c) 2006 ATI Technologies Inc.
7 *
8 *
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <sound/driver.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/slab.h>
28#include <linux/pci.h>
29#include <sound/core.h>
30#include "hda_codec.h"
31#include "hda_local.h"
32
33struct atihdmi_spec {
34 struct hda_multi_out multiout;
35
36 struct hda_pcm pcm_rec;
37};
38
39static struct hda_verb atihdmi_basic_init[] = {
40 /* enable digital output on pin widget */
41 { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
42 {} /* terminator */
43};
44
45/*
46 * Controls
47 */
48static int atihdmi_build_controls(struct hda_codec *codec)
49{
50 struct atihdmi_spec *spec = codec->spec;
51 int err;
52
53 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
54 if (err < 0)
55 return err;
56
57 return 0;
58}
59
60static int atihdmi_init(struct hda_codec *codec)
61{
62 snd_hda_sequence_write(codec, atihdmi_basic_init);
63 return 0;
64}
65
66#ifdef CONFIG_PM
67/*
68 * resume
69 */
70static int atihdmi_resume(struct hda_codec *codec)
71{
72 atihdmi_init(codec);
73 snd_hda_resume_spdif_out(codec);
74
75 return 0;
76}
77#endif
78
79/*
80 * Digital out
81 */
82static int atihdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
83 struct hda_codec *codec,
84 struct snd_pcm_substream *substream)
85{
86 struct atihdmi_spec *spec = codec->spec;
87 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
88}
89
90static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
91 struct hda_codec *codec,
92 struct snd_pcm_substream *substream)
93{
94 struct atihdmi_spec *spec = codec->spec;
95 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
96}
97
98static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
99 .substreams = 1,
100 .channels_min = 2,
101 .channels_max = 2,
102 .nid = 0x2, /* NID to query formats and rates and setup streams */
103 .ops = {
104 .open = atihdmi_dig_playback_pcm_open,
105 .close = atihdmi_dig_playback_pcm_close
106 },
107};
108
109static int atihdmi_build_pcms(struct hda_codec *codec)
110{
111 struct atihdmi_spec *spec = codec->spec;
112 struct hda_pcm *info = &spec->pcm_rec;
113
114 codec->num_pcms = 1;
115 codec->pcm_info = info;
116
117 info->name = "ATI HDMI";
118 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = atihdmi_pcm_digital_playback;
119
120 return 0;
121}
122
123static void atihdmi_free(struct hda_codec *codec)
124{
125 kfree(codec->spec);
126}
127
128static struct hda_codec_ops atihdmi_patch_ops = {
129 .build_controls = atihdmi_build_controls,
130 .build_pcms = atihdmi_build_pcms,
131 .init = atihdmi_init,
132 .free = atihdmi_free,
133#ifdef CONFIG_PM
134 .resume = atihdmi_resume,
135#endif
136};
137
138static int patch_atihdmi(struct hda_codec *codec)
139{
140 struct atihdmi_spec *spec;
141
142 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
143 if (spec == NULL)
144 return -ENOMEM;
145
146 codec->spec = spec;
147
148 spec->multiout.num_dacs = 0; /* no analog */
149 spec->multiout.max_channels = 2;
150 spec->multiout.dig_out_nid = 0x2; /* NID for copying analog to digital,
151 * seems to be unused in pure-digital
152 * case. */
153
154 codec->patch_ops = atihdmi_patch_ops;
155
156 return 0;
157}
158
159/*
160 * patch entries
161 */
162struct hda_codec_preset snd_hda_preset_atihdmi[] = {
163 { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
164 {} /* terminator */
165};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index f0e9a9c90780..98b9f16c26ff 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2174,6 +2174,7 @@ static struct hda_board_config alc880_cfg_tbl[] = {
2174 2174
2175 { .modelname = "lg", .config = ALC880_LG }, 2175 { .modelname = "lg", .config = ALC880_LG },
2176 { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG }, 2176 { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG },
2177 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0068, .config = ALC880_LG },
2177 2178
2178 { .modelname = "lg-lw", .config = ALC880_LG_LW }, 2179 { .modelname = "lg-lw", .config = ALC880_LG_LW },
2179 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW }, 2180 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW },
@@ -3105,6 +3106,7 @@ static struct hda_verb alc260_init_verbs[] = {
3105 { } 3106 { }
3106}; 3107};
3107 3108
3109#if 0 /* should be identical with alc260_init_verbs? */
3108static struct hda_verb alc260_hp_init_verbs[] = { 3110static struct hda_verb alc260_hp_init_verbs[] = {
3109 /* Headphone and output */ 3111 /* Headphone and output */
3110 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 3112 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
@@ -3151,6 +3153,7 @@ static struct hda_verb alc260_hp_init_verbs[] = {
3151 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3153 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3152 { } 3154 { }
3153}; 3155};
3156#endif
3154 3157
3155static struct hda_verb alc260_hp_3013_init_verbs[] = { 3158static struct hda_verb alc260_hp_3013_init_verbs[] = {
3156 /* Line out and output */ 3159 /* Line out and output */
@@ -3822,12 +3825,16 @@ static struct hda_board_config alc260_cfg_tbl[] = {
3822 { .modelname = "basic", .config = ALC260_BASIC }, 3825 { .modelname = "basic", .config = ALC260_BASIC },
3823 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb, 3826 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb,
3824 .config = ALC260_BASIC }, /* Sony VAIO */ 3827 .config = ALC260_BASIC }, /* Sony VAIO */
3828 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cc,
3829 .config = ALC260_BASIC }, /* Sony VAIO VGN-S3HP */
3830 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cd,
3831 .config = ALC260_BASIC }, /* Sony VAIO */
3825 { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729, 3832 { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729,
3826 .config = ALC260_BASIC }, /* CTL Travel Master U553W */ 3833 .config = ALC260_BASIC }, /* CTL Travel Master U553W */
3827 { .modelname = "hp", .config = ALC260_HP }, 3834 { .modelname = "hp", .config = ALC260_HP },
3828 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP }, 3835 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP },
3829 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, 3836 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP },
3830 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP }, 3837 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP_3013 },
3831 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 }, 3838 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 },
3832 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP }, 3839 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP },
3833 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP }, 3840 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP },
@@ -3862,7 +3869,7 @@ static struct alc_config_preset alc260_presets[] = {
3862 .mixers = { alc260_base_output_mixer, 3869 .mixers = { alc260_base_output_mixer,
3863 alc260_input_mixer, 3870 alc260_input_mixer,
3864 alc260_capture_alt_mixer }, 3871 alc260_capture_alt_mixer },
3865 .init_verbs = { alc260_hp_init_verbs }, 3872 .init_verbs = { alc260_init_verbs },
3866 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 3873 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
3867 .dac_nids = alc260_dac_nids, 3874 .dac_nids = alc260_dac_nids,
3868 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 3875 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
@@ -4094,21 +4101,6 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
4094 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 4101 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4095 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 4102 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4096 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 4103 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4097 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
4098 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
4099 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
4100 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
4101 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
4102 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
4103 {
4104 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4105 /* .name = "Capture Source", */
4106 .name = "Input Source",
4107 .count = 3,
4108 .info = alc882_mux_enum_info,
4109 .get = alc882_mux_enum_get,
4110 .put = alc882_mux_enum_put,
4111 },
4112 { } /* end */ 4104 { } /* end */
4113}; 4105};
4114 4106
@@ -4342,8 +4334,6 @@ static struct alc_config_preset alc882_presets[] = {
4342 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 4334 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
4343 .dac_nids = alc882_dac_nids, 4335 .dac_nids = alc882_dac_nids,
4344 .dig_out_nid = ALC882_DIGOUT_NID, 4336 .dig_out_nid = ALC882_DIGOUT_NID,
4345 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
4346 .adc_nids = alc882_adc_nids,
4347 .dig_in_nid = ALC882_DIGIN_NID, 4337 .dig_in_nid = ALC882_DIGIN_NID,
4348 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 4338 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
4349 .channel_mode = alc882_ch_modes, 4339 .channel_mode = alc882_ch_modes,
@@ -4355,8 +4345,6 @@ static struct alc_config_preset alc882_presets[] = {
4355 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 4345 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
4356 .dac_nids = alc882_dac_nids, 4346 .dac_nids = alc882_dac_nids,
4357 .dig_out_nid = ALC882_DIGOUT_NID, 4347 .dig_out_nid = ALC882_DIGOUT_NID,
4358 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
4359 .adc_nids = alc882_adc_nids,
4360 .dig_in_nid = ALC882_DIGIN_NID, 4348 .dig_in_nid = ALC882_DIGIN_NID,
4361 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 4349 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
4362 .channel_mode = alc882_sixstack_modes, 4350 .channel_mode = alc882_sixstack_modes,
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 8c440fb98603..36f199442fdc 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -41,6 +41,7 @@
41#define STAC_REF 0 41#define STAC_REF 0
42#define STAC_D945GTP3 1 42#define STAC_D945GTP3 1
43#define STAC_D945GTP5 2 43#define STAC_D945GTP5 2
44#define STAC_MACMINI 3
44 45
45struct sigmatel_spec { 46struct sigmatel_spec {
46 struct snd_kcontrol_new *mixers[4]; 47 struct snd_kcontrol_new *mixers[4];
@@ -52,6 +53,7 @@ struct sigmatel_spec {
52 unsigned int mic_switch: 1; 53 unsigned int mic_switch: 1;
53 unsigned int alt_switch: 1; 54 unsigned int alt_switch: 1;
54 unsigned int hp_detect: 1; 55 unsigned int hp_detect: 1;
56 unsigned int gpio_mute: 1;
55 57
56 /* playback */ 58 /* playback */
57 struct hda_multi_out multiout; 59 struct hda_multi_out multiout;
@@ -293,6 +295,7 @@ static unsigned int *stac922x_brd_tbl[] = {
293 ref922x_pin_configs, 295 ref922x_pin_configs,
294 d945gtp3_pin_configs, 296 d945gtp3_pin_configs,
295 d945gtp5_pin_configs, 297 d945gtp5_pin_configs,
298 NULL, /* STAC_MACMINI */
296}; 299};
297 300
298static struct hda_board_config stac922x_cfg_tbl[] = { 301static struct hda_board_config stac922x_cfg_tbl[] = {
@@ -324,6 +327,9 @@ static struct hda_board_config stac922x_cfg_tbl[] = {
324 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 327 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
325 .pci_subdevice = 0x0417, 328 .pci_subdevice = 0x0417,
326 .config = STAC_D945GTP5 }, /* Intel D975XBK - 5 Stack */ 329 .config = STAC_D945GTP5 }, /* Intel D975XBK - 5 Stack */
330 { .pci_subvendor = 0x8384,
331 .pci_subdevice = 0x7680,
332 .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */
327 {} /* terminator */ 333 {} /* terminator */
328}; 334};
329 335
@@ -841,6 +847,19 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
841 } 847 }
842 } 848 }
843 849
850 if (imux->num_items == 1) {
851 /*
852 * Set the current input for the muxes.
853 * The STAC9221 has two input muxes with identical source
854 * NID lists. Hopefully this won't get confused.
855 */
856 for (i = 0; i < spec->num_muxes; i++) {
857 snd_hda_codec_write(codec, spec->mux_nids[i], 0,
858 AC_VERB_SET_CONNECT_SEL,
859 imux->items[0].index);
860 }
861 }
862
844 return 0; 863 return 0;
845} 864}
846 865
@@ -946,6 +965,45 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
946 return 1; 965 return 1;
947} 966}
948 967
968/*
969 * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a
970 * funky external mute control using GPIO pins.
971 */
972
973static void stac922x_gpio_mute(struct hda_codec *codec, int pin, int muted)
974{
975 unsigned int gpiostate, gpiomask, gpiodir;
976
977 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
978 AC_VERB_GET_GPIO_DATA, 0);
979
980 if (!muted)
981 gpiostate |= (1 << pin);
982 else
983 gpiostate &= ~(1 << pin);
984
985 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
986 AC_VERB_GET_GPIO_MASK, 0);
987 gpiomask |= (1 << pin);
988
989 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
990 AC_VERB_GET_GPIO_DIRECTION, 0);
991 gpiodir |= (1 << pin);
992
993 /* AppleHDA seems to do this -- WTF is this verb?? */
994 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0);
995
996 snd_hda_codec_write(codec, codec->afg, 0,
997 AC_VERB_SET_GPIO_MASK, gpiomask);
998 snd_hda_codec_write(codec, codec->afg, 0,
999 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1000
1001 msleep(1);
1002
1003 snd_hda_codec_write(codec, codec->afg, 0,
1004 AC_VERB_SET_GPIO_DATA, gpiostate);
1005}
1006
949static int stac92xx_init(struct hda_codec *codec) 1007static int stac92xx_init(struct hda_codec *codec)
950{ 1008{
951 struct sigmatel_spec *spec = codec->spec; 1009 struct sigmatel_spec *spec = codec->spec;
@@ -982,6 +1040,11 @@ static int stac92xx_init(struct hda_codec *codec)
982 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, 1040 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
983 AC_PINCTL_IN_EN); 1041 AC_PINCTL_IN_EN);
984 1042
1043 if (spec->gpio_mute) {
1044 stac922x_gpio_mute(codec, 0, 0);
1045 stac922x_gpio_mute(codec, 1, 0);
1046 }
1047
985 return 0; 1048 return 0;
986} 1049}
987 1050
@@ -1132,7 +1195,7 @@ static int patch_stac922x(struct hda_codec *codec)
1132 spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); 1195 spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl);
1133 if (spec->board_config < 0) 1196 if (spec->board_config < 0)
1134 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, using BIOS defaults\n"); 1197 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, using BIOS defaults\n");
1135 else { 1198 else if (stac922x_brd_tbl[spec->board_config] != NULL) {
1136 spec->num_pins = 10; 1199 spec->num_pins = 10;
1137 spec->pin_nids = stac922x_pin_nids; 1200 spec->pin_nids = stac922x_pin_nids;
1138 spec->pin_configs = stac922x_brd_tbl[spec->board_config]; 1201 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
@@ -1154,6 +1217,9 @@ static int patch_stac922x(struct hda_codec *codec)
1154 return err; 1217 return err;
1155 } 1218 }
1156 1219
1220 if (spec->board_config == STAC_MACMINI)
1221 spec->gpio_mute = 1;
1222
1157 codec->patch_ops = stac92xx_patch_ops; 1223 codec->patch_ops = stac92xx_patch_ops;
1158 1224
1159 return 0; 1225 return 0;
@@ -1262,13 +1328,13 @@ static int vaio_master_sw_put(struct snd_kcontrol *kcontrol,
1262 int change; 1328 int change;
1263 1329
1264 change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, 1330 change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0,
1265 0x80, valp[0] & 0x80); 1331 0x80, (valp[0] ? 0 : 0x80));
1266 change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, 1332 change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0,
1267 0x80, valp[1] & 0x80); 1333 0x80, (valp[1] ? 0 : 0x80));
1268 snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, 1334 snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
1269 0x80, valp[0] & 0x80); 1335 0x80, (valp[0] ? 0 : 0x80));
1270 snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, 1336 snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
1271 0x80, valp[1] & 0x80); 1337 0x80, (valp[1] ? 0 : 0x80));
1272 return change; 1338 return change;
1273} 1339}
1274 1340
@@ -1370,6 +1436,12 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
1370 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x }, 1436 { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
1371 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x }, 1437 { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
1372 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x }, 1438 { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
1439 { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac922x },
1440 { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac922x },
1441 { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac922x },
1442 { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac922x },
1443 { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac922x },
1444 { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac922x },
1373 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x }, 1445 { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x },
1374 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x }, 1446 { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x },
1375 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x }, 1447 { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x },
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 336dc489aee1..ca74f5b85f42 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -1281,9 +1281,15 @@ static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
1281 1281
1282 tmp2 = tmp = snd_ice1712_gpio_read(ice); 1282 tmp2 = tmp = snd_ice1712_gpio_read(ice);
1283 if (enable) 1283 if (enable)
1284 tmp |= AUREON_HP_SEL; 1284 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT)
1285 tmp |= AUREON_HP_SEL;
1286 else
1287 tmp |= PRODIGY_HP_SEL;
1285 else 1288 else
1286 tmp &= ~ AUREON_HP_SEL; 1289 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT)
1290 tmp &= ~ AUREON_HP_SEL;
1291 else
1292 tmp &= ~ PRODIGY_HP_SEL;
1287 if (tmp != tmp2) { 1293 if (tmp != tmp2) {
1288 snd_ice1712_gpio_write(ice, tmp); 1294 snd_ice1712_gpio_write(ice, tmp);
1289 return 1; 1295 return 1;
@@ -2079,16 +2085,16 @@ static unsigned char prodigy71_eeprom[] __devinitdata = {
2079}; 2085};
2080 2086
2081static unsigned char prodigy71lt_eeprom[] __devinitdata = { 2087static unsigned char prodigy71lt_eeprom[] __devinitdata = {
2082 0x0b, /* SYSCINF: clock 512, spdif-in/ADC, 4DACs */ 2088 0x4b, /* SYSCINF: clock 512, spdif-in/ADC, 4DACs */
2083 0x80, /* ACLINK: I2S */ 2089 0x80, /* ACLINK: I2S */
2084 0xfc, /* I2S: vol, 96k, 24bit, 192k */ 2090 0xfc, /* I2S: vol, 96k, 24bit, 192k */
2085 0xc3, /* SPDUF: out-en, out-int */ 2091 0xc3, /* SPDIF: out-en, out-int, spdif-in */
2086 0x00, /* GPIO_DIR */ 2092 0xff, /* GPIO_DIR */
2087 0x07, /* GPIO_DIR1 */ 2093 0xff, /* GPIO_DIR1 */
2088 0x00, /* GPIO_DIR2 */ 2094 0x5f, /* GPIO_DIR2 */
2089 0xff, /* GPIO_MASK */ 2095 0x00, /* GPIO_MASK */
2090 0xf8, /* GPIO_MASK1 */ 2096 0x00, /* GPIO_MASK1 */
2091 0xff, /* GPIO_MASK2 */ 2097 0x00, /* GPIO_MASK2 */
2092 0x00, /* GPIO_STATE */ 2098 0x00, /* GPIO_STATE */
2093 0x00, /* GPIO_STATE1 */ 2099 0x00, /* GPIO_STATE1 */
2094 0x00, /* GPIO_STATE2 */ 2100 0x00, /* GPIO_STATE2 */
diff --git a/sound/pci/ice1712/aureon.h b/sound/pci/ice1712/aureon.h
index 98a6752280f2..3b7bea656c57 100644
--- a/sound/pci/ice1712/aureon.h
+++ b/sound/pci/ice1712/aureon.h
@@ -58,5 +58,6 @@ extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[];
58#define PRODIGY_WM_CS (1 << 8) 58#define PRODIGY_WM_CS (1 << 8)
59#define PRODIGY_SPI_MOSI (1 << 10) 59#define PRODIGY_SPI_MOSI (1 << 10)
60#define PRODIGY_SPI_CLK (1 << 9) 60#define PRODIGY_SPI_CLK (1 << 9)
61#define PRODIGY_HP_SEL (1 << 5)
61 62
62#endif /* __SOUND_AUREON_H */ 63#endif /* __SOUND_AUREON_H */
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index 2c529e741384..b135389fec6c 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -1031,6 +1031,9 @@ struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
1031 .model = "dmx6fire", 1031 .model = "dmx6fire",
1032 .chip_init = snd_ice1712_ews_init, 1032 .chip_init = snd_ice1712_ews_init,
1033 .build_controls = snd_ice1712_ews_add_controls, 1033 .build_controls = snd_ice1712_ews_add_controls,
1034 .mpu401_1_name = "MIDI-Front DMX6fire",
1035 .mpu401_2_name = "Wavetable DMX6fire",
1036 .mpu401_2_info_flags = MPU401_INFO_OUTPUT,
1034 }, 1037 },
1035 { } /* terminator */ 1038 { } /* terminator */
1036}; 1039};
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index c56793b381e2..845907159b74 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -61,7 +61,6 @@
61#include <sound/core.h> 61#include <sound/core.h>
62#include <sound/cs8427.h> 62#include <sound/cs8427.h>
63#include <sound/info.h> 63#include <sound/info.h>
64#include <sound/mpu401.h>
65#include <sound/initval.h> 64#include <sound/initval.h>
66 65
67#include <sound/asoundef.h> 66#include <sound/asoundef.h>
@@ -1596,7 +1595,7 @@ static void __devinit snd_ice1712_proc_init(struct snd_ice1712 * ice)
1596 struct snd_info_entry *entry; 1595 struct snd_info_entry *entry;
1597 1596
1598 if (! snd_card_proc_new(ice->card, "ice1712", &entry)) 1597 if (! snd_card_proc_new(ice->card, "ice1712", &entry))
1599 snd_info_set_text_ops(entry, ice, 1024, snd_ice1712_proc_read); 1598 snd_info_set_text_ops(entry, ice, snd_ice1712_proc_read);
1600} 1599}
1601 1600
1602/* 1601/*
@@ -2398,13 +2397,14 @@ static int __devinit snd_ice1712_chip_init(struct snd_ice1712 *ice)
2398 udelay(200); 2397 udelay(200);
2399 outb(ICE1712_NATIVE, ICEREG(ice, CONTROL)); 2398 outb(ICE1712_NATIVE, ICEREG(ice, CONTROL));
2400 udelay(200); 2399 udelay(200);
2401 if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DMX6FIRE && !ice->dxr_enable) { 2400 if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DMX6FIRE &&
2402 /* Limit active ADCs and DACs to 6; */ 2401 !ice->dxr_enable)
2403 /* Note: DXR extension not supported */ 2402 /* Set eeprom value to limit active ADCs and DACs to 6;
2404 pci_write_config_byte(ice->pci, 0x60, 0x2a); 2403 * Also disable AC97 as no hardware in standard 6fire card/box
2405 } else { 2404 * Note: DXR extensions are not currently supported
2406 pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]); 2405 */
2407 } 2406 ice->eeprom.data[ICE_EEP1_CODEC] = 0x3a;
2407 pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]);
2408 pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]); 2408 pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]);
2409 pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]); 2409 pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]);
2410 pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]); 2410 pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]);
@@ -2737,21 +2737,38 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2737 2737
2738 if (! c->no_mpu401) { 2738 if (! c->no_mpu401) {
2739 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, 2739 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
2740 ICEREG(ice, MPU1_CTRL), 1, 2740 ICEREG(ice, MPU1_CTRL),
2741 (c->mpu401_1_info_flags |
2742 MPU401_INFO_INTEGRATED),
2741 ice->irq, 0, 2743 ice->irq, 0,
2742 &ice->rmidi[0])) < 0) { 2744 &ice->rmidi[0])) < 0) {
2743 snd_card_free(card); 2745 snd_card_free(card);
2744 return err; 2746 return err;
2745 } 2747 }
2746 2748 if (c->mpu401_1_name)
2747 if (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) 2749 /* Prefered name available in card_info */
2750 snprintf(ice->rmidi[0]->name,
2751 sizeof(ice->rmidi[0]->name),
2752 "%s %d", c->mpu401_1_name, card->number);
2753
2754 if (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) {
2755 /* 2nd port used */
2748 if ((err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712, 2756 if ((err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712,
2749 ICEREG(ice, MPU2_CTRL), 1, 2757 ICEREG(ice, MPU2_CTRL),
2758 (c->mpu401_2_info_flags |
2759 MPU401_INFO_INTEGRATED),
2750 ice->irq, 0, 2760 ice->irq, 0,
2751 &ice->rmidi[1])) < 0) { 2761 &ice->rmidi[1])) < 0) {
2752 snd_card_free(card); 2762 snd_card_free(card);
2753 return err; 2763 return err;
2754 } 2764 }
2765 if (c->mpu401_2_name)
2766 /* Prefered name available in card_info */
2767 snprintf(ice->rmidi[1]->name,
2768 sizeof(ice->rmidi[1]->name),
2769 "%s %d", c->mpu401_2_name,
2770 card->number);
2771 }
2755 } 2772 }
2756 2773
2757 snd_ice1712_set_input_clock_source(ice, 0); 2774 snd_ice1712_set_input_clock_source(ice, 0);
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 053f8e56fd68..ce27eac40d4e 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -29,6 +29,7 @@
29#include <sound/ak4xxx-adda.h> 29#include <sound/ak4xxx-adda.h>
30#include <sound/ak4114.h> 30#include <sound/ak4114.h>
31#include <sound/pcm.h> 31#include <sound/pcm.h>
32#include <sound/mpu401.h>
32 33
33 34
34/* 35/*
@@ -495,6 +496,10 @@ struct snd_ice1712_card_info {
495 int (*chip_init)(struct snd_ice1712 *); 496 int (*chip_init)(struct snd_ice1712 *);
496 int (*build_controls)(struct snd_ice1712 *); 497 int (*build_controls)(struct snd_ice1712 *);
497 unsigned int no_mpu401: 1; 498 unsigned int no_mpu401: 1;
499 unsigned int mpu401_1_info_flags;
500 unsigned int mpu401_2_info_flags;
501 const char *mpu401_1_name;
502 const char *mpu401_2_name;
498 unsigned int eeprom_size; 503 unsigned int eeprom_size;
499 unsigned char *eeprom_data; 504 unsigned char *eeprom_data;
500}; 505};
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index b1c007e022d2..34a58c629f47 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -1293,7 +1293,7 @@ static void __devinit snd_vt1724_proc_init(struct snd_ice1712 * ice)
1293 struct snd_info_entry *entry; 1293 struct snd_info_entry *entry;
1294 1294
1295 if (! snd_card_proc_new(ice->card, "ice1724", &entry)) 1295 if (! snd_card_proc_new(ice->card, "ice1724", &entry))
1296 snd_info_set_text_ops(entry, ice, 1024, snd_vt1724_proc_read); 1296 snd_info_set_text_ops(entry, ice, snd_vt1724_proc_read);
1297} 1297}
1298 1298
1299/* 1299/*
@@ -2388,7 +2388,8 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2388 if (! c->no_mpu401) { 2388 if (! c->no_mpu401) {
2389 if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) { 2389 if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) {
2390 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, 2390 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
2391 ICEREG1724(ice, MPU_CTRL), 1, 2391 ICEREG1724(ice, MPU_CTRL),
2392 MPU401_INFO_INTEGRATED,
2392 ice->irq, 0, 2393 ice->irq, 0,
2393 &ice->rmidi[0])) < 0) { 2394 &ice->rmidi[0])) < 0) {
2394 snd_card_free(card); 2395 snd_card_free(card);
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index d23fb3fc2133..0efcad9260a5 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -680,9 +680,8 @@ static void wm_proc_init(struct snd_ice1712 *ice)
680{ 680{
681 struct snd_info_entry *entry; 681 struct snd_info_entry *entry;
682 if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) { 682 if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) {
683 snd_info_set_text_ops(entry, ice, 1024, wm_proc_regs_read); 683 snd_info_set_text_ops(entry, ice, wm_proc_regs_read);
684 entry->mode |= S_IWUSR; 684 entry->mode |= S_IWUSR;
685 entry->c.text.write_size = 1024;
686 entry->c.text.write = wm_proc_regs_write; 685 entry->c.text.write = wm_proc_regs_write;
687 } 686 }
688} 687}
@@ -705,9 +704,8 @@ static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buff
705static void cs_proc_init(struct snd_ice1712 *ice) 704static void cs_proc_init(struct snd_ice1712 *ice)
706{ 705{
707 struct snd_info_entry *entry; 706 struct snd_info_entry *entry;
708 if (! snd_card_proc_new(ice->card, "cs_codec", &entry)) { 707 if (! snd_card_proc_new(ice->card, "cs_codec", &entry))
709 snd_info_set_text_ops(entry, ice, 1024, cs_proc_regs_read); 708 snd_info_set_text_ops(entry, ice, cs_proc_regs_read);
710 }
711} 709}
712 710
713 711
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 0df7602568e2..edc14475ef82 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -66,7 +66,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
66 66
67static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ 67static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
68static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ 68static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
69static int ac97_clock = 0; 69static int ac97_clock;
70static char *ac97_quirk; 70static char *ac97_quirk;
71static int buggy_semaphore; 71static int buggy_semaphore;
72static int buggy_irq = -1; /* auto-check */ 72static int buggy_irq = -1; /* auto-check */
@@ -1807,6 +1807,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
1807 }, 1807 },
1808 { 1808 {
1809 .subvendor = 0x1028, 1809 .subvendor = 0x1028,
1810 .subdevice = 0x014e,
1811 .name = "Dell D800", /* STAC9750/51 */
1812 .type = AC97_TUNE_HP_ONLY
1813 },
1814 {
1815 .subvendor = 0x1028,
1810 .subdevice = 0x0163, 1816 .subdevice = 0x0163,
1811 .name = "Dell Unknown", /* STAC9750/51 */ 1817 .name = "Dell Unknown", /* STAC9750/51 */
1812 .type = AC97_TUNE_HP_ONLY 1818 .type = AC97_TUNE_HP_ONLY
@@ -2645,7 +2651,7 @@ static void __devinit snd_intel8x0_proc_init(struct intel8x0 * chip)
2645 struct snd_info_entry *entry; 2651 struct snd_info_entry *entry;
2646 2652
2647 if (! snd_card_proc_new(chip->card, "intel8x0", &entry)) 2653 if (! snd_card_proc_new(chip->card, "intel8x0", &entry))
2648 snd_info_set_text_ops(entry, chip, 1024, snd_intel8x0_proc_read); 2654 snd_info_set_text_ops(entry, chip, snd_intel8x0_proc_read);
2649} 2655}
2650#else 2656#else
2651#define snd_intel8x0_proc_init(x) 2657#define snd_intel8x0_proc_init(x)
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 720635f0cb81..24703d75b65a 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -59,7 +59,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
59 59
60static int index = -2; /* Exclude the first card */ 60static int index = -2; /* Exclude the first card */
61static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ 61static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
62static int ac97_clock = 0; 62static int ac97_clock;
63 63
64module_param(index, int, 0444); 64module_param(index, int, 0444);
65MODULE_PARM_DESC(index, "Index value for Intel i8x0 modemcard."); 65MODULE_PARM_DESC(index, "Index value for Intel i8x0 modemcard.");
@@ -1092,7 +1092,7 @@ static void __devinit snd_intel8x0m_proc_init(struct intel8x0m * chip)
1092 struct snd_info_entry *entry; 1092 struct snd_info_entry *entry;
1093 1093
1094 if (! snd_card_proc_new(chip->card, "intel8x0m", &entry)) 1094 if (! snd_card_proc_new(chip->card, "intel8x0m", &entry))
1095 snd_info_set_text_ops(entry, chip, 1024, snd_intel8x0m_proc_read); 1095 snd_info_set_text_ops(entry, chip, snd_intel8x0m_proc_read);
1096} 1096}
1097#else /* !CONFIG_PROC_FS */ 1097#else /* !CONFIG_PROC_FS */
1098#define snd_intel8x0m_proc_init(chip) 1098#define snd_intel8x0m_proc_init(chip)
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index e39fad1a4200..6e97932de34f 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2085,7 +2085,7 @@ static void __devinit snd_korg1212_proc_init(struct snd_korg1212 *korg1212)
2085 struct snd_info_entry *entry; 2085 struct snd_info_entry *entry;
2086 2086
2087 if (! snd_card_proc_new(korg1212->card, "korg1212", &entry)) 2087 if (! snd_card_proc_new(korg1212->card, "korg1212", &entry))
2088 snd_info_set_text_ops(entry, korg1212, 1024, snd_korg1212_proc_read); 2088 snd_info_set_text_ops(entry, korg1212, snd_korg1212_proc_read);
2089} 2089}
2090 2090
2091static int 2091static int
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 1928e06b6d82..1c344fbd964d 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -2861,7 +2861,8 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2861#if 0 /* TODO: not supported yet */ 2861#if 0 /* TODO: not supported yet */
2862 /* TODO enable MIDI IRQ and I/O */ 2862 /* TODO enable MIDI IRQ and I/O */
2863 err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401, 2863 err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401,
2864 chip->iobase + MPU401_DATA_PORT, 1, 2864 chip->iobase + MPU401_DATA_PORT,
2865 MPU401_INFO_INTEGRATED,
2865 chip->irq, 0, &chip->rmidi); 2866 chip->irq, 0, &chip->rmidi);
2866 if (err < 0) 2867 if (err < 0)
2867 printk(KERN_WARNING "maestro3: no MIDI support.\n"); 2868 printk(KERN_WARNING "maestro3: no MIDI support.\n");
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 09cc0786495a..366c4a7e65c6 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1244,7 +1244,6 @@ static void __devinit snd_mixart_proc_init(struct snd_mixart *chip)
1244 /* text interface to read perf and temp meters */ 1244 /* text interface to read perf and temp meters */
1245 if (! snd_card_proc_new(chip->card, "board_info", &entry)) { 1245 if (! snd_card_proc_new(chip->card, "board_info", &entry)) {
1246 entry->private_data = chip; 1246 entry->private_data = chip;
1247 entry->c.text.read_size = 1024;
1248 entry->c.text.read = snd_mixart_proc_read; 1247 entry->c.text.read = snd_mixart_proc_read;
1249 } 1248 }
1250 1249
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index dafa2235abaa..8198884b51ee 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1150,9 +1150,9 @@ static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip)
1150 struct snd_info_entry *entry; 1150 struct snd_info_entry *entry;
1151 1151
1152 if (! snd_card_proc_new(chip->card, "info", &entry)) 1152 if (! snd_card_proc_new(chip->card, "info", &entry))
1153 snd_info_set_text_ops(entry, chip, 1024, pcxhr_proc_info); 1153 snd_info_set_text_ops(entry, chip, pcxhr_proc_info);
1154 if (! snd_card_proc_new(chip->card, "sync", &entry)) 1154 if (! snd_card_proc_new(chip->card, "sync", &entry))
1155 snd_info_set_text_ops(entry, chip, 1024, pcxhr_proc_sync); 1155 snd_info_set_text_ops(entry, chip, pcxhr_proc_sync);
1156} 1156}
1157/* end of proc interface */ 1157/* end of proc interface */
1158 1158
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index d8cc985d7241..5618ec9740bd 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1836,11 +1836,11 @@ static int snd_riptide_free(struct snd_riptide *chip)
1836 UNSET_GRESET(cif->hwport); 1836 UNSET_GRESET(cif->hwport);
1837 kfree(chip->cif); 1837 kfree(chip->cif);
1838 } 1838 }
1839 if (chip->irq >= 0)
1840 free_irq(chip->irq, chip);
1839 if (chip->fw_entry) 1841 if (chip->fw_entry)
1840 release_firmware(chip->fw_entry); 1842 release_firmware(chip->fw_entry);
1841 release_and_free_resource(chip->res_port); 1843 release_and_free_resource(chip->res_port);
1842 if (chip->irq >= 0)
1843 free_irq(chip->irq, chip);
1844 kfree(chip); 1844 kfree(chip);
1845 return 0; 1845 return 0;
1846} 1846}
@@ -1992,7 +1992,7 @@ static void __devinit snd_riptide_proc_init(struct snd_riptide *chip)
1992 struct snd_info_entry *entry; 1992 struct snd_info_entry *entry;
1993 1993
1994 if (!snd_card_proc_new(chip->card, "riptide", &entry)) 1994 if (!snd_card_proc_new(chip->card, "riptide", &entry))
1995 snd_info_set_text_ops(entry, chip, 4096, snd_riptide_proc_read); 1995 snd_info_set_text_ops(entry, chip, snd_riptide_proc_read);
1996} 1996}
1997 1997
1998static int __devinit snd_riptide_mixer(struct snd_riptide *chip) 1998static int __devinit snd_riptide_mixer(struct snd_riptide *chip)
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 55b1d4838d97..2cb9fe98db2f 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1368,18 +1368,18 @@ static int __devinit snd_rme32_create(struct rme32 * rme32)
1368 return err; 1368 return err;
1369 rme32->port = pci_resource_start(rme32->pci, 0); 1369 rme32->port = pci_resource_start(rme32->pci, 0);
1370 1370
1371 if (request_irq(pci->irq, snd_rme32_interrupt, SA_INTERRUPT | SA_SHIRQ, "RME32", (void *) rme32)) {
1372 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1373 return -EBUSY;
1374 }
1375 rme32->irq = pci->irq;
1376
1377 if ((rme32->iobase = ioremap_nocache(rme32->port, RME32_IO_SIZE)) == 0) { 1371 if ((rme32->iobase = ioremap_nocache(rme32->port, RME32_IO_SIZE)) == 0) {
1378 snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", 1372 snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n",
1379 rme32->port, rme32->port + RME32_IO_SIZE - 1); 1373 rme32->port, rme32->port + RME32_IO_SIZE - 1);
1380 return -ENOMEM; 1374 return -ENOMEM;
1381 } 1375 }
1382 1376
1377 if (request_irq(pci->irq, snd_rme32_interrupt, SA_INTERRUPT | SA_SHIRQ, "RME32", (void *) rme32)) {
1378 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1379 return -EBUSY;
1380 }
1381 rme32->irq = pci->irq;
1382
1383 /* read the card's revision number */ 1383 /* read the card's revision number */
1384 pci_read_config_byte(pci, 8, &rme32->rev); 1384 pci_read_config_byte(pci, 8, &rme32->rev);
1385 1385
@@ -1578,7 +1578,7 @@ static void __devinit snd_rme32_proc_init(struct rme32 * rme32)
1578 struct snd_info_entry *entry; 1578 struct snd_info_entry *entry;
1579 1579
1580 if (! snd_card_proc_new(rme32->card, "rme32", &entry)) 1580 if (! snd_card_proc_new(rme32->card, "rme32", &entry))
1581 snd_info_set_text_ops(entry, rme32, 1024, snd_rme32_proc_read); 1581 snd_info_set_text_ops(entry, rme32, snd_rme32_proc_read);
1582} 1582}
1583 1583
1584/* 1584/*
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 3c1bc533d511..991cb18c14f3 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -1151,6 +1151,25 @@ static struct snd_pcm_hw_constraint_list hw_constraints_period_bytes = {
1151 .mask = 0 1151 .mask = 0
1152}; 1152};
1153 1153
1154static void
1155rme96_set_buffer_size_constraint(struct rme96 *rme96,
1156 struct snd_pcm_runtime *runtime)
1157{
1158 unsigned int size;
1159
1160 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1161 RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
1162 if ((size = rme96->playback_periodsize) != 0 ||
1163 (size = rme96->capture_periodsize) != 0)
1164 snd_pcm_hw_constraint_minmax(runtime,
1165 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1166 size, size);
1167 else
1168 snd_pcm_hw_constraint_list(runtime, 0,
1169 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
1170 &hw_constraints_period_bytes);
1171}
1172
1154static int 1173static int
1155snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream) 1174snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
1156{ 1175{
@@ -1180,8 +1199,7 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
1180 runtime->hw.rate_min = rate; 1199 runtime->hw.rate_min = rate;
1181 runtime->hw.rate_max = rate; 1200 runtime->hw.rate_max = rate;
1182 } 1201 }
1183 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); 1202 rme96_set_buffer_size_constraint(rme96, runtime);
1184 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
1185 1203
1186 rme96->wcreg_spdif_stream = rme96->wcreg_spdif; 1204 rme96->wcreg_spdif_stream = rme96->wcreg_spdif;
1187 rme96->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 1205 rme96->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
@@ -1219,9 +1237,7 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream)
1219 rme96->capture_substream = substream; 1237 rme96->capture_substream = substream;
1220 spin_unlock_irq(&rme96->lock); 1238 spin_unlock_irq(&rme96->lock);
1221 1239
1222 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); 1240 rme96_set_buffer_size_constraint(rme96, runtime);
1223 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
1224
1225 return 0; 1241 return 0;
1226} 1242}
1227 1243
@@ -1254,8 +1270,7 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream)
1254 runtime->hw.rate_min = rate; 1270 runtime->hw.rate_min = rate;
1255 runtime->hw.rate_max = rate; 1271 runtime->hw.rate_max = rate;
1256 } 1272 }
1257 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); 1273 rme96_set_buffer_size_constraint(rme96, runtime);
1258 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
1259 return 0; 1274 return 0;
1260} 1275}
1261 1276
@@ -1291,8 +1306,7 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream)
1291 rme96->capture_substream = substream; 1306 rme96->capture_substream = substream;
1292 spin_unlock_irq(&rme96->lock); 1307 spin_unlock_irq(&rme96->lock);
1293 1308
1294 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); 1309 rme96_set_buffer_size_constraint(rme96, runtime);
1295 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
1296 return 0; 1310 return 0;
1297} 1311}
1298 1312
@@ -1569,17 +1583,17 @@ snd_rme96_create(struct rme96 *rme96)
1569 return err; 1583 return err;
1570 rme96->port = pci_resource_start(rme96->pci, 0); 1584 rme96->port = pci_resource_start(rme96->pci, 0);
1571 1585
1586 if ((rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {
1587 snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
1588 return -ENOMEM;
1589 }
1590
1572 if (request_irq(pci->irq, snd_rme96_interrupt, SA_INTERRUPT|SA_SHIRQ, "RME96", (void *)rme96)) { 1591 if (request_irq(pci->irq, snd_rme96_interrupt, SA_INTERRUPT|SA_SHIRQ, "RME96", (void *)rme96)) {
1573 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1592 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1574 return -EBUSY; 1593 return -EBUSY;
1575 } 1594 }
1576 rme96->irq = pci->irq; 1595 rme96->irq = pci->irq;
1577 1596
1578 if ((rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {
1579 snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
1580 return -ENOMEM;
1581 }
1582
1583 /* read the card's revision number */ 1597 /* read the card's revision number */
1584 pci_read_config_byte(pci, 8, &rme96->rev); 1598 pci_read_config_byte(pci, 8, &rme96->rev);
1585 1599
@@ -1805,7 +1819,7 @@ snd_rme96_proc_init(struct rme96 *rme96)
1805 struct snd_info_entry *entry; 1819 struct snd_info_entry *entry;
1806 1820
1807 if (! snd_card_proc_new(rme96->card, "rme96", &entry)) 1821 if (! snd_card_proc_new(rme96->card, "rme96", &entry))
1808 snd_info_set_text_ops(entry, rme96, 1024, snd_rme96_proc_read); 1822 snd_info_set_text_ops(entry, rme96, snd_rme96_proc_read);
1809} 1823}
1810 1824
1811/* 1825/*
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 61f82f0d5cc6..eaf3c22449ad 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -389,7 +389,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
389 389
390/* use hotplug firmeare loader? */ 390/* use hotplug firmeare loader? */
391#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) 391#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
392#ifndef HDSP_USE_HWDEP_LOADER 392#if !defined(HDSP_USE_HWDEP_LOADER) && !defined(CONFIG_SND_HDSP)
393#define HDSP_FW_LOADER 393#define HDSP_FW_LOADER
394#endif 394#endif
395#endif 395#endif
@@ -3169,9 +3169,10 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3169 char *clock_source; 3169 char *clock_source;
3170 int x; 3170 int x;
3171 3171
3172 if (hdsp_check_for_iobox (hdsp)) 3172 if (hdsp_check_for_iobox (hdsp)) {
3173 snd_iprintf(buffer, "No I/O box connected.\nPlease connect one and upload firmware.\n"); 3173 snd_iprintf(buffer, "No I/O box connected.\nPlease connect one and upload firmware.\n");
3174 return; 3174 return;
3175 }
3175 3176
3176 if (hdsp_check_for_firmware(hdsp, 0)) { 3177 if (hdsp_check_for_firmware(hdsp, 0)) {
3177 if (hdsp->state & HDSP_FirmwareCached) { 3178 if (hdsp->state & HDSP_FirmwareCached) {
@@ -3470,7 +3471,7 @@ static void __devinit snd_hdsp_proc_init(struct hdsp *hdsp)
3470 struct snd_info_entry *entry; 3471 struct snd_info_entry *entry;
3471 3472
3472 if (! snd_card_proc_new(hdsp->card, "hdsp", &entry)) 3473 if (! snd_card_proc_new(hdsp->card, "hdsp", &entry))
3473 snd_info_set_text_ops(entry, hdsp, 1024, snd_hdsp_proc_read); 3474 snd_info_set_text_ops(entry, hdsp, snd_hdsp_proc_read);
3474} 3475}
3475 3476
3476static void snd_hdsp_free_buffers(struct hdsp *hdsp) 3477static void snd_hdsp_free_buffers(struct hdsp *hdsp)
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 722b9e6ce54a..bba1615504d3 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -2489,7 +2489,7 @@ static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm)
2489 struct snd_info_entry *entry; 2489 struct snd_info_entry *entry;
2490 2490
2491 if (!snd_card_proc_new(hdspm->card, "hdspm", &entry)) 2491 if (!snd_card_proc_new(hdspm->card, "hdspm", &entry))
2492 snd_info_set_text_ops(entry, hdspm, 1024, 2492 snd_info_set_text_ops(entry, hdspm,
2493 snd_hdspm_proc_read); 2493 snd_hdspm_proc_read);
2494} 2494}
2495 2495
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 75d6406303d3..3b945e8c1b15 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -41,7 +41,7 @@
41static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 41static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
42static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 42static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
43static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 43static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
44static int precise_ptr[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* Enable precise pointer */ 44static int precise_ptr[SNDRV_CARDS]; /* Enable precise pointer */
45 45
46module_param_array(index, int, NULL, 0444); 46module_param_array(index, int, NULL, 0444);
47MODULE_PARM_DESC(index, "Index value for RME Digi9652 (Hammerfall) soundcard."); 47MODULE_PARM_DESC(index, "Index value for RME Digi9652 (Hammerfall) soundcard.");
@@ -1787,7 +1787,7 @@ static void __devinit snd_rme9652_proc_init(struct snd_rme9652 *rme9652)
1787 struct snd_info_entry *entry; 1787 struct snd_info_entry *entry;
1788 1788
1789 if (! snd_card_proc_new(rme9652->card, "rme9652", &entry)) 1789 if (! snd_card_proc_new(rme9652->card, "rme9652", &entry))
1790 snd_info_set_text_ops(entry, rme9652, 1024, snd_rme9652_proc_read); 1790 snd_info_set_text_ops(entry, rme9652, snd_rme9652_proc_read);
1791} 1791}
1792 1792
1793static void snd_rme9652_free_buffers(struct snd_rme9652 *rme9652) 1793static void snd_rme9652_free_buffers(struct snd_rme9652 *rme9652)
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 91f8bf3ae9fa..dcf402948347 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -54,8 +54,8 @@ MODULE_SUPPORTED_DEVICE("{{S3,SonicVibes PCI}}");
54static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 54static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
55static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 55static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
56static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 56static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
57static int reverb[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 57static int reverb[SNDRV_CARDS];
58static int mge[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; 58static int mge[SNDRV_CARDS];
59static unsigned int dmaio = 0x7a00; /* DDMA i/o address */ 59static unsigned int dmaio = 0x7a00; /* DDMA i/o address */
60 60
61module_param_array(index, int, NULL, 0444); 61module_param_array(index, int, NULL, 0444);
@@ -1144,7 +1144,7 @@ static void __devinit snd_sonicvibes_proc_init(struct sonicvibes * sonic)
1144 struct snd_info_entry *entry; 1144 struct snd_info_entry *entry;
1145 1145
1146 if (! snd_card_proc_new(sonic->card, "sonicvibes", &entry)) 1146 if (! snd_card_proc_new(sonic->card, "sonicvibes", &entry))
1147 snd_info_set_text_ops(entry, sonic, 1024, snd_sonicvibes_proc_read); 1147 snd_info_set_text_ops(entry, sonic, snd_sonicvibes_proc_read);
1148} 1148}
1149 1149
1150/* 1150/*
@@ -1456,7 +1456,7 @@ static int __devinit snd_sonic_probe(struct pci_dev *pci,
1456 return err; 1456 return err;
1457 } 1457 }
1458 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES, 1458 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES,
1459 sonic->midi_port, 1, 1459 sonic->midi_port, MPU401_INFO_INTEGRATED,
1460 sonic->irq, 0, 1460 sonic->irq, 0,
1461 &midi_uart)) < 0) { 1461 &midi_uart)) < 0) {
1462 snd_card_free(card); 1462 snd_card_free(card);
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 9624a5f2b875..5629b7eba96d 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -148,7 +148,8 @@ static int __devinit snd_trident_probe(struct pci_dev *pci,
148 } 148 }
149 if (trident->device != TRIDENT_DEVICE_ID_SI7018 && 149 if (trident->device != TRIDENT_DEVICE_ID_SI7018 &&
150 (err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE, 150 (err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE,
151 trident->midi_port, 1, 151 trident->midi_port,
152 MPU401_INFO_INTEGRATED,
152 trident->irq, 0, &trident->rmidi)) < 0) { 153 trident->irq, 0, &trident->rmidi)) < 0) {
153 snd_card_free(card); 154 snd_card_free(card);
154 return err; 155 return err;
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 52178b8ad49d..d99ed7237750 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -306,6 +306,8 @@ void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice)
306 outl(mask, TRID_REG(trident, reg)); 306 outl(mask, TRID_REG(trident, reg));
307} 307}
308 308
309EXPORT_SYMBOL(snd_trident_start_voice);
310
309/*--------------------------------------------------------------------------- 311/*---------------------------------------------------------------------------
310 void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice) 312 void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice)
311 313
@@ -328,6 +330,8 @@ void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice)
328 outl(mask, TRID_REG(trident, reg)); 330 outl(mask, TRID_REG(trident, reg));
329} 331}
330 332
333EXPORT_SYMBOL(snd_trident_stop_voice);
334
331/*--------------------------------------------------------------------------- 335/*---------------------------------------------------------------------------
332 int snd_trident_allocate_pcm_channel(struct snd_trident *trident) 336 int snd_trident_allocate_pcm_channel(struct snd_trident *trident)
333 337
@@ -502,6 +506,8 @@ void snd_trident_write_voice_regs(struct snd_trident * trident,
502#endif 506#endif
503} 507}
504 508
509EXPORT_SYMBOL(snd_trident_write_voice_regs);
510
505/*--------------------------------------------------------------------------- 511/*---------------------------------------------------------------------------
506 snd_trident_write_cso_reg 512 snd_trident_write_cso_reg
507 513
@@ -3332,7 +3338,7 @@ static void __devinit snd_trident_proc_init(struct snd_trident * trident)
3332 if (trident->device == TRIDENT_DEVICE_ID_SI7018) 3338 if (trident->device == TRIDENT_DEVICE_ID_SI7018)
3333 s = "sis7018"; 3339 s = "sis7018";
3334 if (! snd_card_proc_new(trident->card, s, &entry)) 3340 if (! snd_card_proc_new(trident->card, s, &entry))
3335 snd_info_set_text_ops(entry, trident, 1024, snd_trident_proc_read); 3341 snd_info_set_text_ops(entry, trident, snd_trident_proc_read);
3336} 3342}
3337 3343
3338static int snd_trident_dev_free(struct snd_device *device) 3344static int snd_trident_dev_free(struct snd_device *device)
@@ -3884,6 +3890,8 @@ struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident,
3884 return NULL; 3890 return NULL;
3885} 3891}
3886 3892
3893EXPORT_SYMBOL(snd_trident_alloc_voice);
3894
3887void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice) 3895void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice)
3888{ 3896{
3889 unsigned long flags; 3897 unsigned long flags;
@@ -3912,6 +3920,8 @@ void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voi
3912 private_free(voice); 3920 private_free(voice);
3913} 3921}
3914 3922
3923EXPORT_SYMBOL(snd_trident_free_voice);
3924
3915static void snd_trident_clear_voices(struct snd_trident * trident, unsigned short v_min, unsigned short v_max) 3925static void snd_trident_clear_voices(struct snd_trident * trident, unsigned short v_min, unsigned short v_max)
3916{ 3926{
3917 unsigned int i, val, mask[2] = { 0, 0 }; 3927 unsigned int i, val, mask[2] = { 0, 0 };
@@ -3993,13 +4003,3 @@ int snd_trident_resume(struct pci_dev *pci)
3993 return 0; 4003 return 0;
3994} 4004}
3995#endif /* CONFIG_PM */ 4005#endif /* CONFIG_PM */
3996
3997EXPORT_SYMBOL(snd_trident_alloc_voice);
3998EXPORT_SYMBOL(snd_trident_free_voice);
3999EXPORT_SYMBOL(snd_trident_start_voice);
4000EXPORT_SYMBOL(snd_trident_stop_voice);
4001EXPORT_SYMBOL(snd_trident_write_voice_regs);
4002/* trident_memory.c symbols */
4003EXPORT_SYMBOL(snd_trident_synth_alloc);
4004EXPORT_SYMBOL(snd_trident_synth_free);
4005EXPORT_SYMBOL(snd_trident_synth_copy_from_user);
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index 46c6982c9e88..aff3f874131c 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -349,6 +349,7 @@ snd_trident_synth_alloc(struct snd_trident *hw, unsigned int size)
349 return blk; 349 return blk;
350} 350}
351 351
352EXPORT_SYMBOL(snd_trident_synth_alloc);
352 353
353/* 354/*
354 * free a synth sample area 355 * free a synth sample area
@@ -365,6 +366,7 @@ snd_trident_synth_free(struct snd_trident *hw, struct snd_util_memblk *blk)
365 return 0; 366 return 0;
366} 367}
367 368
369EXPORT_SYMBOL(snd_trident_synth_free);
368 370
369/* 371/*
370 * reset TLB entry and free kernel page 372 * reset TLB entry and free kernel page
@@ -486,3 +488,4 @@ int snd_trident_synth_copy_from_user(struct snd_trident *trident,
486 return 0; 488 return 0;
487} 489}
488 490
491EXPORT_SYMBOL(snd_trident_synth_copy_from_user);
diff --git a/sound/pci/trident/trident_synth.c b/sound/pci/trident/trident_synth.c
index cc7af8bc55a0..9b7dee84743b 100644
--- a/sound/pci/trident/trident_synth.c
+++ b/sound/pci/trident/trident_synth.c
@@ -914,7 +914,9 @@ static int snd_trident_synth_create_port(struct snd_trident * trident, int idx)
914 &callbacks, 914 &callbacks,
915 SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE, 915 SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
916 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE | 916 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
917 SNDRV_SEQ_PORT_TYPE_SYNTH, 917 SNDRV_SEQ_PORT_TYPE_SYNTH |
918 SNDRV_SEQ_PORT_TYPE_HARDWARE |
919 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER,
918 16, 0, 920 16, 0,
919 name); 921 name);
920 if (p->chset->port < 0) { 922 if (p->chset->port < 0) {
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 39daf62d2bad..2527bbd958c5 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1775,6 +1775,12 @@ static struct ac97_quirk ac97_quirks[] = {
1775 .name = "Targa Traveller 811", 1775 .name = "Targa Traveller 811",
1776 .type = AC97_TUNE_HP_ONLY, 1776 .type = AC97_TUNE_HP_ONLY,
1777 }, 1777 },
1778 {
1779 .subvendor = 0x161f,
1780 .subdevice = 0x2032,
1781 .name = "m680x",
1782 .type = AC97_TUNE_HP_ONLY, /* http://launchpad.net/bugs/38546 */
1783 },
1778 { } /* terminator */ 1784 { } /* terminator */
1779}; 1785};
1780 1786
@@ -1973,7 +1979,7 @@ static int __devinit snd_via686_init_misc(struct via82xx *chip)
1973 pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg); 1979 pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
1974 if (chip->mpu_res) { 1980 if (chip->mpu_res) {
1975 if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A, 1981 if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A,
1976 mpu_port, 1, 1982 mpu_port, MPU401_INFO_INTEGRATED,
1977 chip->irq, 0, &chip->rmidi) < 0) { 1983 chip->irq, 0, &chip->rmidi) < 0) {
1978 printk(KERN_WARNING "unable to initialize MPU-401" 1984 printk(KERN_WARNING "unable to initialize MPU-401"
1979 " at 0x%lx, skipping\n", mpu_port); 1985 " at 0x%lx, skipping\n", mpu_port);
@@ -2015,7 +2021,7 @@ static void __devinit snd_via82xx_proc_init(struct via82xx *chip)
2015 struct snd_info_entry *entry; 2021 struct snd_info_entry *entry;
2016 2022
2017 if (! snd_card_proc_new(chip->card, "via82xx", &entry)) 2023 if (! snd_card_proc_new(chip->card, "via82xx", &entry))
2018 snd_info_set_text_ops(entry, chip, 1024, snd_via82xx_proc_read); 2024 snd_info_set_text_ops(entry, chip, snd_via82xx_proc_read);
2019} 2025}
2020 2026
2021/* 2027/*
@@ -2365,7 +2371,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci, int revision)
2365 { .subvendor = 0x1462, .subdevice = 0x0470, .action = VIA_DXS_SRC }, /* MSI KT880 Delta-FSR */ 2371 { .subvendor = 0x1462, .subdevice = 0x0470, .action = VIA_DXS_SRC }, /* MSI KT880 Delta-FSR */
2366 { .subvendor = 0x1462, .subdevice = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */ 2372 { .subvendor = 0x1462, .subdevice = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */
2367 { .subvendor = 0x1462, .subdevice = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */ 2373 { .subvendor = 0x1462, .subdevice = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */
2368 { .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */ 2374 { .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_SRC }, /* MSI K8T Neo2-FI */
2369 { .subvendor = 0x1462, .subdevice = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */ 2375 { .subvendor = 0x1462, .subdevice = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */
2370 { .subvendor = 0x1462, .subdevice = 0x7142, .action = VIA_DXS_ENABLE }, /* MSI K8MM-V */ 2376 { .subvendor = 0x1462, .subdevice = 0x7142, .action = VIA_DXS_ENABLE }, /* MSI K8MM-V */
2371 { .subvendor = 0x1462, .subdevice = 0xb012, .action = VIA_DXS_SRC }, /* P4M800/VIA8237R */ 2377 { .subvendor = 0x1462, .subdevice = 0xb012, .action = VIA_DXS_SRC }, /* P4M800/VIA8237R */
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index ef97e50cd6c2..577a2b03759f 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -929,7 +929,7 @@ static void __devinit snd_via82xx_proc_init(struct via82xx_modem *chip)
929 struct snd_info_entry *entry; 929 struct snd_info_entry *entry;
930 930
931 if (! snd_card_proc_new(chip->card, "via82xx", &entry)) 931 if (! snd_card_proc_new(chip->card, "via82xx", &entry))
932 snd_info_set_text_ops(entry, chip, 1024, snd_via82xx_proc_read); 932 snd_info_set_text_ops(entry, chip, snd_via82xx_proc_read);
933} 933}
934 934
935/* 935/*
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 65ebf5f1933a..26aa775b7b69 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -308,7 +308,8 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
308 } 308 }
309 if (chip->mpu_res) { 309 if (chip->mpu_res) {
310 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI, 310 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,
311 mpu_port[dev], 1, 311 mpu_port[dev],
312 MPU401_INFO_INTEGRATED,
312 pci->irq, 0, &chip->rawmidi)) < 0) { 313 pci->irq, 0, &chip->rawmidi)) < 0) {
313 printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]); 314 printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]);
314 legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */ 315 legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 8ac5ab50b5c7..f894752523bb 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -1919,7 +1919,7 @@ static int __devinit snd_ymfpci_proc_init(struct snd_card *card, struct snd_ymfp
1919 struct snd_info_entry *entry; 1919 struct snd_info_entry *entry;
1920 1920
1921 if (! snd_card_proc_new(card, "ymfpci", &entry)) 1921 if (! snd_card_proc_new(card, "ymfpci", &entry))
1922 snd_info_set_text_ops(entry, chip, 1024, snd_ymfpci_proc_read); 1922 snd_info_set_text_ops(entry, chip, snd_ymfpci_proc_read);
1923 return 0; 1923 return 0;
1924} 1924}
1925 1925
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
index bd0d70ff3019..1dfe29b863d3 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
@@ -144,7 +144,7 @@ static void pdacf_proc_init(struct snd_pdacf *chip)
144 struct snd_info_entry *entry; 144 struct snd_info_entry *entry;
145 145
146 if (! snd_card_proc_new(chip->card, "pdaudiocf", &entry)) 146 if (! snd_card_proc_new(chip->card, "pdaudiocf", &entry))
147 snd_info_set_text_ops(entry, chip, 1024, pdacf_proc_read); 147 snd_info_set_text_ops(entry, chip, pdacf_proc_read);
148} 148}
149 149
150struct snd_pdacf *snd_pdacf_create(struct snd_card *card) 150struct snd_pdacf *snd_pdacf_create(struct snd_card *card)
diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c
index 7f82f619f9f4..1ee0918c3b9f 100644
--- a/sound/pcmcia/vx/vxp_ops.c
+++ b/sound/pcmcia/vx/vxp_ops.c
@@ -202,7 +202,7 @@ static int vxp_load_xilinx_binary(struct vx_core *_chip, const struct firmware *
202 c |= (int)vx_inb(chip, RXM) << 8; 202 c |= (int)vx_inb(chip, RXM) << 8;
203 c |= vx_inb(chip, RXL); 203 c |= vx_inb(chip, RXL);
204 204
205 snd_printdd(KERN_DEBUG "xilinx: dsp size received 0x%x, orig 0x%x\n", c, fw->size); 205 snd_printdd(KERN_DEBUG "xilinx: dsp size received 0x%x, orig 0x%Zx\n", c, fw->size);
206 206
207 vx_outb(chip, ICR, ICR_HF0); 207 vx_outb(chip, ICR, ICR_HF0);
208 208
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 7e0cda2b6ef9..cafe6640cc1a 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -261,7 +261,7 @@ static int vxpocket_config(struct pcmcia_device *link)
261 261
262 link->dev_node = &vxp->node; 262 link->dev_node = &vxp->node;
263 kfree(parse); 263 kfree(parse);
264 return 9; 264 return 0;
265 265
266cs_failed: 266cs_failed:
267 cs_error(link, last_fn, last_ret); 267 cs_error(link, last_fn, last_ret);
diff --git a/sound/ppc/Makefile b/sound/ppc/Makefile
index d6ba9959097b..4d95c652c8ca 100644
--- a/sound/ppc/Makefile
+++ b/sound/ppc/Makefile
@@ -3,7 +3,7 @@
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> 3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4# 4#
5 5
6snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o toonie.o keywest.o beep.o 6snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o
7 7
8# Toplevel Module Dependency 8# Toplevel Module Dependency
9obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o 9obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index f0794ef9d1ac..b678814975c9 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -867,8 +867,6 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
867 unsigned int *prop, l; 867 unsigned int *prop, l;
868 struct macio_chip* macio; 868 struct macio_chip* macio;
869 869
870 u32 layout_id = 0;
871
872 if (!machine_is(powermac)) 870 if (!machine_is(powermac))
873 return -ENODEV; 871 return -ENODEV;
874 872
@@ -929,8 +927,14 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
929 if (prop && *prop < 16) 927 if (prop && *prop < 16)
930 chip->subframe = *prop; 928 chip->subframe = *prop;
931 prop = (unsigned int *) get_property(sound, "layout-id", NULL); 929 prop = (unsigned int *) get_property(sound, "layout-id", NULL);
932 if (prop) 930 if (prop) {
933 layout_id = *prop; 931 /* partly deprecate snd-powermac, for those machines
932 * that have a layout-id property for now */
933 printk(KERN_INFO "snd-powermac no longer handles any "
934 "machines with a layout-id property "
935 "in the device-tree, use snd-aoa.\n");
936 return -ENODEV;
937 }
934 /* This should be verified on older screamers */ 938 /* This should be verified on older screamers */
935 if (device_is_compatible(sound, "screamer")) { 939 if (device_is_compatible(sound, "screamer")) {
936 chip->model = PMAC_SCREAMER; 940 chip->model = PMAC_SCREAMER;
@@ -963,38 +967,6 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
963 chip->freq_table = tumbler_freqs; 967 chip->freq_table = tumbler_freqs;
964 chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ 968 chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
965 } 969 }
966 if (device_is_compatible(sound, "AOAKeylargo") ||
967 device_is_compatible(sound, "AOAbase") ||
968 device_is_compatible(sound, "AOAK2")) {
969 /* For now, only support very basic TAS3004 based machines with
970 * single frequency until proper i2s control is implemented
971 */
972 switch(layout_id) {
973 case 0x24:
974 case 0x29:
975 case 0x33:
976 case 0x46:
977 case 0x48:
978 case 0x50:
979 case 0x5c:
980 chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
981 chip->model = PMAC_SNAPPER;
982 chip->can_byte_swap = 0; /* FIXME: check this */
983 chip->control_mask = MASK_IEPC | 0x11;/* disable IEE */
984 break;
985 case 0x3a:
986 chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
987 chip->model = PMAC_TOONIE;
988 chip->can_byte_swap = 0; /* FIXME: check this */
989 chip->control_mask = MASK_IEPC | 0x11;/* disable IEE */
990 break;
991 default:
992 printk(KERN_ERR "snd: Unknown layout ID 0x%x\n",
993 layout_id);
994 return -ENODEV;
995
996 }
997 }
998 prop = (unsigned int *)get_property(sound, "device-id", NULL); 970 prop = (unsigned int *)get_property(sound, "device-id", NULL);
999 if (prop) 971 if (prop)
1000 chip->device_id = *prop; 972 chip->device_id = *prop;
diff --git a/sound/ppc/pmac.h b/sound/ppc/pmac.h
index 3a9bd4dbb9a6..8394e66ceb00 100644
--- a/sound/ppc/pmac.h
+++ b/sound/ppc/pmac.h
@@ -85,7 +85,7 @@ struct pmac_stream {
85 85
86enum snd_pmac_model { 86enum snd_pmac_model {
87 PMAC_AWACS, PMAC_SCREAMER, PMAC_BURGUNDY, PMAC_DACA, PMAC_TUMBLER, 87 PMAC_AWACS, PMAC_SCREAMER, PMAC_BURGUNDY, PMAC_DACA, PMAC_TUMBLER,
88 PMAC_SNAPPER, PMAC_TOONIE 88 PMAC_SNAPPER
89}; 89};
90 90
91struct snd_pmac { 91struct snd_pmac {
@@ -188,7 +188,6 @@ int snd_pmac_burgundy_init(struct snd_pmac *chip);
188int snd_pmac_daca_init(struct snd_pmac *chip); 188int snd_pmac_daca_init(struct snd_pmac *chip);
189int snd_pmac_tumbler_init(struct snd_pmac *chip); 189int snd_pmac_tumbler_init(struct snd_pmac *chip);
190int snd_pmac_tumbler_post_init(void); 190int snd_pmac_tumbler_post_init(void);
191int snd_pmac_toonie_init(struct snd_pmac *chip);
192 191
193/* i2c functions */ 192/* i2c functions */
194struct pmac_keywest { 193struct pmac_keywest {
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index f4902a219e50..fa9a44ab487e 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -94,13 +94,6 @@ static int __init snd_pmac_probe(struct platform_device *devptr)
94 if ( snd_pmac_tumbler_init(chip) < 0 || snd_pmac_tumbler_post_init() < 0) 94 if ( snd_pmac_tumbler_init(chip) < 0 || snd_pmac_tumbler_post_init() < 0)
95 goto __error; 95 goto __error;
96 break; 96 break;
97 case PMAC_TOONIE:
98 strcpy(card->driver, "PMac Toonie");
99 strcpy(card->shortname, "PowerMac Toonie");
100 strcpy(card->longname, card->shortname);
101 if ((err = snd_pmac_toonie_init(chip)) < 0)
102 goto __error;
103 break;
104 case PMAC_AWACS: 97 case PMAC_AWACS:
105 case PMAC_SCREAMER: 98 case PMAC_SCREAMER:
106 name_ext = chip->model == PMAC_SCREAMER ? "Screamer" : "AWACS"; 99 name_ext = chip->model == PMAC_SCREAMER ? "Screamer" : "AWACS";
@@ -188,11 +181,15 @@ static int __init alsa_card_pmac_init(void)
188 if ((err = platform_driver_register(&snd_pmac_driver)) < 0) 181 if ((err = platform_driver_register(&snd_pmac_driver)) < 0)
189 return err; 182 return err;
190 device = platform_device_register_simple(SND_PMAC_DRIVER, -1, NULL, 0); 183 device = platform_device_register_simple(SND_PMAC_DRIVER, -1, NULL, 0);
191 if (IS_ERR(device)) { 184 if (!IS_ERR(device)) {
192 platform_driver_unregister(&snd_pmac_driver); 185 if (platform_get_drvdata(device))
193 return PTR_ERR(device); 186 return 0;
194 } 187 platform_device_unregister(device);
195 return 0; 188 err = -ENODEV;
189 } else
190 err = PTR_ERR(device);
191 platform_driver_unregister(&snd_pmac_driver);
192 return err;
196 193
197} 194}
198 195
diff --git a/sound/ppc/toonie.c b/sound/ppc/toonie.c
index 1ac7c8552f50..e69de29bb2d1 100644
--- a/sound/ppc/toonie.c
+++ b/sound/ppc/toonie.c
@@ -1,378 +0,0 @@
1/*
2 * Mac Mini "toonie" mixer control
3 *
4 * Copyright (c) 2005 by Benjamin Herrenschmidt <benh@kernel.crashing.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <sound/driver.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/i2c.h>
25#include <linux/kmod.h>
26#include <linux/slab.h>
27#include <linux/interrupt.h>
28#include <sound/core.h>
29#include <asm/io.h>
30#include <asm/irq.h>
31#include <asm/machdep.h>
32#include <asm/pmac_feature.h>
33#include "pmac.h"
34
35#undef DEBUG
36
37#ifdef DEBUG
38#define DBG(fmt...) printk(fmt)
39#else
40#define DBG(fmt...)
41#endif
42
43struct pmac_gpio {
44 unsigned int addr;
45 u8 active_val;
46 u8 inactive_val;
47 u8 active_state;
48};
49
50struct pmac_toonie
51{
52 struct pmac_gpio hp_detect_gpio;
53 struct pmac_gpio hp_mute_gpio;
54 struct pmac_gpio amp_mute_gpio;
55 int hp_detect_irq;
56 int auto_mute_notify;
57 struct work_struct detect_work;
58};
59
60
61/*
62 * gpio access
63 */
64#define do_gpio_write(gp, val) \
65 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, (gp)->addr, val)
66#define do_gpio_read(gp) \
67 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, (gp)->addr, 0)
68#define tumbler_gpio_free(gp) /* NOP */
69
70static void write_audio_gpio(struct pmac_gpio *gp, int active)
71{
72 if (! gp->addr)
73 return;
74 active = active ? gp->active_val : gp->inactive_val;
75 do_gpio_write(gp, active);
76 DBG("(I) gpio %x write %d\n", gp->addr, active);
77}
78
79static int check_audio_gpio(struct pmac_gpio *gp)
80{
81 int ret;
82
83 if (! gp->addr)
84 return 0;
85
86 ret = do_gpio_read(gp);
87
88 return (ret & 0xd) == (gp->active_val & 0xd);
89}
90
91static int read_audio_gpio(struct pmac_gpio *gp)
92{
93 int ret;
94 if (! gp->addr)
95 return 0;
96 ret = ((do_gpio_read(gp) & 0x02) !=0);
97 return ret == gp->active_state;
98}
99
100
101enum { TOONIE_MUTE_HP, TOONIE_MUTE_AMP };
102
103static int toonie_get_mute_switch(struct snd_kcontrol *kcontrol,
104 struct snd_ctl_elem_value *ucontrol)
105{
106 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
107 struct pmac_toonie *mix = chip->mixer_data;
108 struct pmac_gpio *gp;
109
110 if (mix == NULL)
111 return -ENODEV;
112 switch(kcontrol->private_value) {
113 case TOONIE_MUTE_HP:
114 gp = &mix->hp_mute_gpio;
115 break;
116 case TOONIE_MUTE_AMP:
117 gp = &mix->amp_mute_gpio;
118 break;
119 default:
120 return -EINVAL;
121 }
122 ucontrol->value.integer.value[0] = !check_audio_gpio(gp);
123 return 0;
124}
125
126static int toonie_put_mute_switch(struct snd_kcontrol *kcontrol,
127 struct snd_ctl_elem_value *ucontrol)
128{
129 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
130 struct pmac_toonie *mix = chip->mixer_data;
131 struct pmac_gpio *gp;
132 int val;
133
134 if (chip->update_automute && chip->auto_mute)
135 return 0; /* don't touch in the auto-mute mode */
136
137 if (mix == NULL)
138 return -ENODEV;
139
140 switch(kcontrol->private_value) {
141 case TOONIE_MUTE_HP:
142 gp = &mix->hp_mute_gpio;
143 break;
144 case TOONIE_MUTE_AMP:
145 gp = &mix->amp_mute_gpio;
146 break;
147 default:
148 return -EINVAL;
149 }
150 val = ! check_audio_gpio(gp);
151 if (val != ucontrol->value.integer.value[0]) {
152 write_audio_gpio(gp, ! ucontrol->value.integer.value[0]);
153 return 1;
154 }
155 return 0;
156}
157
158static struct snd_kcontrol_new toonie_hp_sw __initdata = {
159 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
160 .name = "Headphone Playback Switch",
161 .info = snd_pmac_boolean_mono_info,
162 .get = toonie_get_mute_switch,
163 .put = toonie_put_mute_switch,
164 .private_value = TOONIE_MUTE_HP,
165};
166static struct snd_kcontrol_new toonie_speaker_sw __initdata = {
167 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
168 .name = "PC Speaker Playback Switch",
169 .info = snd_pmac_boolean_mono_info,
170 .get = toonie_get_mute_switch,
171 .put = toonie_put_mute_switch,
172 .private_value = TOONIE_MUTE_AMP,
173};
174
175/*
176 * auto-mute stuffs
177 */
178static int toonie_detect_headphone(struct snd_pmac *chip)
179{
180 struct pmac_toonie *mix = chip->mixer_data;
181 int detect = 0;
182
183 if (mix->hp_detect_gpio.addr)
184 detect |= read_audio_gpio(&mix->hp_detect_gpio);
185 return detect;
186}
187
188static void toonie_check_mute(struct snd_pmac *chip, struct pmac_gpio *gp, int val,
189 int do_notify, struct snd_kcontrol *sw)
190{
191 if (check_audio_gpio(gp) != val) {
192 write_audio_gpio(gp, val);
193 if (do_notify)
194 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
195 &sw->id);
196 }
197}
198
199static void toonie_detect_handler(void *self)
200{
201 struct snd_pmac *chip = (struct snd_pmac *) self;
202 struct pmac_toonie *mix;
203 int headphone;
204
205 if (!chip)
206 return;
207
208 mix = chip->mixer_data;
209 snd_assert(mix, return);
210
211 headphone = toonie_detect_headphone(chip);
212
213 DBG("headphone: %d, lineout: %d\n", headphone, lineout);
214
215 if (headphone) {
216 /* unmute headphone/lineout & mute speaker */
217 toonie_check_mute(chip, &mix->hp_mute_gpio, 0,
218 mix->auto_mute_notify, chip->master_sw_ctl);
219 toonie_check_mute(chip, &mix->amp_mute_gpio, 1,
220 mix->auto_mute_notify, chip->speaker_sw_ctl);
221 } else {
222 /* unmute speaker, mute others */
223 toonie_check_mute(chip, &mix->amp_mute_gpio, 0,
224 mix->auto_mute_notify, chip->speaker_sw_ctl);
225 toonie_check_mute(chip, &mix->hp_mute_gpio, 1,
226 mix->auto_mute_notify, chip->master_sw_ctl);
227 }
228 if (mix->auto_mute_notify) {
229 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
230 &chip->hp_detect_ctl->id);
231 }
232}
233
234static void toonie_update_automute(struct snd_pmac *chip, int do_notify)
235{
236 if (chip->auto_mute) {
237 struct pmac_toonie *mix;
238 mix = chip->mixer_data;
239 snd_assert(mix, return);
240 mix->auto_mute_notify = do_notify;
241 schedule_work(&mix->detect_work);
242 }
243}
244
245/* interrupt - headphone plug changed */
246static irqreturn_t toonie_hp_intr(int irq, void *devid, struct pt_regs *regs)
247{
248 struct snd_pmac *chip = devid;
249
250 if (chip->update_automute && chip->initialized) {
251 chip->update_automute(chip, 1);
252 return IRQ_HANDLED;
253 }
254 return IRQ_NONE;
255}
256
257/* look for audio gpio device */
258static int find_audio_gpio(const char *name, const char *platform,
259 struct pmac_gpio *gp)
260{
261 struct device_node *np;
262 u32 *base, addr;
263
264 if (! (np = find_devices("gpio")))
265 return -ENODEV;
266
267 for (np = np->child; np; np = np->sibling) {
268 char *property = get_property(np, "audio-gpio", NULL);
269 if (property && strcmp(property, name) == 0)
270 break;
271 if (device_is_compatible(np, name))
272 break;
273 }
274 if (np == NULL)
275 return -ENODEV;
276
277 base = (u32 *)get_property(np, "AAPL,address", NULL);
278 if (! base) {
279 base = (u32 *)get_property(np, "reg", NULL);
280 if (!base) {
281 DBG("(E) cannot find address for device %s !\n", name);
282 return -ENODEV;
283 }
284 addr = *base;
285 if (addr < 0x50)
286 addr += 0x50;
287 } else
288 addr = *base;
289
290 gp->addr = addr & 0x0000ffff;
291
292 /* Try to find the active state, default to 0 ! */
293 base = (u32 *)get_property(np, "audio-gpio-active-state", NULL);
294 if (base) {
295 gp->active_state = *base;
296 gp->active_val = (*base) ? 0x5 : 0x4;
297 gp->inactive_val = (*base) ? 0x4 : 0x5;
298 } else {
299 u32 *prop = NULL;
300 gp->active_state = 0;
301 gp->active_val = 0x4;
302 gp->inactive_val = 0x5;
303 /* Here are some crude hacks to extract the GPIO polarity and
304 * open collector informations out of the do-platform script
305 * as we don't yet have an interpreter for these things
306 */
307 if (platform)
308 prop = (u32 *)get_property(np, platform, NULL);
309 if (prop) {
310 if (prop[3] == 0x9 && prop[4] == 0x9) {
311 gp->active_val = 0xd;
312 gp->inactive_val = 0xc;
313 }
314 if (prop[3] == 0x1 && prop[4] == 0x1) {
315 gp->active_val = 0x5;
316 gp->inactive_val = 0x4;
317 }
318 }
319 }
320
321 DBG("(I) GPIO device %s found, offset: %x, active state: %d !\n",
322 name, gp->addr, gp->active_state);
323
324 return (np->n_intrs > 0) ? np->intrs[0].line : 0;
325}
326
327static void toonie_cleanup(struct snd_pmac *chip)
328{
329 struct pmac_toonie *mix = chip->mixer_data;
330 if (! mix)
331 return;
332 if (mix->hp_detect_irq >= 0)
333 free_irq(mix->hp_detect_irq, chip);
334 kfree(mix);
335 chip->mixer_data = NULL;
336}
337
338int __init snd_pmac_toonie_init(struct snd_pmac *chip)
339{
340 struct pmac_toonie *mix;
341
342 mix = kmalloc(sizeof(*mix), GFP_KERNEL);
343 if (! mix)
344 return -ENOMEM;
345
346 chip->mixer_data = mix;
347 chip->mixer_free = toonie_cleanup;
348
349 find_audio_gpio("headphone-mute", NULL, &mix->hp_mute_gpio);
350 find_audio_gpio("amp-mute", NULL, &mix->amp_mute_gpio);
351 mix->hp_detect_irq = find_audio_gpio("headphone-detect",
352 NULL, &mix->hp_detect_gpio);
353
354 strcpy(chip->card->mixername, "PowerMac Toonie");
355
356 chip->master_sw_ctl = snd_ctl_new1(&toonie_hp_sw, chip);
357 snd_ctl_add(chip->card, chip->master_sw_ctl);
358
359 chip->speaker_sw_ctl = snd_ctl_new1(&toonie_speaker_sw, chip);
360 snd_ctl_add(chip->card, chip->speaker_sw_ctl);
361
362 INIT_WORK(&mix->detect_work, toonie_detect_handler, (void *)chip);
363
364 if (mix->hp_detect_irq >= 0) {
365 snd_pmac_add_automute(chip);
366
367 chip->detect_headphone = toonie_detect_headphone;
368 chip->update_automute = toonie_update_automute;
369 toonie_update_automute(chip, 0);
370
371 if (request_irq(mix->hp_detect_irq, toonie_hp_intr, 0,
372 "Sound Headphone Detection", chip) < 0)
373 mix->hp_detect_irq = -1;
374 }
375
376 return 0;
377}
378
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index e622d08215c9..5eecdd09a79d 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -92,7 +92,7 @@ MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard.");
92#define D_USR (1<<4) 92#define D_USR (1<<4)
93#define D_DESC (1<<5) 93#define D_DESC (1<<5)
94 94
95static int dbri_debug = 0; 95static int dbri_debug;
96module_param(dbri_debug, int, 0644); 96module_param(dbri_debug, int, 0644);
97MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard."); 97MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard.");
98 98
@@ -593,7 +593,7 @@ struct snd_dbri {
593/* Return a pointer to dbri_streaminfo */ 593/* Return a pointer to dbri_streaminfo */
594#define DBRI_STREAM(dbri, substream) &dbri->stream_info[DBRI_STREAMNO(substream)] 594#define DBRI_STREAM(dbri, substream) &dbri->stream_info[DBRI_STREAMNO(substream)]
595 595
596static struct snd_dbri *dbri_list = NULL; /* All DBRI devices */ 596static struct snd_dbri *dbri_list; /* All DBRI devices */
597 597
598/* 598/*
599 * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr. 599 * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr.
@@ -2521,11 +2521,11 @@ void snd_dbri_proc(struct snd_dbri * dbri)
2521 struct snd_info_entry *entry; 2521 struct snd_info_entry *entry;
2522 2522
2523 if (! snd_card_proc_new(dbri->card, "regs", &entry)) 2523 if (! snd_card_proc_new(dbri->card, "regs", &entry))
2524 snd_info_set_text_ops(entry, dbri, 1024, dbri_regs_read); 2524 snd_info_set_text_ops(entry, dbri, dbri_regs_read);
2525 2525
2526#ifdef DBRI_DEBUG 2526#ifdef DBRI_DEBUG
2527 if (! snd_card_proc_new(dbri->card, "debug", &entry)) { 2527 if (! snd_card_proc_new(dbri->card, "debug", &entry)) {
2528 snd_info_set_text_ops(entry, dbri, 4096, dbri_debug_read); 2528 snd_info_set_text_ops(entry, dbri, dbri_debug_read);
2529 entry->mode = S_IFREG | S_IRUGO; /* Readable only. */ 2529 entry->mode = S_IFREG | S_IRUGO; /* Readable only. */
2530 } 2530 }
2531#endif 2531#endif
diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c
index fc733bbf4487..573e3701c14f 100644
--- a/sound/synth/emux/emux.c
+++ b/sound/synth/emux/emux.c
@@ -63,6 +63,7 @@ int snd_emux_new(struct snd_emux **remu)
63 return 0; 63 return 0;
64} 64}
65 65
66EXPORT_SYMBOL(snd_emux_new);
66 67
67/* 68/*
68 */ 69 */
@@ -136,6 +137,7 @@ int snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, ch
136 return 0; 137 return 0;
137} 138}
138 139
140EXPORT_SYMBOL(snd_emux_register);
139 141
140/* 142/*
141 */ 143 */
@@ -171,18 +173,8 @@ int snd_emux_free(struct snd_emux *emu)
171 return 0; 173 return 0;
172} 174}
173 175
174
175EXPORT_SYMBOL(snd_emux_new);
176EXPORT_SYMBOL(snd_emux_register);
177EXPORT_SYMBOL(snd_emux_free); 176EXPORT_SYMBOL(snd_emux_free);
178 177
179EXPORT_SYMBOL(snd_emux_terminate_all);
180EXPORT_SYMBOL(snd_emux_lock_voice);
181EXPORT_SYMBOL(snd_emux_unlock_voice);
182
183/* soundfont.c */
184EXPORT_SYMBOL(snd_sf_linear_to_log);
185
186 178
187/* 179/*
188 * INIT part 180 * INIT part
diff --git a/sound/synth/emux/emux_proc.c b/sound/synth/emux/emux_proc.c
index 1ba68ce30279..58b9601f3ad0 100644
--- a/sound/synth/emux/emux_proc.c
+++ b/sound/synth/emux/emux_proc.c
@@ -119,7 +119,6 @@ void snd_emux_proc_init(struct snd_emux *emu, struct snd_card *card, int device)
119 119
120 entry->content = SNDRV_INFO_CONTENT_TEXT; 120 entry->content = SNDRV_INFO_CONTENT_TEXT;
121 entry->private_data = emu; 121 entry->private_data = emu;
122 entry->c.text.read_size = 1024;
123 entry->c.text.read = snd_emux_proc_info_read; 122 entry->c.text.read = snd_emux_proc_info_read;
124 if (snd_info_register(entry) < 0) 123 if (snd_info_register(entry) < 0)
125 snd_info_free_entry(entry); 124 snd_info_free_entry(entry);
diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c
index 8f00f07701c4..d176cc01742d 100644
--- a/sound/synth/emux/emux_seq.c
+++ b/sound/synth/emux/emux_seq.c
@@ -55,7 +55,8 @@ static struct snd_midi_op emux_ops = {
55 SNDRV_SEQ_PORT_TYPE_MIDI_GM |\ 55 SNDRV_SEQ_PORT_TYPE_MIDI_GM |\
56 SNDRV_SEQ_PORT_TYPE_MIDI_GS |\ 56 SNDRV_SEQ_PORT_TYPE_MIDI_GS |\
57 SNDRV_SEQ_PORT_TYPE_MIDI_XG |\ 57 SNDRV_SEQ_PORT_TYPE_MIDI_XG |\
58 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE) 58 SNDRV_SEQ_PORT_TYPE_HARDWARE |\
59 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER)
59 60
60/* 61/*
61 * Initialise the EMUX Synth by creating a client and registering 62 * Initialise the EMUX Synth by creating a client and registering
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c
index 24705d15ebd8..3733118d39bb 100644
--- a/sound/synth/emux/emux_synth.c
+++ b/sound/synth/emux/emux_synth.c
@@ -434,6 +434,7 @@ snd_emux_terminate_all(struct snd_emux *emu)
434 spin_unlock_irqrestore(&emu->voice_lock, flags); 434 spin_unlock_irqrestore(&emu->voice_lock, flags);
435} 435}
436 436
437EXPORT_SYMBOL(snd_emux_terminate_all);
437 438
438/* 439/*
439 * Terminate all voices associated with the given port 440 * Terminate all voices associated with the given port
@@ -951,6 +952,8 @@ void snd_emux_lock_voice(struct snd_emux *emu, int voice)
951 spin_unlock_irqrestore(&emu->voice_lock, flags); 952 spin_unlock_irqrestore(&emu->voice_lock, flags);
952} 953}
953 954
955EXPORT_SYMBOL(snd_emux_lock_voice);
956
954/* 957/*
955 */ 958 */
956void snd_emux_unlock_voice(struct snd_emux *emu, int voice) 959void snd_emux_unlock_voice(struct snd_emux *emu, int voice)
@@ -965,3 +968,5 @@ void snd_emux_unlock_voice(struct snd_emux *emu, int voice)
965 voice, emu->voices[voice].state); 968 voice, emu->voices[voice].state);
966 spin_unlock_irqrestore(&emu->voice_lock, flags); 969 spin_unlock_irqrestore(&emu->voice_lock, flags);
967} 970}
971
972EXPORT_SYMBOL(snd_emux_unlock_voice);
diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c
index 32c27162dfb6..455e535933ec 100644
--- a/sound/synth/emux/soundfont.c
+++ b/sound/synth/emux/soundfont.c
@@ -195,7 +195,7 @@ snd_soundfont_load(struct snd_sf_list *sflist, const void __user *data,
195 break; 195 break;
196 case SNDRV_SFNT_REMOVE_INFO: 196 case SNDRV_SFNT_REMOVE_INFO:
197 /* patch must be opened */ 197 /* patch must be opened */
198 if (sflist->currsf) { 198 if (!sflist->currsf) {
199 snd_printk("soundfont: remove_info: patch not opened\n"); 199 snd_printk("soundfont: remove_info: patch not opened\n");
200 rc = -EINVAL; 200 rc = -EINVAL;
201 } else { 201 } else {
@@ -810,6 +810,9 @@ snd_sf_linear_to_log(unsigned int amount, int offset, int ratio)
810 return v; 810 return v;
811} 811}
812 812
813EXPORT_SYMBOL(snd_sf_linear_to_log);
814
815
813#define OFFSET_MSEC 653117 /* base = 1000 */ 816#define OFFSET_MSEC 653117 /* base = 1000 */
814#define OFFSET_ABSCENT 851781 /* base = 8176 */ 817#define OFFSET_ABSCENT 851781 /* base = 8176 */
815#define OFFSET_SAMPLERATE 1011119 /* base = 44100 */ 818#define OFFSET_SAMPLERATE 1011119 /* base = 44100 */
@@ -1485,4 +1488,3 @@ snd_soundfont_remove_unlocked(struct snd_sf_list *sflist)
1485 unlock_preset(sflist); 1488 unlock_preset(sflist);
1486 return 0; 1489 return 0;
1487} 1490}
1488
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 4e614ac39f21..627de9525a32 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -2138,7 +2138,7 @@ static void proc_pcm_format_add(struct snd_usb_stream *stream)
2138 2138
2139 sprintf(name, "stream%d", stream->pcm_index); 2139 sprintf(name, "stream%d", stream->pcm_index);
2140 if (! snd_card_proc_new(card, name, &entry)) 2140 if (! snd_card_proc_new(card, name, &entry))
2141 snd_info_set_text_ops(entry, stream, 1024, proc_pcm_format_read); 2141 snd_info_set_text_ops(entry, stream, proc_pcm_format_read);
2142} 2142}
2143 2143
2144#else 2144#else
@@ -2627,9 +2627,10 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2627 if (!csep && altsd->bNumEndpoints >= 2) 2627 if (!csep && altsd->bNumEndpoints >= 2)
2628 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); 2628 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
2629 if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) { 2629 if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) {
2630 snd_printk(KERN_ERR "%d:%u:%d : no or invalid class specific endpoint descriptor\n", 2630 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
2631 " class specific endpoint descriptor\n",
2631 dev->devnum, iface_no, altno); 2632 dev->devnum, iface_no, altno);
2632 continue; 2633 csep = NULL;
2633 } 2634 }
2634 2635
2635 fp = kmalloc(sizeof(*fp), GFP_KERNEL); 2636 fp = kmalloc(sizeof(*fp), GFP_KERNEL);
@@ -2648,7 +2649,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2648 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) 2649 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
2649 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) 2650 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
2650 * (fp->maxpacksize & 0x7ff); 2651 * (fp->maxpacksize & 0x7ff);
2651 fp->attributes = csep[3]; 2652 fp->attributes = csep ? csep[3] : 0;
2652 2653
2653 /* some quirks for attributes here */ 2654 /* some quirks for attributes here */
2654 2655
@@ -2980,7 +2981,7 @@ static int create_ua1000_quirk(struct snd_usb_audio *chip,
2980 return -ENXIO; 2981 return -ENXIO;
2981 alts = &iface->altsetting[1]; 2982 alts = &iface->altsetting[1];
2982 altsd = get_iface_desc(alts); 2983 altsd = get_iface_desc(alts);
2983 if (alts->extralen != 11 || alts->extra[1] != CS_AUDIO_INTERFACE || 2984 if (alts->extralen != 11 || alts->extra[1] != USB_DT_CS_INTERFACE ||
2984 altsd->bNumEndpoints != 1) 2985 altsd->bNumEndpoints != 1)
2985 return -ENXIO; 2986 return -ENXIO;
2986 2987
@@ -3197,9 +3198,9 @@ static void snd_usb_audio_create_proc(struct snd_usb_audio *chip)
3197{ 3198{
3198 struct snd_info_entry *entry; 3199 struct snd_info_entry *entry;
3199 if (! snd_card_proc_new(chip->card, "usbbus", &entry)) 3200 if (! snd_card_proc_new(chip->card, "usbbus", &entry))
3200 snd_info_set_text_ops(entry, chip, 1024, proc_audio_usbbus_read); 3201 snd_info_set_text_ops(entry, chip, proc_audio_usbbus_read);
3201 if (! snd_card_proc_new(chip->card, "usbid", &entry)) 3202 if (! snd_card_proc_new(chip->card, "usbid", &entry))
3202 snd_info_set_text_ops(entry, chip, 1024, proc_audio_usbid_read); 3203 snd_info_set_text_ops(entry, chip, proc_audio_usbid_read);
3203} 3204}
3204 3205
3205/* 3206/*
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 88733524d0fb..0f4b2b8541d6 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -30,13 +30,6 @@
30#define USB_SUBCLASS_MIDI_STREAMING 0x03 30#define USB_SUBCLASS_MIDI_STREAMING 0x03
31#define USB_SUBCLASS_VENDOR_SPEC 0xff 31#define USB_SUBCLASS_VENDOR_SPEC 0xff
32 32
33#define CS_AUDIO_UNDEFINED 0x20
34#define CS_AUDIO_DEVICE 0x21
35#define CS_AUDIO_CONFIGURATION 0x22
36#define CS_AUDIO_STRING 0x23
37#define CS_AUDIO_INTERFACE 0x24
38#define CS_AUDIO_ENDPOINT 0x25
39
40#define HEADER 0x01 33#define HEADER 0x01
41#define INPUT_TERMINAL 0x02 34#define INPUT_TERMINAL 0x02
42#define OUTPUT_TERMINAL 0x03 35#define OUTPUT_TERMINAL 0x03
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 2b9d940c8064..5105b6b05748 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -48,6 +48,7 @@
48#include <linux/usb.h> 48#include <linux/usb.h>
49#include <sound/core.h> 49#include <sound/core.h>
50#include <sound/rawmidi.h> 50#include <sound/rawmidi.h>
51#include <sound/asequencer.h>
51#include "usbaudio.h" 52#include "usbaudio.h"
52 53
53 54
@@ -1010,97 +1011,157 @@ static struct snd_rawmidi_substream *snd_usbmidi_find_substream(struct snd_usb_m
1010 * "(product) MIDI (n)" schema because they aren't external MIDI ports, 1011 * "(product) MIDI (n)" schema because they aren't external MIDI ports,
1011 * such as internal control or synthesizer ports. 1012 * such as internal control or synthesizer ports.
1012 */ 1013 */
1013static struct { 1014static struct port_info {
1014 u32 id; 1015 u32 id;
1015 int port; 1016 short int port;
1016 const char *name_format; 1017 short int voices;
1017} snd_usbmidi_port_names[] = { 1018 const char *name;
1019 unsigned int seq_flags;
1020} snd_usbmidi_port_info[] = {
1021#define PORT_INFO(vendor, product, num, name_, voices_, flags) \
1022 { .id = USB_ID(vendor, product), \
1023 .port = num, .voices = voices_, \
1024 .name = name_, .seq_flags = flags }
1025#define EXTERNAL_PORT(vendor, product, num, name) \
1026 PORT_INFO(vendor, product, num, name, 0, \
1027 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
1028 SNDRV_SEQ_PORT_TYPE_HARDWARE | \
1029 SNDRV_SEQ_PORT_TYPE_PORT)
1030#define CONTROL_PORT(vendor, product, num, name) \
1031 PORT_INFO(vendor, product, num, name, 0, \
1032 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
1033 SNDRV_SEQ_PORT_TYPE_HARDWARE)
1034#define ROLAND_SYNTH_PORT(vendor, product, num, name, voices) \
1035 PORT_INFO(vendor, product, num, name, voices, \
1036 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
1037 SNDRV_SEQ_PORT_TYPE_MIDI_GM | \
1038 SNDRV_SEQ_PORT_TYPE_MIDI_GM2 | \
1039 SNDRV_SEQ_PORT_TYPE_MIDI_GS | \
1040 SNDRV_SEQ_PORT_TYPE_MIDI_XG | \
1041 SNDRV_SEQ_PORT_TYPE_HARDWARE | \
1042 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER)
1043#define SOUNDCANVAS_PORT(vendor, product, num, name, voices) \
1044 PORT_INFO(vendor, product, num, name, voices, \
1045 SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
1046 SNDRV_SEQ_PORT_TYPE_MIDI_GM | \
1047 SNDRV_SEQ_PORT_TYPE_MIDI_GM2 | \
1048 SNDRV_SEQ_PORT_TYPE_MIDI_GS | \
1049 SNDRV_SEQ_PORT_TYPE_MIDI_XG | \
1050 SNDRV_SEQ_PORT_TYPE_MIDI_MT32 | \
1051 SNDRV_SEQ_PORT_TYPE_HARDWARE | \
1052 SNDRV_SEQ_PORT_TYPE_SYNTHESIZER)
1018 /* Roland UA-100 */ 1053 /* Roland UA-100 */
1019 { USB_ID(0x0582, 0x0000), 2, "%s Control" }, 1054 CONTROL_PORT(0x0582, 0x0000, 2, "%s Control"),
1020 /* Roland SC-8850 */ 1055 /* Roland SC-8850 */
1021 { USB_ID(0x0582, 0x0003), 0, "%s Part A" }, 1056 SOUNDCANVAS_PORT(0x0582, 0x0003, 0, "%s Part A", 128),
1022 { USB_ID(0x0582, 0x0003), 1, "%s Part B" }, 1057 SOUNDCANVAS_PORT(0x0582, 0x0003, 1, "%s Part B", 128),
1023 { USB_ID(0x0582, 0x0003), 2, "%s Part C" }, 1058 SOUNDCANVAS_PORT(0x0582, 0x0003, 2, "%s Part C", 128),
1024 { USB_ID(0x0582, 0x0003), 3, "%s Part D" }, 1059 SOUNDCANVAS_PORT(0x0582, 0x0003, 3, "%s Part D", 128),
1025 { USB_ID(0x0582, 0x0003), 4, "%s MIDI 1" }, 1060 EXTERNAL_PORT(0x0582, 0x0003, 4, "%s MIDI 1"),
1026 { USB_ID(0x0582, 0x0003), 5, "%s MIDI 2" }, 1061 EXTERNAL_PORT(0x0582, 0x0003, 5, "%s MIDI 2"),
1027 /* Roland U-8 */ 1062 /* Roland U-8 */
1028 { USB_ID(0x0582, 0x0004), 0, "%s MIDI" }, 1063 EXTERNAL_PORT(0x0582, 0x0004, 0, "%s MIDI"),
1029 { USB_ID(0x0582, 0x0004), 1, "%s Control" }, 1064 CONTROL_PORT(0x0582, 0x0004, 1, "%s Control"),
1030 /* Roland SC-8820 */ 1065 /* Roland SC-8820 */
1031 { USB_ID(0x0582, 0x0007), 0, "%s Part A" }, 1066 SOUNDCANVAS_PORT(0x0582, 0x0007, 0, "%s Part A", 64),
1032 { USB_ID(0x0582, 0x0007), 1, "%s Part B" }, 1067 SOUNDCANVAS_PORT(0x0582, 0x0007, 1, "%s Part B", 64),
1033 { USB_ID(0x0582, 0x0007), 2, "%s MIDI" }, 1068 EXTERNAL_PORT(0x0582, 0x0007, 2, "%s MIDI"),
1034 /* Roland SK-500 */ 1069 /* Roland SK-500 */
1035 { USB_ID(0x0582, 0x000b), 0, "%s Part A" }, 1070 SOUNDCANVAS_PORT(0x0582, 0x000b, 0, "%s Part A", 64),
1036 { USB_ID(0x0582, 0x000b), 1, "%s Part B" }, 1071 SOUNDCANVAS_PORT(0x0582, 0x000b, 1, "%s Part B", 64),
1037 { USB_ID(0x0582, 0x000b), 2, "%s MIDI" }, 1072 EXTERNAL_PORT(0x0582, 0x000b, 2, "%s MIDI"),
1038 /* Roland SC-D70 */ 1073 /* Roland SC-D70 */
1039 { USB_ID(0x0582, 0x000c), 0, "%s Part A" }, 1074 SOUNDCANVAS_PORT(0x0582, 0x000c, 0, "%s Part A", 64),
1040 { USB_ID(0x0582, 0x000c), 1, "%s Part B" }, 1075 SOUNDCANVAS_PORT(0x0582, 0x000c, 1, "%s Part B", 64),
1041 { USB_ID(0x0582, 0x000c), 2, "%s MIDI" }, 1076 EXTERNAL_PORT(0x0582, 0x000c, 2, "%s MIDI"),
1042 /* Edirol UM-880 */ 1077 /* Edirol UM-880 */
1043 { USB_ID(0x0582, 0x0014), 8, "%s Control" }, 1078 CONTROL_PORT(0x0582, 0x0014, 8, "%s Control"),
1044 /* Edirol SD-90 */ 1079 /* Edirol SD-90 */
1045 { USB_ID(0x0582, 0x0016), 0, "%s Part A" }, 1080 ROLAND_SYNTH_PORT(0x0582, 0x0016, 0, "%s Part A", 128),
1046 { USB_ID(0x0582, 0x0016), 1, "%s Part B" }, 1081 ROLAND_SYNTH_PORT(0x0582, 0x0016, 1, "%s Part B", 128),
1047 { USB_ID(0x0582, 0x0016), 2, "%s MIDI 1" }, 1082 EXTERNAL_PORT(0x0582, 0x0016, 2, "%s MIDI 1"),
1048 { USB_ID(0x0582, 0x0016), 3, "%s MIDI 2" }, 1083 EXTERNAL_PORT(0x0582, 0x0016, 3, "%s MIDI 2"),
1049 /* Edirol UM-550 */ 1084 /* Edirol UM-550 */
1050 { USB_ID(0x0582, 0x0023), 5, "%s Control" }, 1085 CONTROL_PORT(0x0582, 0x0023, 5, "%s Control"),
1051 /* Edirol SD-20 */ 1086 /* Edirol SD-20 */
1052 { USB_ID(0x0582, 0x0027), 0, "%s Part A" }, 1087 ROLAND_SYNTH_PORT(0x0582, 0x0027, 0, "%s Part A", 64),
1053 { USB_ID(0x0582, 0x0027), 1, "%s Part B" }, 1088 ROLAND_SYNTH_PORT(0x0582, 0x0027, 1, "%s Part B", 64),
1054 { USB_ID(0x0582, 0x0027), 2, "%s MIDI" }, 1089 EXTERNAL_PORT(0x0582, 0x0027, 2, "%s MIDI"),
1055 /* Edirol SD-80 */ 1090 /* Edirol SD-80 */
1056 { USB_ID(0x0582, 0x0029), 0, "%s Part A" }, 1091 ROLAND_SYNTH_PORT(0x0582, 0x0029, 0, "%s Part A", 128),
1057 { USB_ID(0x0582, 0x0029), 1, "%s Part B" }, 1092 ROLAND_SYNTH_PORT(0x0582, 0x0029, 1, "%s Part B", 128),
1058 { USB_ID(0x0582, 0x0029), 2, "%s MIDI 1" }, 1093 EXTERNAL_PORT(0x0582, 0x0029, 2, "%s MIDI 1"),
1059 { USB_ID(0x0582, 0x0029), 3, "%s MIDI 2" }, 1094 EXTERNAL_PORT(0x0582, 0x0029, 3, "%s MIDI 2"),
1060 /* Edirol UA-700 */ 1095 /* Edirol UA-700 */
1061 { USB_ID(0x0582, 0x002b), 0, "%s MIDI" }, 1096 EXTERNAL_PORT(0x0582, 0x002b, 0, "%s MIDI"),
1062 { USB_ID(0x0582, 0x002b), 1, "%s Control" }, 1097 CONTROL_PORT(0x0582, 0x002b, 1, "%s Control"),
1063 /* Roland VariOS */ 1098 /* Roland VariOS */
1064 { USB_ID(0x0582, 0x002f), 0, "%s MIDI" }, 1099 EXTERNAL_PORT(0x0582, 0x002f, 0, "%s MIDI"),
1065 { USB_ID(0x0582, 0x002f), 1, "%s External MIDI" }, 1100 EXTERNAL_PORT(0x0582, 0x002f, 1, "%s External MIDI"),
1066 { USB_ID(0x0582, 0x002f), 2, "%s Sync" }, 1101 EXTERNAL_PORT(0x0582, 0x002f, 2, "%s Sync"),
1067 /* Edirol PCR */ 1102 /* Edirol PCR */
1068 { USB_ID(0x0582, 0x0033), 0, "%s MIDI" }, 1103 EXTERNAL_PORT(0x0582, 0x0033, 0, "%s MIDI"),
1069 { USB_ID(0x0582, 0x0033), 1, "%s 1" }, 1104 EXTERNAL_PORT(0x0582, 0x0033, 1, "%s 1"),
1070 { USB_ID(0x0582, 0x0033), 2, "%s 2" }, 1105 EXTERNAL_PORT(0x0582, 0x0033, 2, "%s 2"),
1071 /* BOSS GS-10 */ 1106 /* BOSS GS-10 */
1072 { USB_ID(0x0582, 0x003b), 0, "%s MIDI" }, 1107 EXTERNAL_PORT(0x0582, 0x003b, 0, "%s MIDI"),
1073 { USB_ID(0x0582, 0x003b), 1, "%s Control" }, 1108 CONTROL_PORT(0x0582, 0x003b, 1, "%s Control"),
1074 /* Edirol UA-1000 */ 1109 /* Edirol UA-1000 */
1075 { USB_ID(0x0582, 0x0044), 0, "%s MIDI" }, 1110 EXTERNAL_PORT(0x0582, 0x0044, 0, "%s MIDI"),
1076 { USB_ID(0x0582, 0x0044), 1, "%s Control" }, 1111 CONTROL_PORT(0x0582, 0x0044, 1, "%s Control"),
1077 /* Edirol UR-80 */ 1112 /* Edirol UR-80 */
1078 { USB_ID(0x0582, 0x0048), 0, "%s MIDI" }, 1113 EXTERNAL_PORT(0x0582, 0x0048, 0, "%s MIDI"),
1079 { USB_ID(0x0582, 0x0048), 1, "%s 1" }, 1114 EXTERNAL_PORT(0x0582, 0x0048, 1, "%s 1"),
1080 { USB_ID(0x0582, 0x0048), 2, "%s 2" }, 1115 EXTERNAL_PORT(0x0582, 0x0048, 2, "%s 2"),
1081 /* Edirol PCR-A */ 1116 /* Edirol PCR-A */
1082 { USB_ID(0x0582, 0x004d), 0, "%s MIDI" }, 1117 EXTERNAL_PORT(0x0582, 0x004d, 0, "%s MIDI"),
1083 { USB_ID(0x0582, 0x004d), 1, "%s 1" }, 1118 EXTERNAL_PORT(0x0582, 0x004d, 1, "%s 1"),
1084 { USB_ID(0x0582, 0x004d), 2, "%s 2" }, 1119 EXTERNAL_PORT(0x0582, 0x004d, 2, "%s 2"),
1085 /* Edirol UM-3EX */ 1120 /* Edirol UM-3EX */
1086 { USB_ID(0x0582, 0x009a), 3, "%s Control" }, 1121 CONTROL_PORT(0x0582, 0x009a, 3, "%s Control"),
1087 /* M-Audio MidiSport 8x8 */ 1122 /* M-Audio MidiSport 8x8 */
1088 { USB_ID(0x0763, 0x1031), 8, "%s Control" }, 1123 CONTROL_PORT(0x0763, 0x1031, 8, "%s Control"),
1089 { USB_ID(0x0763, 0x1033), 8, "%s Control" }, 1124 CONTROL_PORT(0x0763, 0x1033, 8, "%s Control"),
1090 /* MOTU Fastlane */ 1125 /* MOTU Fastlane */
1091 { USB_ID(0x07fd, 0x0001), 0, "%s MIDI A" }, 1126 EXTERNAL_PORT(0x07fd, 0x0001, 0, "%s MIDI A"),
1092 { USB_ID(0x07fd, 0x0001), 1, "%s MIDI B" }, 1127 EXTERNAL_PORT(0x07fd, 0x0001, 1, "%s MIDI B"),
1093 /* Emagic Unitor8/AMT8/MT4 */ 1128 /* Emagic Unitor8/AMT8/MT4 */
1094 { USB_ID(0x086a, 0x0001), 8, "%s Broadcast" }, 1129 EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"),
1095 { USB_ID(0x086a, 0x0002), 8, "%s Broadcast" }, 1130 EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"),
1096 { USB_ID(0x086a, 0x0003), 4, "%s Broadcast" }, 1131 EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"),
1097}; 1132};
1098 1133
1134static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number)
1135{
1136 int i;
1137
1138 for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_info); ++i) {
1139 if (snd_usbmidi_port_info[i].id == umidi->chip->usb_id &&
1140 snd_usbmidi_port_info[i].port == number)
1141 return &snd_usbmidi_port_info[i];
1142 }
1143 return NULL;
1144}
1145
1146static void snd_usbmidi_get_port_info(struct snd_rawmidi *rmidi, int number,
1147 struct snd_seq_port_info *seq_port_info)
1148{
1149 struct snd_usb_midi *umidi = rmidi->private_data;
1150 struct port_info *port_info;
1151
1152 /* TODO: read port flags from descriptors */
1153 port_info = find_port_info(umidi, number);
1154 if (port_info) {
1155 seq_port_info->type = port_info->seq_flags;
1156 seq_port_info->midi_voices = port_info->voices;
1157 }
1158}
1159
1099static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi, 1160static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi,
1100 int stream, int number, 1161 int stream, int number,
1101 struct snd_rawmidi_substream ** rsubstream) 1162 struct snd_rawmidi_substream ** rsubstream)
1102{ 1163{
1103 int i; 1164 struct port_info *port_info;
1104 const char *name_format; 1165 const char *name_format;
1105 1166
1106 struct snd_rawmidi_substream *substream = snd_usbmidi_find_substream(umidi, stream, number); 1167 struct snd_rawmidi_substream *substream = snd_usbmidi_find_substream(umidi, stream, number);
@@ -1110,14 +1171,8 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi,
1110 } 1171 }
1111 1172
1112 /* TODO: read port name from jack descriptor */ 1173 /* TODO: read port name from jack descriptor */
1113 name_format = "%s MIDI %d"; 1174 port_info = find_port_info(umidi, number);
1114 for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_names); ++i) { 1175 name_format = port_info ? port_info->name : "%s MIDI %d";
1115 if (snd_usbmidi_port_names[i].id == umidi->chip->usb_id &&
1116 snd_usbmidi_port_names[i].port == number) {
1117 name_format = snd_usbmidi_port_names[i].name_format;
1118 break;
1119 }
1120 }
1121 snprintf(substream->name, sizeof(substream->name), 1176 snprintf(substream->name, sizeof(substream->name),
1122 name_format, umidi->chip->card->shortname, number + 1); 1177 name_format, umidi->chip->card->shortname, number + 1);
1123 1178
@@ -1358,7 +1413,7 @@ static int snd_usbmidi_detect_yamaha(struct snd_usb_midi* umidi,
1358 for (cs_desc = hostif->extra; 1413 for (cs_desc = hostif->extra;
1359 cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2; 1414 cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2;
1360 cs_desc += cs_desc[0]) { 1415 cs_desc += cs_desc[0]) {
1361 if (cs_desc[1] == CS_AUDIO_INTERFACE) { 1416 if (cs_desc[1] == USB_DT_CS_INTERFACE) {
1362 if (cs_desc[2] == MIDI_IN_JACK) 1417 if (cs_desc[2] == MIDI_IN_JACK)
1363 endpoint->in_cables = (endpoint->in_cables << 1) | 1; 1418 endpoint->in_cables = (endpoint->in_cables << 1) | 1;
1364 else if (cs_desc[2] == MIDI_OUT_JACK) 1419 else if (cs_desc[2] == MIDI_OUT_JACK)
@@ -1457,6 +1512,10 @@ static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi* umidi,
1457 return 0; 1512 return 0;
1458} 1513}
1459 1514
1515static struct snd_rawmidi_global_ops snd_usbmidi_ops = {
1516 .get_port_info = snd_usbmidi_get_port_info,
1517};
1518
1460static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi, 1519static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi,
1461 int out_ports, int in_ports) 1520 int out_ports, int in_ports)
1462{ 1521{
@@ -1472,6 +1531,7 @@ static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi,
1472 rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | 1531 rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
1473 SNDRV_RAWMIDI_INFO_INPUT | 1532 SNDRV_RAWMIDI_INFO_INPUT |
1474 SNDRV_RAWMIDI_INFO_DUPLEX; 1533 SNDRV_RAWMIDI_INFO_DUPLEX;
1534 rmidi->ops = &snd_usbmidi_ops;
1475 rmidi->private_data = umidi; 1535 rmidi->private_data = umidi;
1476 rmidi->private_free = snd_usbmidi_rawmidi_free; 1536 rmidi->private_free = snd_usbmidi_rawmidi_free;
1477 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_usbmidi_output_ops); 1537 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_usbmidi_output_ops);
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index ce86283ee0fa..491e975a0c87 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -46,6 +46,27 @@
46/* ignore error from controls - for debugging */ 46/* ignore error from controls - for debugging */
47/* #define IGNORE_CTL_ERROR */ 47/* #define IGNORE_CTL_ERROR */
48 48
49/*
50 * Sound Blaster remote control configuration
51 *
52 * format of remote control data:
53 * Extigy: xx 00
54 * Audigy 2 NX: 06 80 xx 00 00 00
55 * Live! 24-bit: 06 80 xx yy 22 83
56 */
57static const struct rc_config {
58 u32 usb_id;
59 u8 offset;
60 u8 length;
61 u8 packet_length;
62 u8 mute_mixer_id;
63 u32 mute_code;
64} rc_configs[] = {
65 { USB_ID(0x041e, 0x3000), 0, 1, 2, 18, 0x0013 }, /* Extigy */
66 { USB_ID(0x041e, 0x3020), 2, 1, 6, 18, 0x0013 }, /* Audigy 2 NX */
67 { USB_ID(0x041e, 0x3040), 2, 2, 6, 2, 0x6e91 }, /* Live! 24-bit */
68};
69
49struct usb_mixer_interface { 70struct usb_mixer_interface {
50 struct snd_usb_audio *chip; 71 struct snd_usb_audio *chip;
51 unsigned int ctrlif; 72 unsigned int ctrlif;
@@ -55,11 +76,7 @@ struct usb_mixer_interface {
55 struct usb_mixer_elem_info **id_elems; /* array[256], indexed by unit id */ 76 struct usb_mixer_elem_info **id_elems; /* array[256], indexed by unit id */
56 77
57 /* Sound Blaster remote control stuff */ 78 /* Sound Blaster remote control stuff */
58 enum { 79 const struct rc_config *rc_cfg;
59 RC_NONE,
60 RC_EXTIGY,
61 RC_AUDIGY2NX,
62 } rc_type;
63 unsigned long rc_hwdep_open; 80 unsigned long rc_hwdep_open;
64 u32 rc_code; 81 u32 rc_code;
65 wait_queue_head_t rc_waitq; 82 wait_queue_head_t rc_waitq;
@@ -1647,7 +1664,7 @@ static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer,
1647static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer, 1664static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
1648 int unitid) 1665 int unitid)
1649{ 1666{
1650 if (mixer->rc_type == RC_NONE) 1667 if (!mixer->rc_cfg)
1651 return; 1668 return;
1652 /* unit ids specific to Extigy/Audigy 2 NX: */ 1669 /* unit ids specific to Extigy/Audigy 2 NX: */
1653 switch (unitid) { 1670 switch (unitid) {
@@ -1732,20 +1749,19 @@ static void snd_usb_soundblaster_remote_complete(struct urb *urb,
1732 struct pt_regs *regs) 1749 struct pt_regs *regs)
1733{ 1750{
1734 struct usb_mixer_interface *mixer = urb->context; 1751 struct usb_mixer_interface *mixer = urb->context;
1735 /* 1752 const struct rc_config *rc = mixer->rc_cfg;
1736 * format of remote control data:
1737 * Extigy: xx 00
1738 * Audigy 2 NX: 06 80 xx 00 00 00
1739 */
1740 int offset = mixer->rc_type == RC_EXTIGY ? 0 : 2;
1741 u32 code; 1753 u32 code;
1742 1754
1743 if (urb->status < 0 || urb->actual_length <= offset) 1755 if (urb->status < 0 || urb->actual_length < rc->packet_length)
1744 return; 1756 return;
1745 code = mixer->rc_buffer[offset]; 1757
1758 code = mixer->rc_buffer[rc->offset];
1759 if (rc->length == 2)
1760 code |= mixer->rc_buffer[rc->offset + 1] << 8;
1761
1746 /* the Mute button actually changes the mixer control */ 1762 /* the Mute button actually changes the mixer control */
1747 if (code == 13) 1763 if (code == rc->mute_code)
1748 snd_usb_mixer_notify_id(mixer, 18); 1764 snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
1749 mixer->rc_code = code; 1765 mixer->rc_code = code;
1750 wmb(); 1766 wmb();
1751 wake_up(&mixer->rc_waitq); 1767 wake_up(&mixer->rc_waitq);
@@ -1801,21 +1817,17 @@ static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *f
1801static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer) 1817static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
1802{ 1818{
1803 struct snd_hwdep *hwdep; 1819 struct snd_hwdep *hwdep;
1804 int err, len; 1820 int err, len, i;
1805 1821
1806 switch (mixer->chip->usb_id) { 1822 for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
1807 case USB_ID(0x041e, 0x3000): 1823 if (rc_configs[i].usb_id == mixer->chip->usb_id)
1808 mixer->rc_type = RC_EXTIGY; 1824 break;
1809 len = 2; 1825 if (i >= ARRAY_SIZE(rc_configs))
1810 break;
1811 case USB_ID(0x041e, 0x3020):
1812 mixer->rc_type = RC_AUDIGY2NX;
1813 len = 6;
1814 break;
1815 default:
1816 return 0; 1826 return 0;
1817 } 1827 mixer->rc_cfg = &rc_configs[i];
1818 1828
1829 len = mixer->rc_cfg->packet_length;
1830
1819 init_waitqueue_head(&mixer->rc_waitq); 1831 init_waitqueue_head(&mixer->rc_waitq);
1820 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep); 1832 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
1821 if (err < 0) 1833 if (err < 0)
@@ -1998,7 +2010,7 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif)
1998 if ((err = snd_audigy2nx_controls_create(mixer)) < 0) 2010 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
1999 goto _error; 2011 goto _error;
2000 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry)) 2012 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry))
2001 snd_info_set_text_ops(entry, mixer, 1024, 2013 snd_info_set_text_ops(entry, mixer,
2002 snd_audigy2nx_proc_read); 2014 snd_audigy2nx_proc_read);
2003 } 2015 }
2004 2016
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index fe67a92e2a1a..88b72b52590f 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -632,7 +632,7 @@ static int usX2Y_pcms_lock_check(struct snd_card *card)
632 for (s = 0; s < 2; ++s) { 632 for (s = 0; s < 2; ++s) {
633 struct snd_pcm_substream *substream; 633 struct snd_pcm_substream *substream;
634 substream = pcm->streams[s].substream; 634 substream = pcm->streams[s].substream;
635 if (substream && substream->ffile != NULL) 635 if (SUBSTREAM_BUSY(substream))
636 err = -EBUSY; 636 err = -EBUSY;
637 } 637 }
638 } 638 }