[Zrouter-src-freebsd] ZRouter.org: push to FreeBSD HEAD tree

zrouter-src-freebsd at zrouter.org zrouter-src-freebsd at zrouter.org
Mon Jan 16 12:37:26 UTC 2012


details:   http://zrouter.org/hg/FreeBSD/head//rev/484dfe564ae6
changeset: 283:484dfe564ae6
user:      ray at terran.dlink.ua
date:      Mon Jan 16 14:38:30 2012 +0200
description:
FreeBSD HEAD @svn 230212r.

diffstat:

 head/Makefile.inc1                                           |    15 +-
 head/ObsoleteFiles.inc                                       |     5 +-
 head/UPDATING                                                |    11 +-
 head/bin/sh/cd.c                                             |     9 +-
 head/bin/sh/eval.c                                           |    41 +-
 head/bin/sh/eval.h                                           |     3 +-
 head/bin/sh/input.c                                          |    14 +-
 head/bin/sh/trap.c                                           |    39 +-
 head/contrib/compiler-rt/lib/int_lib.h                       |    20 +
 head/contrib/compiler-rt/lib/sparc64/divmod.m4               |   250 +
 head/contrib/compiler-rt/lib/sparc64/divsi3.S                |   333 +
 head/contrib/compiler-rt/lib/sparc64/generate.sh             |     6 +
 head/contrib/compiler-rt/lib/sparc64/modsi3.S                |   333 +
 head/contrib/compiler-rt/lib/sparc64/udivsi3.S               |     1 +
 head/contrib/compiler-rt/lib/sparc64/umodsi3.S               |     1 +
 head/etc/rc.d/accounting                                     |     4 +-
 head/etc/rc.d/amd                                            |     4 +-
 head/etc/rc.d/apm                                            |     4 +-
 head/etc/rc.d/apmd                                           |     4 +-
 head/etc/rc.d/bootparams                                     |     4 +-
 head/etc/rc.d/bsnmpd                                         |     4 +-
 head/etc/rc.d/bthidd                                         |     4 +-
 head/etc/rc.d/cleanvar                                       |     4 +-
 head/etc/rc.d/cleartmp                                       |     4 +-
 head/etc/rc.d/cron                                           |     4 +-
 head/etc/rc.d/ddb                                            |     4 +-
 head/etc/rc.d/devd                                           |     4 +-
 head/etc/rc.d/dmesg                                          |     4 +-
 head/etc/rc.d/ftp-proxy                                      |     4 +-
 head/etc/rc.d/ftpd                                           |     4 +-
 head/etc/rc.d/gptboot                                        |     4 +-
 head/etc/rc.d/hastd                                          |     4 +-
 head/etc/rc.d/hcsecd                                         |     4 +-
 head/etc/rc.d/hostapd                                        |     4 +-
 head/etc/rc.d/inetd                                          |     4 +-
 head/etc/rc.d/ip6addrctl                                     |     4 +-
 head/etc/rc.d/ipfilter                                       |     4 +-
 head/etc/rc.d/ipfs                                           |     4 +-
 head/etc/rc.d/ipmon                                          |     4 +-
 head/etc/rc.d/ipnat                                          |     4 +-
 head/etc/rc.d/ipsec                                          |     4 +-
 head/etc/rc.d/ipxrouted                                      |     4 +-
 head/etc/rc.d/jail                                           |     4 +-
 head/etc/rc.d/keyserv                                        |     4 +-
 head/etc/rc.d/lpd                                            |     4 +-
 head/etc/rc.d/mountd                                         |     4 +-
 head/etc/rc.d/moused                                         |     6 +-
 head/etc/rc.d/mroute6d                                       |     4 +-
 head/etc/rc.d/mrouted                                        |     4 +-
 head/etc/rc.d/natd                                           |     4 +-
 head/etc/rc.d/netwait                                        |     4 +-
 head/etc/rc.d/newsyslog                                      |     4 +-
 head/etc/rc.d/nfscbd                                         |     4 +-
 head/etc/rc.d/nfsd                                           |     4 +-
 head/etc/rc.d/nfsuserd                                       |     4 +-
 head/etc/rc.d/nscd                                           |     4 +-
 head/etc/rc.d/ntpd                                           |     4 +-
 head/etc/rc.d/ntpdate                                        |     4 +-
 head/etc/rc.d/pf                                             |     4 +-
 head/etc/rc.d/pflog                                          |     4 +-
 head/etc/rc.d/pfsync                                         |     4 +-
 head/etc/rc.d/powerd                                         |     4 +-
 head/etc/rc.d/ppp                                            |     4 +-
 head/etc/rc.d/pppoed                                         |     4 +-
 head/etc/rc.d/quota                                          |     4 +-
 head/etc/rc.d/rarpd                                          |     4 +-
 head/etc/rc.d/rfcomm_pppd_server                             |     4 +-
 head/etc/rc.d/route6d                                        |     4 +-
 head/etc/rc.d/routed                                         |     4 +-
 head/etc/rc.d/rpcbind                                        |     4 +-
 head/etc/rc.d/rtadvd                                         |     4 +-
 head/etc/rc.d/rtsold                                         |     4 +-
 head/etc/rc.d/rwho                                           |     4 +-
 head/etc/rc.d/sdpd                                           |     4 +-
 head/etc/rc.d/sendmail                                       |     8 +-
 head/etc/rc.d/sshd                                           |     4 +-
 head/etc/rc.d/syslogd                                        |     6 +-
 head/etc/rc.d/timed                                          |     4 +-
 head/etc/rc.d/ubthidhci                                      |     4 +-
 head/etc/rc.d/virecover                                      |     4 +-
 head/etc/rc.d/watchdogd                                      |     4 +-
 head/etc/rc.subr                                             |    53 +-
 head/games/morse/morse.c                                     |   177 +-
 head/include/stdatomic.h                                     |     7 +-
 head/include/xlocale.h                                       |     6 +-
 head/lib/libc/arm/_fpmath.h                                  |     5 +-
 head/lib/libc/arm/gen/Makefile.inc                           |     4 +-
 head/lib/libc/arm/gen/flt_rounds.c                           |    63 +
 head/lib/libc/arm/softfloat/softfloat.h                      |    30 +-
 head/lib/libc/gen/getutxent.3                                |     3 +-
 head/lib/libc/gen/sem.c                                      |     4 +-
 head/lib/libc/gen/sem_new.c                                  |     3 +-
 head/lib/libc/mips/softfloat/softfloat.h                     |    30 +-
 head/lib/libc/softfloat/Symbol.map                           |    16 +-
 head/lib/libc/softfloat/bits32/softfloat.c                   |     6 +-
 head/lib/libc/softfloat/bits64/softfloat.c                   |     6 +-
 head/lib/libc/softfloat/softfloat-for-gcc.h                  |    22 +-
 head/lib/libc/softfloat/softfloat-specialize                 |     6 +-
 head/lib/libc/sparc64/fpu/fpu_emu.h                          |     5 +-
 head/lib/libc/sparc64/fpu/fpu_mul.c                          |     6 +-
 head/lib/libc/sys/setuid.2                                   |     4 +-
 head/lib/libkvm/kvm_proc.c                                   |    56 +-
 head/lib/libutil/Makefile                                    |    84 +-
 head/lib/libutil/libutil.h                                   |    47 +-
 head/lib/libutil/pidfile.3                                   |     5 +-
 head/lib/libutil/pidfile.c                                   |     9 +-
 head/lib/msun/Makefile                                       |     4 +-
 head/lib/msun/arm/Makefile.inc                               |     3 +-
 head/lib/msun/arm/fenv.h                                     |    26 +-
 head/lib/msun/src/fenv-softfloat.h                           |   184 +
 head/release/Makefile                                        |     4 +-
 head/release/generate-release.sh                             |    40 +-
 head/sbin/geom/class/part/gpart.8                            |    26 +-
 head/sbin/hastd/secondary.c                                  |    19 +-
 head/sbin/routed/parms.c                                     |     6 +-
 head/share/man/man4/snd_hda.4                                |   345 +-
 head/share/man/man5/src.conf.5                               |     9 +-
 head/share/man/man7/release.7                                |     8 +-
 head/share/man/man8/rc.8                                     |     8 +-
 head/share/man/man8/rc.subr.8                                |    32 +-
 head/share/misc/bsd-family-tree                              |    17 +-
 head/sys/amd64/linux32/linux.h                               |     4 +-
 head/sys/amd64/linux32/linux32_dummy.c                       |     4 +-
 head/sys/amd64/linux32/linux32_sysvec.c                      |     4 +-
 head/sys/arm/at91/at91_st.c                                  |     4 +-
 head/sys/arm/include/float.h                                 |    18 +-
 head/sys/arm/sa11x0/sa11x0_ost.c                             |     4 +-
 head/sys/boot/forth/loader.conf                              |     5 +-
 head/sys/boot/powerpc/ps3/ps3mmu.c                           |     4 +-
 head/sys/cam/ctl/scsi_ctl.c                                  |     6 +-
 head/sys/cam/scsi/scsi_all.c                                 |   102 +-
 head/sys/cam/scsi/scsi_all.h                                 |    54 +-
 head/sys/cam/scsi/scsi_da.c                                  |   436 +-
 head/sys/compat/linprocfs/linprocfs.c                        |     6 +-
 head/sys/compat/linux/linux_file.c                           |     4 +-
 head/sys/compat/linux/linux_ioctl.c                          |     4 +-
 head/sys/compat/linux/linux_ipc.c                            |     4 +-
 head/sys/compat/linux/linux_misc.c                           |     4 +-
 head/sys/compat/linux/linux_signal.c                         |     4 +-
 head/sys/compat/linux/linux_socket.c                         |     4 +-
 head/sys/compat/linux/linux_stats.c                          |     4 +-
 head/sys/compat/svr4/imgact_svr4.c                           |     4 +-
 head/sys/conf/files                                          |     6 +-
 head/sys/conf/kmod.mk                                        |     3 +-
 head/sys/conf/options                                        |     9 +-
 head/sys/contrib/dev/npe/LICENSE                             |     4 +-
 head/sys/contrib/dev/nve/amd64/nvenetlib.README              |     4 +-
 head/sys/contrib/dev/nve/i386/nvenetlib.README               |     4 +-
 head/sys/contrib/octeon-sdk/cvmx-pcie.c                      |     6 +
 head/sys/contrib/pf/net/pf_table.c                           |    22 +-
 head/sys/dev/ahci/ahci.h                                     |     4 +-
 head/sys/dev/ata/ata-all.c                                   |     4 +-
 head/sys/dev/ata/ata-all.h                                   |     4 +-
 head/sys/dev/ata/ata-card.c                                  |     4 +-
 head/sys/dev/ata/ata-cbus.c                                  |     4 +-
 head/sys/dev/ata/ata-disk.c                                  |     4 +-
 head/sys/dev/ata/ata-disk.h                                  |     4 +-
 head/sys/dev/ata/ata-dma.c                                   |     4 +-
 head/sys/dev/ata/ata-isa.c                                   |     4 +-
 head/sys/dev/ata/ata-lowlevel.c                              |     4 +-
 head/sys/dev/ata/ata-pci.c                                   |     4 +-
 head/sys/dev/ata/ata-pci.h                                   |     4 +-
 head/sys/dev/ata/ata-queue.c                                 |     4 +-
 head/sys/dev/ata/ata-raid.c                                  |    10 +-
 head/sys/dev/ata/ata-raid.h                                  |     4 +-
 head/sys/dev/ata/ata-sata.c                                  |     4 +-
 head/sys/dev/ata/ata_if.m                                    |     4 +-
 head/sys/dev/ata/atapi-cd.c                                  |     4 +-
 head/sys/dev/ata/atapi-cd.h                                  |     4 +-
 head/sys/dev/ata/atapi-fd.c                                  |     4 +-
 head/sys/dev/ata/atapi-fd.h                                  |     4 +-
 head/sys/dev/ata/atapi-tape.c                                |     4 +-
 head/sys/dev/ata/atapi-tape.h                                |     4 +-
 head/sys/dev/ata/chipsets/ata-acard.c                        |     4 +-
 head/sys/dev/ata/chipsets/ata-acerlabs.c                     |     4 +-
 head/sys/dev/ata/chipsets/ata-adaptec.c                      |     4 +-
 head/sys/dev/ata/chipsets/ata-ahci.c                         |     4 +-
 head/sys/dev/ata/chipsets/ata-amd.c                          |     4 +-
 head/sys/dev/ata/chipsets/ata-ati.c                          |     4 +-
 head/sys/dev/ata/chipsets/ata-cenatek.c                      |     4 +-
 head/sys/dev/ata/chipsets/ata-cypress.c                      |     4 +-
 head/sys/dev/ata/chipsets/ata-cyrix.c                        |     4 +-
 head/sys/dev/ata/chipsets/ata-highpoint.c                    |     4 +-
 head/sys/dev/ata/chipsets/ata-intel.c                        |     4 +-
 head/sys/dev/ata/chipsets/ata-ite.c                          |     4 +-
 head/sys/dev/ata/chipsets/ata-jmicron.c                      |     4 +-
 head/sys/dev/ata/chipsets/ata-marvell.c                      |     4 +-
 head/sys/dev/ata/chipsets/ata-micron.c                       |     4 +-
 head/sys/dev/ata/chipsets/ata-national.c                     |     4 +-
 head/sys/dev/ata/chipsets/ata-netcell.c                      |     4 +-
 head/sys/dev/ata/chipsets/ata-nvidia.c                       |     4 +-
 head/sys/dev/ata/chipsets/ata-promise.c                      |     4 +-
 head/sys/dev/ata/chipsets/ata-serverworks.c                  |     4 +-
 head/sys/dev/ata/chipsets/ata-siliconimage.c                 |     4 +-
 head/sys/dev/ata/chipsets/ata-sis.c                          |     4 +-
 head/sys/dev/ata/chipsets/ata-via.c                          |     4 +-
 head/sys/dev/ath/ath_hal/ah.c                                |    26 +-
 head/sys/dev/ath/ath_hal/ah.h                                |     8 +-
 head/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c              |    10 +-
 head/sys/dev/ath/ath_hal/ar9001/ar9130_eeprom.c              |    27 +-
 head/sys/dev/ath/ath_hal/ar9001/ar9130_eeprom.h              |     4 +-
 head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c              |    15 +-
 head/sys/dev/bxe/bxe_hsi.h                                   |     4 +-
 head/sys/dev/e1000/if_em.c                                   |    92 +-
 head/sys/dev/ex/if_ex.c                                      |     4 +-
 head/sys/dev/ex/if_exreg.h                                   |     4 +-
 head/sys/dev/fb/boot_font.c                                  |   366 +-
 head/sys/dev/fb/splash_pcx.c                                 |     4 +-
 head/sys/dev/fb/vga.c                                        |     4 +-
 head/sys/dev/hpt27xx/README                                  |     4 +-
 head/sys/dev/hptmv/readme.txt                                |     4 +-
 head/sys/dev/hwpmc/hwpmc_uncore.c                            |    16 +-
 head/sys/dev/hwpmc/hwpmc_uncore.h                            |     3 +-
 head/sys/dev/ieee488/ibfoo.c                                 |     4 +-
 head/sys/dev/ieee488/pcii.c                                  |    10 +-
 head/sys/dev/ieee488/upd7210.c                               |     6 +-
 head/sys/dev/ieee488/upd7210.h                               |     8 +-
 head/sys/dev/netmap/if_re_netmap.h                           |     6 +-
 head/sys/dev/netmap/netmap.c                                 |    37 +-
 head/sys/dev/netmap/netmap_kern.h                            |    52 +-
 head/sys/dev/nxge/include/xgehal-channel.h                   |     4 +-
 head/sys/dev/nxge/include/xgehal-config.h                    |     4 +-
 head/sys/dev/nxge/xgehal/xgehal-fifo-fp.c                    |     6 +-
 head/sys/dev/pst/pst-iop.c                                   |     4 +-
 head/sys/dev/pst/pst-iop.h                                   |     4 +-
 head/sys/dev/pst/pst-pci.c                                   |     4 +-
 head/sys/dev/pst/pst-raid.c                                  |     4 +-
 head/sys/dev/sound/pci/ds1-fw.h                              |     6 +-
 head/sys/dev/sound/pci/emu10kx.c                             |    10 +-
 head/sys/dev/sound/pci/hda/hda_reg.h                         |    10 +-
 head/sys/dev/sound/pci/hda/hdaa.c                            |  5903 +++++++
 head/sys/dev/sound/pci/hda/hdaa.h                            |   230 +
 head/sys/dev/sound/pci/hda/hdaa_patches.c                    |   638 +
 head/sys/dev/sound/pci/hda/hdac.c                            |  7918 +---------
 head/sys/dev/sound/pci/hda/hdac.h                            |   544 +-
 head/sys/dev/sound/pci/hda/hdac_if.m                         |   114 +
 head/sys/dev/sound/pci/hda/hdac_private.h                    |   222 +-
 head/sys/dev/sound/pci/hda/hdac_reg.h                        |    10 +-
 head/sys/dev/sound/pci/hda/hdacc.c                           |   662 +
 head/sys/dev/syscons/blank/blank_saver.c                     |     4 +-
 head/sys/dev/syscons/fade/fade_saver.c                       |     4 +-
 head/sys/dev/syscons/green/green_saver.c                     |     4 +-
 head/sys/dev/syscons/logo/logo_saver.c                       |     4 +-
 head/sys/dev/syscons/rain/rain_saver.c                       |     4 +-
 head/sys/dev/syscons/schistory.c                             |     4 +-
 head/sys/dev/syscons/snake/snake_saver.c                     |     4 +-
 head/sys/dev/syscons/star/star_saver.c                       |     4 +-
 head/sys/dev/syscons/syscons.c                               |     4 +-
 head/sys/dev/syscons/syscons.h                               |     4 +-
 head/sys/dev/syscons/warp/warp_saver.c                       |     4 +-
 head/sys/dev/tws/tws.c                                       |     4 +-
 head/sys/dev/usb/controller/xhci.c                           |    30 +-
 head/sys/dev/usb/serial/ucycom.c                             |     4 +-
 head/sys/dev/usb/serial/uftdi.c                              |     3 +-
 head/sys/dev/usb/serial/usb_serial.c                         |    55 +-
 head/sys/dev/usb/serial/usb_serial.h                         |    10 +-
 head/sys/dev/usb/usb.h                                       |     3 +-
 head/sys/dev/usb/usb_hub.c                                   |    64 +-
 head/sys/dev/usb/usb_request.c                               |   100 +-
 head/sys/dev/usb/usb_request.h                               |     4 +-
 head/sys/dev/usb/usbdevs                                     |     3 +-
 head/sys/dev/vxge/include/vxgehal-ll.h                       |    24 +-
 head/sys/dev/xen/xenpci/evtchn.c                             |     4 +-
 head/sys/fs/nfsserver/nfs_nfsdstate.c                        |     6 +-
 head/sys/fs/procfs/procfs.c                                  |     4 +-
 head/sys/fs/procfs/procfs_ioctl.c                            |     4 +-
 head/sys/fs/procfs/procfs_status.c                           |     4 +-
 head/sys/fs/pseudofs/pseudofs.c                              |     4 +-
 head/sys/fs/pseudofs/pseudofs.h                              |     4 +-
 head/sys/fs/pseudofs/pseudofs_fileno.c                       |     4 +-
 head/sys/fs/pseudofs/pseudofs_internal.h                     |     4 +-
 head/sys/fs/pseudofs/pseudofs_vncache.c                      |     4 +-
 head/sys/fs/pseudofs/pseudofs_vnops.c                        |     4 +-
 head/sys/fs/tmpfs/tmpfs.h                                    |     4 +-
 head/sys/fs/tmpfs/tmpfs_subr.c                               |    16 +-
 head/sys/fs/tmpfs/tmpfs_vfsops.c                             |     8 +-
 head/sys/fs/tmpfs/tmpfs_vnops.c                              |    47 +-
 head/sys/geom/part/g_part_ebr.c                              |     7 +-
 head/sys/geom/part/g_part_mbr.c                              |     7 +-
 head/sys/gnu/fs/reiserfs/reiserfs_fs.h                       |     4 +-
 head/sys/gnu/fs/reiserfs/reiserfs_fs_i.h                     |     4 +-
 head/sys/gnu/fs/reiserfs/reiserfs_fs_sb.h                    |     4 +-
 head/sys/gnu/fs/reiserfs/reiserfs_hashes.c                   |     4 +-
 head/sys/gnu/fs/reiserfs/reiserfs_inode.c                    |     4 +-
 head/sys/gnu/fs/reiserfs/reiserfs_item_ops.c                 |     4 +-
 head/sys/gnu/fs/reiserfs/reiserfs_mount.h                    |     4 +-
 head/sys/gnu/fs/reiserfs/reiserfs_namei.c                    |     4 +-
 head/sys/gnu/fs/reiserfs/reiserfs_prints.c                   |     4 +-
 head/sys/gnu/fs/reiserfs/reiserfs_stree.c                    |     6 +-
 head/sys/gnu/fs/reiserfs/reiserfs_vfsops.c                   |     4 +-
 head/sys/gnu/fs/reiserfs/reiserfs_vnops.c                    |     4 +-
 head/sys/i386/conf/XENHVM                                    |    24 +
 head/sys/i386/ibcs2/coff.h                                   |     4 +-
 head/sys/i386/ibcs2/ibcs2_isc.c                              |     4 +-
 head/sys/i386/ibcs2/ibcs2_sysi86.c                           |     4 +-
 head/sys/i386/ibcs2/ibcs2_xenix.c                            |     4 +-
 head/sys/i386/ibcs2/imgact_coff.c                            |     4 +-
 head/sys/i386/include/pcaudioio.h                            |     4 +-
 head/sys/i386/linux/imgact_linux.c                           |     4 +-
 head/sys/i386/linux/linux.h                                  |     4 +-
 head/sys/i386/linux/linux_dummy.c                            |     4 +-
 head/sys/i386/linux/linux_sysvec.c                           |     4 +-
 head/sys/kern/imgact_elf.c                                   |     4 +-
 head/sys/kern/kern_jail.c                                    |    53 +-
 head/sys/kern/kern_proc.c                                    |    27 +-
 head/sys/kern/kern_umtx.c                                    |     7 +-
 head/sys/kern/link_elf_obj.c                                 |     6 +-
 head/sys/kern/subr_bus.c                                     |    12 +-
 head/sys/kern/vfs_cache.c                                    |    76 +-
 head/sys/kern/vfs_mount.c                                    |    31 +-
 head/sys/mips/atheros/ar71xx_machdep.c                       |     3 +-
 head/sys/mips/atheros/ar71xx_pci.c                           |    85 +-
 head/sys/mips/conf/AR71XX_BASE                               |     7 +-
 head/sys/mips/include/db_machdep.h                           |     5 +-
 head/sys/mips/include/float.h                                |    15 +-
 head/sys/mips/mips/db_trace.c                                |    33 +-
 head/sys/mips/mips/elf_machdep.c                             |     8 +-
 head/sys/mips/mips/support.S                                 |    21 +-
 head/sys/modules/ar71xx/Makefile                             |    30 +
 head/sys/modules/ar71xx/ar71xx_ehci/Makefile                 |    43 +
 head/sys/modules/ar71xx/ar71xx_ohci/Makefile                 |    43 +
 head/sys/modules/gpio/Makefile                               |    30 +
 head/sys/modules/gpio/gpiobus/Makefile                       |    40 +
 head/sys/modules/gpio/gpioiic/Makefile                       |    40 +
 head/sys/modules/gpio/gpioled/Makefile                       |    40 +
 head/sys/modules/sound/driver/hda/Makefile                   |     7 +-
 head/sys/modules/wlan/Makefile                               |     5 +-
 head/sys/net/bpf_buffer.c                                    |     4 +-
 head/sys/net/bpf_buffer.h                                    |     4 +-
 head/sys/net/bpf_zerocopy.c                                  |     4 +-
 head/sys/net/bpf_zerocopy.h                                  |     4 +-
 head/sys/net/if_vlan.c                                       |   107 +-
 head/sys/net/if_vlan_var.h                                   |    12 +-
 head/sys/net80211/ieee80211_tdma.c                           |     6 +-
 head/sys/netinet/in.c                                        |    84 +-
 head/sys/netinet/sctp_output.c                               |     6 +-
 head/sys/netinet/sctp_usrreq.c                               |     6 +-
 head/sys/netinet/sctputil.c                                  |     4 +-
 head/sys/netinet6/sctp6_var.h                                |     3 +-
 head/sys/ofed/drivers/infiniband/core/local_sa.c             |     2 +-
 head/sys/ofed/drivers/infiniband/core/notice.c               |     2 +-
 head/sys/powerpc/aim/machdep.c                               |     7 +-
 head/sys/powerpc/aim/slb.c                                   |    20 +-
 head/sys/powerpc/aim/trap.c                                  |    92 +-
 head/sys/powerpc/aim/trap_subr64.S                           |   181 +-
 head/sys/powerpc/include/pcpu.h                              |     6 +-
 head/sys/powerpc/powermac/windtunnel.c                       |    46 +-
 head/sys/powerpc/powerpc/genassym.c                          |     5 +-
 head/sys/powerpc/ps3/platform_ps3.c                          |    12 +-
 head/sys/powerpc/ps3/ps3pic.c                                |    16 +-
 head/sys/sys/ata.h                                           |     4 +-
 head/sys/sys/cdrio.h                                         |     4 +-
 head/sys/sys/consio.h                                        |     4 +-
 head/sys/sys/dvdio.h                                         |     4 +-
 head/sys/sys/imgact_elf.h                                    |     4 +-
 head/sys/sys/mbuf.h                                          |     5 +-
 head/sys/sys/param.h                                         |     4 +-
 head/sys/sys/proc.h                                          |     8 +-
 head/sys/sys/vnode.h                                         |     4 +-
 head/sys/ufs/ffs/ffs_vfsops.c                                |   128 +-
 head/tools/build/options/WITHOUT_UTMPX                       |     3 +-
 head/tools/regression/bin/sh/builtins/case14.0               |     5 +
 head/tools/regression/bin/sh/builtins/case15.0               |     5 +
 head/tools/regression/bin/sh/builtins/case16.0               |     7 +
 head/tools/regression/bin/sh/builtins/case17.0               |     3 +
 head/tools/regression/bin/sh/builtins/case18.0               |     7 +
 head/tools/regression/bin/sh/builtins/case19.0               |     7 +
 head/tools/regression/bin/sh/builtins/cd8.0                  |    26 +
 head/tools/regression/bin/sh/builtins/trap10.0               |     6 +
 head/tools/regression/bin/sh/builtins/trap11.0               |     8 +
 head/tools/regression/bin/sh/builtins/trap9.0                |     3 +
 head/tools/regression/bin/sh/expansion/cmdsubst12.0          |     6 +
 head/tools/regression/bin/sh/expansion/cmdsubst13.0          |    12 +
 head/tools/regression/lib/libc/stdio/test-getdelim.t         |    10 +
 head/tools/regression/lib/libc/stdio/test-print-positional.t |    10 +
 head/tools/regression/lib/libc/stdio/test-printbasic.t       |    10 +
 head/tools/regression/lib/libc/stdio/test-printfloat.c       |     8 +-
 head/tools/regression/lib/msun/test-next.c                   |     4 +-
 head/usr.bin/Makefile                                        |     3 +-
 head/usr.bin/ctlstat/ctlstat.c                               |     4 +-
 head/usr.bin/grep/grep.c                                     |     5 +-
 head/usr.bin/mail/edit.c                                     |     4 +-
 head/usr.bin/printf/printf.c                                 |    38 +-
 head/usr.bin/tftp/main.c                                     |     4 +-
 head/usr.bin/unzip/unzip.c                                   |     4 +-
 head/usr.bin/wtmpcvt/Makefile                                |     5 -
 head/usr.bin/wtmpcvt/wtmpcvt.1                               |    66 -
 head/usr.bin/wtmpcvt/wtmpcvt.c                               |   138 -
 head/usr.sbin/acpi/acpidb/Makefile                           |     7 +-
 head/usr.sbin/acpi/iasl/Makefile                             |    16 +-
 head/usr.sbin/config/mkmakefile.c                            |    10 +-
 head/usr.sbin/lpr/lpc/lpc.c                                  |     4 +-
 head/usr.sbin/timed/timedc/timedc.c                          |     4 +-
 393 files changed, 13507 insertions(+), 9702 deletions(-)

diffs (32235 lines):

diff -r b112b8e55492 -r 484dfe564ae6 head/Makefile.inc1
--- a/head/Makefile.inc1	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/Makefile.inc1	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 #
-# $FreeBSD: head/Makefile.inc1 229673 2012-01-06 00:34:27Z adrian $
+# $FreeBSD: head/Makefile.inc1 230127 2012-01-15 08:36:25Z glebius $
 #
 # Make command line options:
 #	-DNO_CLEANDIR run ${MAKE} clean, instead of ${MAKE} cleandir
@@ -904,10 +904,21 @@
 	    ${CROSSENV} PATH=${TMPPATH} ${MAKE} KERNEL=${INSTKERNNAME} \
 	    DESTDIR=${DESTDIR}/${DISTDIR}/kernel \
 	    ${.TARGET:S/distributekernel/install/}
+.for _kernel in ${BUILDKERNELS:S/${INSTALLKERNEL}//}
+	cd ${KRNLOBJDIR}/${_kernel}; \
+	    ${CROSSENV} PATH=${TMPPATH} ${MAKE} \
+	    KERNEL=${INSTKERNNAME}.${_kernel} \
+	    DESTDIR=${DESTDIR}/${DISTDIR}/kernel.${_kernel} \
+	    ${.TARGET:S/distributekernel/install/}
+.endfor
 
 packagekernel:
-	${_+_}cd ${DESTDIR}/${DISTDIR}/kernel; \
+	cd ${DESTDIR}/${DISTDIR}/kernel; \
 	    tar cvJf ${DESTDIR}/${DISTDIR}/kernel.txz .
+.for _kernel in ${BUILDKERNELS:S/${INSTALLKERNEL}//}
+	cd ${DESTDIR}/${DISTDIR}/kernel.${_kernel}; \
+	    tar cvJf ${DESTDIR}/${DISTDIR}/kernel.${_kernel}.txz .
+.endfor
 
 #
 # doxygen
diff -r b112b8e55492 -r 484dfe564ae6 head/ObsoleteFiles.inc
--- a/head/ObsoleteFiles.inc	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/ObsoleteFiles.inc	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 #
-# $FreeBSD: head/ObsoleteFiles.inc 228703 2011-12-19 12:50:12Z glebius $
+# $FreeBSD: head/ObsoleteFiles.inc 230060 2012-01-13 15:40:49Z ed $
 #
 # This file lists old files (OLD_FILES), libraries (OLD_LIBS) and
 # directories (OLD_DIRS) which should get removed at an update. Recently
@@ -38,6 +38,9 @@
 #   xargs -n1 | sort | uniq -d;
 # done
 
+# 20120113: removal of wtmpcvt(1)
+OLD_FILES+=usr/bin/wtmpcvt
+OLD_FILES+=usr/share/man/man1/wtmpcvt.1.gz
 # 20111214: eventtimers(7) moved to eventtimers(4)
 OLD_FILES+=usr/share/man/man7/eventtimers.7.gz
 # 20111125: amd(4) removed
diff -r b112b8e55492 -r 484dfe564ae6 head/UPDATING
--- a/head/UPDATING	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/UPDATING	Mon Jan 16 14:38:30 2012 +0200
@@ -22,6 +22,15 @@
 	machines to maximize performance.  (To disable malloc debugging, run
 	ln -s aj /etc/malloc.conf.)
 
+20120114:
+	The set_rcvar() function has been removed from /etc/rc.subr.  All
+	base and ports rc.d scripts have been updated, so if you have a
+	port installed with a script in /usr/local/etc/rc.d you can either
+	hand-edit the rcvar= line, or reinstall the port.
+
+	An easy way to handle the mass-update of /etc/rc.d:
+	rm /etc/rc.d/* && mergemaster -i
+
 20120109:
 	panic(9) now stops other CPUs in the SMP systems, disables interrupts
 	on the current CPU and prevents other threads from running.
@@ -1541,4 +1550,4 @@
 Contact Warner Losh if you have any questions about your use of
 this document.
 
-$FreeBSD: head/UPDATING 229854 2012-01-09 12:06:09Z avg $
+$FreeBSD: head/UPDATING 230122 2012-01-14 23:19:10Z dougb $
diff -r b112b8e55492 -r 484dfe564ae6 head/bin/sh/cd.c
--- a/head/bin/sh/cd.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/bin/sh/cd.c	Mon Jan 16 14:38:30 2012 +0200
@@ -36,7 +36,7 @@
 #endif
 #endif /* not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/bin/sh/cd.c 223060 2011-06-13 21:03:27Z jilles $");
+__FBSDID("$FreeBSD: head/bin/sh/cd.c 230095 2012-01-13 23:32:27Z jilles $");
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -130,7 +130,12 @@
 	    (path = bltinlookup("CDPATH", 1)) == NULL)
 		path = nullstr;
 	while ((p = padvance(&path, dest)) != NULL) {
-		if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
+		if (stat(p, &statb) < 0) {
+			if (errno != ENOENT)
+				errno1 = errno;
+		} else if (!S_ISDIR(statb.st_mode))
+			errno1 = ENOTDIR;
+		else {
 			if (!print) {
 				/*
 				 * XXX - rethink
diff -r b112b8e55492 -r 484dfe564ae6 head/bin/sh/eval.c
--- a/head/bin/sh/eval.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/bin/sh/eval.c	Mon Jan 16 14:38:30 2012 +0200
@@ -36,7 +36,7 @@
 #endif
 #endif /* not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/bin/sh/eval.c 228937 2011-12-28 22:10:12Z jilles $");
+__FBSDID("$FreeBSD: head/bin/sh/eval.c 230212 2012-01-16 11:07:46Z dumbbell $");
 
 #include <paths.h>
 #include <signal.h>
@@ -75,7 +75,7 @@
 
 
 int evalskip;			/* set if we are skipping commands */
-static int skipcount;		/* number of levels to skip */
+int skipcount;			/* number of levels to skip */
 MKINIT int loopnest;		/* current loop nesting level */
 int funcnest;			/* depth of function calls */
 static int builtin_flags;	/* evalcommand flags for builtins */
@@ -89,7 +89,7 @@
 
 static void evalloop(union node *, int);
 static void evalfor(union node *, int);
-static union node *evalcase(union node *, int);
+static union node *evalcase(union node *);
 static void evalsubshell(union node *, int);
 static void evalredir(union node *, int);
 static void expredir(union node *);
@@ -256,7 +256,18 @@
 			evalfor(n, flags & ~EV_EXIT);
 			break;
 		case NCASE:
-			next = evalcase(n, flags);
+			next = evalcase(n);
+			break;
+		case NCLIST:
+			next = n->nclist.body;
+			break;
+		case NCLISTFALLTHRU:
+			if (n->nclist.body) {
+				evaltree(n->nclist.body, flags & ~EV_EXIT);
+				if (evalskip)
+					goto out;
+			}
+			next = n->nclist.next;
 			break;
 		case NDEFUN:
 			defun(n->narg.text, n->narg.next);
@@ -366,9 +377,14 @@
 }
 
 
+/*
+ * Evaluate a case statement, returning the selected tree.
+ *
+ * The exit status needs care to get right.
+ */
 
 static union node *
-evalcase(union node *n, int flags)
+evalcase(union node *n)
 {
 	union node *cp;
 	union node *patp;
@@ -378,25 +394,26 @@
 	setstackmark(&smark);
 	arglist.lastp = &arglist.list;
 	oexitstatus = exitstatus;
-	exitstatus = 0;
 	expandarg(n->ncase.expr, &arglist, EXP_TILDE);
 	for (cp = n->ncase.cases ; cp ; cp = cp->nclist.next) {
 		for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
 			if (casematch(patp, arglist.list->text)) {
 				popstackmark(&smark);
 				while (cp->nclist.next &&
-				    cp->type == NCLISTFALLTHRU) {
-					evaltree(cp->nclist.body,
-					    flags & ~EV_EXIT);
-					if (evalskip != 0)
-						return (NULL);
+				    cp->type == NCLISTFALLTHRU &&
+				    cp->nclist.body == NULL)
 					cp = cp->nclist.next;
-				}
+				if (cp->nclist.next &&
+				    cp->type == NCLISTFALLTHRU)
+					return (cp);
+				if (cp->nclist.body == NULL)
+					exitstatus = 0;
 				return (cp->nclist.body);
 			}
 		}
 	}
 	popstackmark(&smark);
+	exitstatus = 0;
 	return (NULL);
 }
 
diff -r b112b8e55492 -r 484dfe564ae6 head/bin/sh/eval.h
--- a/head/bin/sh/eval.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/bin/sh/eval.h	Mon Jan 16 14:38:30 2012 +0200
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)eval.h	8.2 (Berkeley) 5/4/95
- * $FreeBSD: head/bin/sh/eval.h 223060 2011-06-13 21:03:27Z jilles $
+ * $FreeBSD: head/bin/sh/eval.h 230212 2012-01-16 11:07:46Z dumbbell $
  */
 
 extern char *commandname;	/* currently executing command */
@@ -60,6 +60,7 @@
 #define in_function()	funcnest
 extern int funcnest;
 extern int evalskip;
+extern int skipcount;
 
 /* reasons for skipping commands (see comment on breakcmd routine) */
 #define SKIPBREAK	1
diff -r b112b8e55492 -r 484dfe564ae6 head/bin/sh/input.c
--- a/head/bin/sh/input.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/bin/sh/input.c	Mon Jan 16 14:38:30 2012 +0200
@@ -36,7 +36,7 @@
 #endif
 #endif /* not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/bin/sh/input.c 229220 2012-01-01 22:17:12Z jilles $");
+__FBSDID("$FreeBSD: head/bin/sh/input.c 230118 2012-01-14 22:46:18Z jilles $");
 
 #include <stdio.h>	/* defines BUFSIZ */
 #include <fcntl.h>
@@ -97,7 +97,7 @@
 MKINIT int parselleft;		/* copy of parsefile->lleft */
 char *parsenextc;		/* copy of parsefile->nextc */
 MKINIT struct parsefile basepf;	/* top level input file */
-char basebuf[BUFSIZ];		/* buffer for top level input file */
+char basebuf[BUFSIZ + 1];	/* buffer for top level input file */
 static struct parsefile *parsefile = &basepf;	/* current input file */
 int init_editline = 0;		/* editline library initialized? */
 int whichprompt;		/* 1 == PS1, 2 == PS2 */
@@ -189,8 +189,8 @@
 			nr = 0;
 		else {
 			nr = el_len;
-			if (nr > BUFSIZ - 1)
-				nr = BUFSIZ - 1;
+			if (nr > BUFSIZ)
+				nr = BUFSIZ;
 			memcpy(parsenextc, rl_cp, nr);
 			if (nr != el_len) {
 				el_len -= nr;
@@ -200,7 +200,7 @@
 		}
 	} else
 #endif
-		nr = read(parsefile->fd, parsenextc, BUFSIZ - 1);
+		nr = read(parsefile->fd, parsenextc, BUFSIZ);
 
 	if (nr <= 0) {
                 if (nr < 0) {
@@ -428,13 +428,13 @@
 	(void)fcntl(fd, F_SETFD, FD_CLOEXEC);
 	if (push) {
 		pushfile();
-		parsefile->buf = ckmalloc(BUFSIZ);
+		parsefile->buf = ckmalloc(BUFSIZ + 1);
 	}
 	if (parsefile->fd > 0)
 		close(parsefile->fd);
 	parsefile->fd = fd;
 	if (parsefile->buf == NULL)
-		parsefile->buf = ckmalloc(BUFSIZ);
+		parsefile->buf = ckmalloc(BUFSIZ + 1);
 	parselleft = parsenleft = 0;
 	plinno = 1;
 }
diff -r b112b8e55492 -r 484dfe564ae6 head/bin/sh/trap.c
--- a/head/bin/sh/trap.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/bin/sh/trap.c	Mon Jan 16 14:38:30 2012 +0200
@@ -36,7 +36,7 @@
 #endif
 #endif /* not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/bin/sh/trap.c 223060 2011-06-13 21:03:27Z jilles $");
+__FBSDID("$FreeBSD: head/bin/sh/trap.c 230212 2012-01-16 11:07:46Z dumbbell $");
 
 #include <signal.h>
 #include <unistd.h>
@@ -191,10 +191,11 @@
 			argv++;
 		}
 	}
-	while (*argv) {
+	for (; *argv; argv++) {
 		if ((signo = sigstring_to_signum(*argv)) == -1) {
 			warning("bad signal %s", *argv);
 			errors = 1;
+			continue;
 		}
 		INTOFF;
 		if (action)
@@ -205,7 +206,6 @@
 		if (signo != 0)
 			setsignal(signo);
 		INTON;
-		argv++;
 	}
 	return errors;
 }
@@ -412,7 +412,7 @@
 dotrap(void)
 {
 	int i;
-	int savestatus;
+	int savestatus, prev_evalskip, prev_skipcount;
 
 	in_dotrap++;
 	for (;;) {
@@ -427,10 +427,36 @@
 					 */
 					if (i == SIGCHLD)
 						ignore_sigchld++;
+
+					/*
+					 * Backup current evalskip
+					 * state and reset it before
+					 * executing a trap, so that the
+					 * trap is not disturbed by an
+					 * ongoing break/continue/return
+					 * statement.
+					 */
+					prev_evalskip  = evalskip;
+					prev_skipcount = skipcount;
+					evalskip = 0;
+
 					last_trapsig = i;
 					savestatus = exitstatus;
 					evalstring(trap[i], 0);
 					exitstatus = savestatus;
+
+					/*
+					 * If such a command was not
+					 * already in progress, allow a
+					 * break/continue/return in the
+					 * trap action to have an effect
+					 * outside of it.
+					 */
+					if (prev_evalskip != 0) {
+						evalskip  = prev_evalskip;
+						skipcount = prev_skipcount;
+					}
+
 					if (i == SIGCHLD)
 						ignore_sigchld--;
 				}
@@ -501,6 +527,11 @@
 	}
 	handler = &loc1;
 	if ((p = trap[0]) != NULL && *p != '\0') {
+		/*
+		 * Reset evalskip, or the trap on EXIT could be
+		 * interrupted if the last command was a "return".
+		 */
+		evalskip = 0;
 		trap[0] = NULL;
 		evalstring(p, 0);
 	}
diff -r b112b8e55492 -r 484dfe564ae6 head/contrib/compiler-rt/lib/int_lib.h
--- a/head/contrib/compiler-rt/lib/int_lib.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/contrib/compiler-rt/lib/int_lib.h	Mon Jan 16 14:38:30 2012 +0200
@@ -43,4 +43,24 @@
 /* Include internal utility function declarations. */
 #include "int_util.h"
 
+/*
+ * Workaround for LLVM bug 11663.  Prevent endless recursion in
+ * __c?zdi2(), where calls to __builtin_c?z() are expanded to
+ * __c?zdi2() instead of __c?zsi2().
+ *
+ * Instead of placing this workaround in c?zdi2.c, put it in this
+ * global header to prevent other C files from making the detour
+ * through __c?zdi2() as well.
+ *
+ * This problem has only been observed on FreeBSD for sparc64 and
+ * mips64 with GCC 4.2.1.
+ */
+#if defined(__FreeBSD__) && (defined(__sparc64__) || \
+    defined(__mips_n64) || defined(__mips_o64))
+si_int __clzsi2(si_int);
+si_int __ctzsi2(si_int);
+#define	__builtin_clz	__clzsi2
+#define	__builtin_ctz	__ctzsi2
+#endif
+
 #endif /* INT_LIB_H */
diff -r b112b8e55492 -r 484dfe564ae6 head/contrib/compiler-rt/lib/sparc64/divmod.m4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/sparc64/divmod.m4	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,250 @@
+/*
+ * This m4 code has been taken from The SPARC Architecture Manual Version 8.
+ */
+
+/*
+ * Division/Remainder
+ *
+ * Input is:
+ *   dividend -- the thing being divided
+ *   divisor -- how many ways to divide it
+ * Important parameters:
+ *   N -- how many bits per iteration we try to get
+ *        as our current guess: define(N, 4) define(TWOSUPN, 16)
+ *   WORDSIZE -- how many bits altogether we're talking about:
+ *               obviously: define(WORDSIZE, 32)
+ * A derived constant:
+ *   TOPBITS -- how many bits are in the top "decade" of a number:
+ *        define(TOPBITS, eval( WORDSIZE - N*((WORDSIZE-1)/N) ) )
+ * Important variables are:
+ *   Q -- the partial quotient under development -- initially 0
+ *   R -- the remainder so far -- initially == the dividend
+ *   ITER -- number of iterations of the main division loop which will
+ *           be required. Equal to CEIL( lg2(quotient)/N )
+ *           Note that this is log_base_(2ˆN) of the quotient.
+ *   V -- the current comparand -- initially divisor*2ˆ(ITER*N-1)
+ * Cost:
+ *   current estimate for non-large dividend is
+ *        CEIL( lg2(quotient) / N ) x ( 10 + 7N/2 ) + C
+ *   a large dividend is one greater than 2ˆ(31-TOPBITS) and takes a
+ *   different path, as the upper bits of the quotient must be developed
+ *   one bit at a time.
+ *   This uses the m4 and cpp macro preprocessors.
+ */
+
+define(dividend, `%o0')
+define(divisor,`%o1')
+define(Q, `%o2')
+define(R, `%o3')
+define(ITER, `%o4')
+define(V, `%o5')
+define(SIGN, `%g3')
+define(T, `%g1')
+define(SC,`%g2')
+/*
+ * This is the recursive definition of how we develop quotient digits.
+ * It takes three important parameters:
+ *   $1 -- the current depth, 1<=$1<=N
+ *   $2 -- the current accumulation of quotient bits
+ *   N -- max depth
+ * We add a new bit to $2 and either recurse or insert the bits in the quotient.
+ * Dynamic input:
+ *   R -- current remainder
+ *   Q -- current quotient
+ *   V -- current comparand
+ *   cc -- set on current value of R
+ * Dynamic output:
+ *   R', Q', V', cc'
+ */
+
+#include "../assembly.h"
+
+.text
+	.align 4
+
+define(DEVELOP_QUOTIENT_BITS,
+`	!depth $1, accumulated bits $2
+	bl	L.$1.eval(TWOSUPN+$2)
+	srl	V,1,V
+	! remainder is nonnegative
+	subcc	R,V,R
+	ifelse( $1, N,
+	`	b	9f
+		add	Q, ($2*2+1), Q
+	',` DEVELOP_QUOTIENT_BITS( incr($1), `eval(2*$2+1)')
+	')
+L.$1.eval(TWOSUPN+$2):
+	! remainder is negative
+	addcc	R,V,R
+	ifelse( $1, N,
+	`	b	9f
+		add	Q, ($2*2-1), Q
+	',` DEVELOP_QUOTIENT_BITS( incr($1), `eval(2*$2-1)')
+	')
+	ifelse( $1, 1, `9:')
+')
+ifelse( ANSWER, `quotient', `
+DEFINE_COMPILERRT_FUNCTION(__udivsi3)
+	save	%sp,-64,%sp		! do this for debugging
+	b	divide
+	mov	0,SIGN			! result always nonnegative
+DEFINE_COMPILERRT_FUNCTION(__divsi3)
+	save	%sp,-64,%sp		! do this for debugging
+	orcc	divisor,dividend,%g0	! are either dividend or divisor negative
+	bge	divide			! if not, skip this junk
+	xor	divisor,dividend,SIGN	! record sign of result in sign of SIGN
+	tst	divisor
+	bge	2f
+	tst	dividend
+	! divisor < 0
+	bge	divide
+	neg	divisor
+	2:
+	! dividend < 0
+	neg	dividend
+	! FALL THROUGH
+',`
+DEFINE_COMPILERRT_FUNCTION(__umodsi3)
+	save	%sp,-64,%sp		! do this for debugging
+	b	divide
+	mov	0,SIGN			! result always nonnegative
+DEFINE_COMPILERRT_FUNCTION(__modsi3)
+	save	%sp,-64,%sp		! do this for debugging
+	orcc	divisor,dividend,%g0	! are either dividend or divisor negative
+	bge	divide			! if not, skip this junk
+	mov	dividend,SIGN		! record sign of result in sign of SIGN
+	tst	divisor
+	bge	2f
+	tst	dividend
+	! divisor < 0
+	bge	divide
+	neg	divisor
+	2:
+	! dividend < 0
+	neg	dividend
+	! FALL THROUGH
+')
+
+divide:
+	! Compute size of quotient, scale comparand.
+	orcc	divisor,%g0,V		! movcc divisor,V
+	te	2			! if divisor = 0
+	mov	dividend,R
+	mov	0,Q
+	sethi	%hi(1<<(WORDSIZE-TOPBITS-1)),T
+	cmp	R,T
+	blu	not_really_big
+	mov	0,ITER
+	!
+	! Here, the dividend is >= 2ˆ(31-N) or so. We must be careful here,
+	! as our usual N-at-a-shot divide step will cause overflow and havoc.
+	! The total number of bits in the result here is N*ITER+SC, where
+	! SC <= N.
+	! Compute ITER in an unorthodox manner: know we need to Shift V into
+! the top decade: so don't even bother to compare to R.
+1:
+	cmp	V,T
+	bgeu	3f
+	mov	1,SC
+	sll	V,N,V
+	b	1b
+	inc	ITER
+! Now compute SC
+2:	addcc	V,V,V
+	bcc	not_too_big
+	add	SC,1,SC
+		! We're here if the divisor overflowed when Shifting.
+		! This means that R has the high-order bit set.
+		! Restore V and subtract from R.
+		sll	T,TOPBITS,T	! high order bit
+		srl	V,1,V		! rest of V
+		add	V,T,V
+		b	do_single_div
+		dec	SC
+not_too_big:
+3:	cmp	V,R
+	blu	2b
+	nop
+	be	do_single_div
+	nop
+! V > R: went too far: back up 1 step
+!     srl V,1,V
+!      dec SC
+! do single-bit divide steps
+!
+! We have to be careful here. We know that R >= V, so we can do the
+! first divide step without thinking. BUT, the others are conditional,
+! and are only done if R >= 0. Because both R and V may have the high-
+! order bit set in the first step, just falling into the regular
+! division loop will mess up the first time around.
+! So we unroll slightly...
+do_single_div:
+	deccc	SC
+	bl	end_regular_divide
+	nop
+	sub	R,V,R
+	mov	1,Q
+	b	end_single_divloop
+	nop
+single_divloop:
+	sll	Q,1,Q
+	bl	1f
+	srl	V,1,V
+	! R >= 0
+		sub	R,V,R
+		b	2f
+		inc	Q
+	1:	! R < 0
+		add	R,V,R
+		dec	Q
+	2:
+	end_single_divloop:
+		deccc	SC
+		bge	single_divloop
+		tst	R
+		b	end_regular_divide
+		nop
+
+not_really_big:
+1:
+	sll	V,N,V
+	cmp	V,R
+	bleu	1b
+	inccc	ITER
+	be	got_result
+	dec	ITER
+do_regular_divide:
+	! Do the main division iteration
+	tst	R
+	! Fall through into divide loop
+divloop:
+	sll	Q,N,Q
+	DEVELOP_QUOTIENT_BITS( 1, 0 )
+end_regular_divide:
+	deccc	ITER
+	bge	divloop
+	tst	R
+	bge	got_result
+	nop
+	! non-restoring fixup here
+ifelse( ANSWER, `quotient',
+`	dec	Q
+',`	add	R,divisor,R
+')
+
+got_result:
+	tst	SIGN
+	bge	1f
+	restore
+	! answer < 0
+	retl				! leaf-routine return
+ifelse( ANSWER, `quotient',
+`	neg	%o2,%o0			! quotient <- -Q
+',`	neg	%o3,%o0 		! remainder <- -R
+')
+1:
+	retl				! leaf-routine return
+ifelse( ANSWER, `quotient',
+`	mov	%o2,%o0			! quotient <- Q
+',`	mov	%o3,%o0			! remainder <- R
+')
diff -r b112b8e55492 -r 484dfe564ae6 head/contrib/compiler-rt/lib/sparc64/divsi3.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/sparc64/divsi3.S	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,333 @@
+/*
+ * This m4 code has been taken from The SPARC Architecture Manual Version 8.
+ */
+/*
+ * Division/Remainder
+ *
+ * Input is:
+ *   dividend -- the thing being divided
+ *   divisor -- how many ways to divide it
+ * Important parameters:
+ *   N -- how many bits per iteration we try to get
+ *        as our current guess:
+ *   WORDSIZE -- how many bits altogether we're talking about:
+ *               obviously:
+ * A derived constant:
+ *   TOPBITS -- how many bits are in the top "decade" of a number:
+ *
+ * Important variables are:
+ *   Q -- the partial quotient under development -- initially 0
+ *   R -- the remainder so far -- initially == the dividend
+ *   ITER -- number of iterations of the main division loop which will
+ *           be required. Equal to CEIL( lg2(quotient)/4 )
+ *           Note that this is log_base_(2ˆ4) of the quotient.
+ *   V -- the current comparand -- initially divisor*2ˆ(ITER*4-1)
+ * Cost:
+ *   current estimate for non-large dividend is
+ *        CEIL( lg2(quotient) / 4 ) x ( 10 + 74/2 ) + C
+ *   a large dividend is one greater than 2ˆ(31-4 ) and takes a
+ *   different path, as the upper bits of the quotient must be developed
+ *   one bit at a time.
+ *   This uses the m4 and cpp macro preprocessors.
+ */
+/*
+ * This is the recursive definition of how we develop quotient digits.
+ * It takes three important parameters:
+ *   $1 -- the current depth, 1<=$1<=4
+ *   $2 -- the current accumulation of quotient bits
+ *   4 -- max depth
+ * We add a new bit to $2 and either recurse or insert the bits in the quotient.
+ * Dynamic input:
+ *   %o3 -- current remainder
+ *   %o2 -- current quotient
+ *   %o5 -- current comparand
+ *   cc -- set on current value of %o3
+ * Dynamic output:
+ *   %o3', %o2', %o5', cc'
+ */
+#include "../assembly.h"
+.text
+	.align 4
+DEFINE_COMPILERRT_FUNCTION(__udivsi3)
+	save	%sp,-64,%sp		! do this for debugging
+	b	divide
+	mov	0,%g3			! result always nonnegative
+DEFINE_COMPILERRT_FUNCTION(__divsi3)
+	save	%sp,-64,%sp		! do this for debugging
+	orcc	%o1,%o0,%g0	! are either %o0 or %o1 negative
+	bge	divide			! if not, skip this junk
+	xor	%o1,%o0,%g3	! record sign of result in sign of %g3
+	tst	%o1
+	bge	2f
+	tst	%o0
+	! %o1 < 0
+	bge	divide
+	neg	%o1
+	2:
+	! %o0 < 0
+	neg	%o0
+	! FALL THROUGH
+divide:
+	! Compute size of quotient, scale comparand.
+	orcc	%o1,%g0,%o5		! movcc %o1,%o5
+	te	2			! if %o1 = 0
+	mov	%o0,%o3
+	mov	0,%o2
+	sethi	%hi(1<<(32-4 -1)),%g1
+	cmp	%o3,%g1
+	blu	not_really_big
+	mov	0,%o4
+	!
+	! Here, the %o0 is >= 2ˆ(31-4) or so. We must be careful here,
+	! as our usual 4-at-a-shot divide step will cause overflow and havoc.
+	! The total number of bits in the result here is 4*%o4+%g2, where
+	! %g2 <= 4.
+	! Compute %o4 in an unorthodox manner: know we need to Shift %o5 into
+! the top decade: so don't even bother to compare to %o3.
+1:
+	cmp	%o5,%g1
+	bgeu	3f
+	mov	1,%g2
+	sll	%o5,4,%o5
+	b	1b
+	inc	%o4
+! Now compute %g2
+2:	addcc	%o5,%o5,%o5
+	bcc	not_too_big
+	add	%g2,1,%g2
+		! We're here if the %o1 overflowed when Shifting.
+		! This means that %o3 has the high-order bit set.
+		! Restore %o5 and subtract from %o3.
+		sll	%g1,4 ,%g1	! high order bit
+		srl	%o5,1,%o5		! rest of %o5
+		add	%o5,%g1,%o5
+		b	do_single_div
+		dec	%g2
+not_too_big:
+3:	cmp	%o5,%o3
+	blu	2b
+	nop
+	be	do_single_div
+	nop
+! %o5 > %o3: went too far: back up 1 step
+!     srl %o5,1,%o5
+!      dec %g2
+! do single-bit divide steps
+!
+! We have to be careful here. We know that %o3 >= %o5, so we can do the
+! first divide step without thinking. BUT, the others are conditional,
+! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high-
+! order bit set in the first step, just falling into the regular
+! division loop will mess up the first time around.
+! So we unroll slightly...
+do_single_div:
+	deccc	%g2
+	bl	end_regular_divide
+	nop
+	sub	%o3,%o5,%o3
+	mov	1,%o2
+	b	end_single_divloop
+	nop
+single_divloop:
+	sll	%o2,1,%o2
+	bl	1f
+	srl	%o5,1,%o5
+	! %o3 >= 0
+		sub	%o3,%o5,%o3
+		b	2f
+		inc	%o2
+	1:	! %o3 < 0
+		add	%o3,%o5,%o3
+		dec	%o2
+	2:
+	end_single_divloop:
+		deccc	%g2
+		bge	single_divloop
+		tst	%o3
+		b	end_regular_divide
+		nop
+not_really_big:
+1:
+	sll	%o5,4,%o5
+	cmp	%o5,%o3
+	bleu	1b
+	inccc	%o4
+	be	got_result
+	dec	%o4
+do_regular_divide:
+	! Do the main division iteration
+	tst	%o3
+	! Fall through into divide loop
+divloop:
+	sll	%o2,4,%o2
+		!depth 1, accumulated bits 0
+	bl	L.1.16
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 2, accumulated bits 1
+	bl	L.2.17
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 3, accumulated bits 3
+	bl	L.3.19
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits 7
+	bl	L.4.23
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (7*2+1), %o2
+L.4.23:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (7*2-1), %o2
+L.3.19:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits 5
+	bl	L.4.21
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (5*2+1), %o2
+L.4.21:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (5*2-1), %o2
+L.2.17:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 3, accumulated bits 1
+	bl	L.3.17
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits 3
+	bl	L.4.19
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (3*2+1), %o2
+L.4.19:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (3*2-1), %o2
+L.3.17:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits 1
+	bl	L.4.17
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (1*2+1), %o2
+L.4.17:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (1*2-1), %o2
+L.1.16:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 2, accumulated bits -1
+	bl	L.2.15
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 3, accumulated bits -1
+	bl	L.3.15
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits -1
+	bl	L.4.15
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-1*2+1), %o2
+L.4.15:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-1*2-1), %o2
+L.3.15:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits -3
+	bl	L.4.13
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-3*2+1), %o2
+L.4.13:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-3*2-1), %o2
+L.2.15:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 3, accumulated bits -3
+	bl	L.3.13
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits -5
+	bl	L.4.11
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-5*2+1), %o2
+L.4.11:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-5*2-1), %o2
+L.3.13:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits -7
+	bl	L.4.9
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-7*2+1), %o2
+L.4.9:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-7*2-1), %o2
+	9:
+end_regular_divide:
+	deccc	%o4
+	bge	divloop
+	tst	%o3
+	bge	got_result
+	nop
+	! non-restoring fixup here
+	dec	%o2
+got_result:
+	tst	%g3
+	bge	1f
+	restore
+	! answer < 0
+	retl				! leaf-routine return
+	neg	%o2,%o0			! quotient <- -%o2
+1:
+	retl				! leaf-routine return
+	mov	%o2,%o0			! quotient <- %o2
diff -r b112b8e55492 -r 484dfe564ae6 head/contrib/compiler-rt/lib/sparc64/generate.sh
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/sparc64/generate.sh	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+m4 divmod.m4 | sed -e 's/[[:space:]]*$//' | grep -v '^$' > modsi3.S
+m4 -DANSWER=quotient divmod.m4 | sed -e 's/[[:space:]]*$//' | grep -v '^$' > divsi3.S
+echo '! This file intentionally left blank' > umodsi3.S
+echo '! This file intentionally left blank' > udivsi3.S
diff -r b112b8e55492 -r 484dfe564ae6 head/contrib/compiler-rt/lib/sparc64/modsi3.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/sparc64/modsi3.S	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,333 @@
+/*
+ * This m4 code has been taken from The SPARC Architecture Manual Version 8.
+ */
+/*
+ * Division/Remainder
+ *
+ * Input is:
+ *   dividend -- the thing being divided
+ *   divisor -- how many ways to divide it
+ * Important parameters:
+ *   N -- how many bits per iteration we try to get
+ *        as our current guess:
+ *   WORDSIZE -- how many bits altogether we're talking about:
+ *               obviously:
+ * A derived constant:
+ *   TOPBITS -- how many bits are in the top "decade" of a number:
+ *
+ * Important variables are:
+ *   Q -- the partial quotient under development -- initially 0
+ *   R -- the remainder so far -- initially == the dividend
+ *   ITER -- number of iterations of the main division loop which will
+ *           be required. Equal to CEIL( lg2(quotient)/4 )
+ *           Note that this is log_base_(2ˆ4) of the quotient.
+ *   V -- the current comparand -- initially divisor*2ˆ(ITER*4-1)
+ * Cost:
+ *   current estimate for non-large dividend is
+ *        CEIL( lg2(quotient) / 4 ) x ( 10 + 74/2 ) + C
+ *   a large dividend is one greater than 2ˆ(31-4 ) and takes a
+ *   different path, as the upper bits of the quotient must be developed
+ *   one bit at a time.
+ *   This uses the m4 and cpp macro preprocessors.
+ */
+/*
+ * This is the recursive definition of how we develop quotient digits.
+ * It takes three important parameters:
+ *   $1 -- the current depth, 1<=$1<=4
+ *   $2 -- the current accumulation of quotient bits
+ *   4 -- max depth
+ * We add a new bit to $2 and either recurse or insert the bits in the quotient.
+ * Dynamic input:
+ *   %o3 -- current remainder
+ *   %o2 -- current quotient
+ *   %o5 -- current comparand
+ *   cc -- set on current value of %o3
+ * Dynamic output:
+ *   %o3', %o2', %o5', cc'
+ */
+#include "../assembly.h"
+.text
+	.align 4
+DEFINE_COMPILERRT_FUNCTION(__umodsi3)
+	save	%sp,-64,%sp		! do this for debugging
+	b	divide
+	mov	0,%g3			! result always nonnegative
+DEFINE_COMPILERRT_FUNCTION(__modsi3)
+	save	%sp,-64,%sp		! do this for debugging
+	orcc	%o1,%o0,%g0	! are either %o0 or %o1 negative
+	bge	divide			! if not, skip this junk
+	mov	%o0,%g3		! record sign of result in sign of %g3
+	tst	%o1
+	bge	2f
+	tst	%o0
+	! %o1 < 0
+	bge	divide
+	neg	%o1
+	2:
+	! %o0 < 0
+	neg	%o0
+	! FALL THROUGH
+divide:
+	! Compute size of quotient, scale comparand.
+	orcc	%o1,%g0,%o5		! movcc %o1,%o5
+	te	2			! if %o1 = 0
+	mov	%o0,%o3
+	mov	0,%o2
+	sethi	%hi(1<<(32-4 -1)),%g1
+	cmp	%o3,%g1
+	blu	not_really_big
+	mov	0,%o4
+	!
+	! Here, the %o0 is >= 2ˆ(31-4) or so. We must be careful here,
+	! as our usual 4-at-a-shot divide step will cause overflow and havoc.
+	! The total number of bits in the result here is 4*%o4+%g2, where
+	! %g2 <= 4.
+	! Compute %o4 in an unorthodox manner: know we need to Shift %o5 into
+! the top decade: so don't even bother to compare to %o3.
+1:
+	cmp	%o5,%g1
+	bgeu	3f
+	mov	1,%g2
+	sll	%o5,4,%o5
+	b	1b
+	inc	%o4
+! Now compute %g2
+2:	addcc	%o5,%o5,%o5
+	bcc	not_too_big
+	add	%g2,1,%g2
+		! We're here if the %o1 overflowed when Shifting.
+		! This means that %o3 has the high-order bit set.
+		! Restore %o5 and subtract from %o3.
+		sll	%g1,4 ,%g1	! high order bit
+		srl	%o5,1,%o5		! rest of %o5
+		add	%o5,%g1,%o5
+		b	do_single_div
+		dec	%g2
+not_too_big:
+3:	cmp	%o5,%o3
+	blu	2b
+	nop
+	be	do_single_div
+	nop
+! %o5 > %o3: went too far: back up 1 step
+!     srl %o5,1,%o5
+!      dec %g2
+! do single-bit divide steps
+!
+! We have to be careful here. We know that %o3 >= %o5, so we can do the
+! first divide step without thinking. BUT, the others are conditional,
+! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high-
+! order bit set in the first step, just falling into the regular
+! division loop will mess up the first time around.
+! So we unroll slightly...
+do_single_div:
+	deccc	%g2
+	bl	end_regular_divide
+	nop
+	sub	%o3,%o5,%o3
+	mov	1,%o2
+	b	end_single_divloop
+	nop
+single_divloop:
+	sll	%o2,1,%o2
+	bl	1f
+	srl	%o5,1,%o5
+	! %o3 >= 0
+		sub	%o3,%o5,%o3
+		b	2f
+		inc	%o2
+	1:	! %o3 < 0
+		add	%o3,%o5,%o3
+		dec	%o2
+	2:
+	end_single_divloop:
+		deccc	%g2
+		bge	single_divloop
+		tst	%o3
+		b	end_regular_divide
+		nop
+not_really_big:
+1:
+	sll	%o5,4,%o5
+	cmp	%o5,%o3
+	bleu	1b
+	inccc	%o4
+	be	got_result
+	dec	%o4
+do_regular_divide:
+	! Do the main division iteration
+	tst	%o3
+	! Fall through into divide loop
+divloop:
+	sll	%o2,4,%o2
+		!depth 1, accumulated bits 0
+	bl	L.1.16
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 2, accumulated bits 1
+	bl	L.2.17
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 3, accumulated bits 3
+	bl	L.3.19
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits 7
+	bl	L.4.23
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (7*2+1), %o2
+L.4.23:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (7*2-1), %o2
+L.3.19:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits 5
+	bl	L.4.21
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (5*2+1), %o2
+L.4.21:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (5*2-1), %o2
+L.2.17:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 3, accumulated bits 1
+	bl	L.3.17
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits 3
+	bl	L.4.19
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (3*2+1), %o2
+L.4.19:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (3*2-1), %o2
+L.3.17:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits 1
+	bl	L.4.17
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (1*2+1), %o2
+L.4.17:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (1*2-1), %o2
+L.1.16:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 2, accumulated bits -1
+	bl	L.2.15
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 3, accumulated bits -1
+	bl	L.3.15
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits -1
+	bl	L.4.15
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-1*2+1), %o2
+L.4.15:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-1*2-1), %o2
+L.3.15:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits -3
+	bl	L.4.13
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-3*2+1), %o2
+L.4.13:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-3*2-1), %o2
+L.2.15:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 3, accumulated bits -3
+	bl	L.3.13
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits -5
+	bl	L.4.11
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-5*2+1), %o2
+L.4.11:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-5*2-1), %o2
+L.3.13:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+	 	!depth 4, accumulated bits -7
+	bl	L.4.9
+	srl	%o5,1,%o5
+	! remainder is nonnegative
+	subcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-7*2+1), %o2
+L.4.9:
+	! remainder is negative
+	addcc	%o3,%o5,%o3
+		b	9f
+		add	%o2, (-7*2-1), %o2
+	9:
+end_regular_divide:
+	deccc	%o4
+	bge	divloop
+	tst	%o3
+	bge	got_result
+	nop
+	! non-restoring fixup here
+	add	%o3,%o1,%o3
+got_result:
+	tst	%g3
+	bge	1f
+	restore
+	! answer < 0
+	retl				! leaf-routine return
+	neg	%o3,%o0 		! remainder <- -%o3
+1:
+	retl				! leaf-routine return
+	mov	%o3,%o0			! remainder <- %o3
diff -r b112b8e55492 -r 484dfe564ae6 head/contrib/compiler-rt/lib/sparc64/udivsi3.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/sparc64/udivsi3.S	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,1 @@
+! This file intentionally left blank
diff -r b112b8e55492 -r 484dfe564ae6 head/contrib/compiler-rt/lib/sparc64/umodsi3.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/contrib/compiler-rt/lib/sparc64/umodsi3.S	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,1 @@
+! This file intentionally left blank
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/accounting
--- a/head/etc/rc.d/accounting	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/accounting	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/accounting 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: accounting
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="accounting"
-rcvar=`set_rcvar`
+rcvar="accounting_enable"
 accounting_command="/usr/sbin/accton"
 accounting_file="/var/account/acct"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/amd
--- a/head/etc/rc.d/amd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/amd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/amd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: amd
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="amd"
-rcvar=`set_rcvar`
+rcvar="amd_enable"
 command="/usr/sbin/${name}"
 start_precmd="amd_precmd"
 command_args="&"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/apm
--- a/head/etc/rc.d/apm	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/apm	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/apm 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: apm
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="apm"
-rcvar=`set_rcvar`
+rcvar="apm_enable"
 start_precmd="apm_precmd"
 command="/usr/sbin/${name}"
 start_cmd="${command} -e enable"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/apmd
--- a/head/etc/rc.d/apmd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/apmd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/apmd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: apmd
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="apmd"
-rcvar=`set_rcvar`
+rcvar="apmd_enable"
 command="/usr/sbin/${name}"
 start_precmd="apmd_prestart"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/bootparams
--- a/head/etc/rc.d/bootparams	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/bootparams	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/bootparams 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: bootparams
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="bootparamd"
-rcvar=`set_rcvar`
+rcvar="bootparamd_enable"
 required_files="/etc/bootparams"
 command="/usr/sbin/${name}"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/bsnmpd
--- a/head/etc/rc.d/bsnmpd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/bsnmpd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/bsnmpd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: bsnmpd
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="bsnmpd"
-rcvar=`set_rcvar`
+rcvar="bsnmpd_enable"
 command="/usr/sbin/${name}"
 pidfile="/var/run/snmpd.pid"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/bthidd
--- a/head/etc/rc.d/bthidd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/bthidd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/bthidd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: bthidd
@@ -11,9 +11,9 @@
 . /etc/rc.subr
 
 name="bthidd"
+rcvar="bthidd_enable"
 command="/usr/sbin/${name}"
 pidfile="/var/run/${name}.pid"
-rcvar=`set_rcvar`
 start_precmd="bthidd_prestart"
 
 bthidd_prestart()
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/cleanvar
--- a/head/etc/rc.d/cleanvar	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/cleanvar	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/cleanvar 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: cleanvar
@@ -9,7 +9,7 @@
 . /etc/rc.subr
 
 name="cleanvar"
-rcvar=`set_rcvar`
+rcvar="cleanvar_enable"
 
 start_precmd="${name}_prestart"
 start_cmd="${name}_start"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/cleartmp
--- a/head/etc/rc.d/cleartmp	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/cleartmp	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/cleartmp 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: cleartmp
@@ -11,7 +11,7 @@
 
 name="cleartmp"
 # Disguise rcvar for the start method to run irrespective of its setting.
-rcvar1=`set_rcvar clear_tmp`
+rcvar1="clear_tmp_enable"
 start_cmd="${name}_start"
 stop_cmd=":"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/cron
--- a/head/etc/rc.d/cron	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/cron	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/cron 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: cron
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="cron"
-rcvar="`set_rcvar`"
+rcvar="cron_enable"
 command="/usr/sbin/${name}"
 pidfile="/var/run/${name}.pid"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ddb
--- a/head/etc/rc.d/ddb	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ddb	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/ddb 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ddb
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="ddb"
-rcvar=`set_rcvar`
+rcvar="ddb_enable"
 command="/sbin/${name}"
 start_precmd="ddb_prestart"
 stop_cmd=":"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/devd
--- a/head/etc/rc.d/devd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/devd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD: head/etc/rc.d/devd 220962 2011-04-23 04:26:31Z dougb $
+# $FreeBSD: head/etc/rc.d/devd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: devd
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="devd"
-rcvar=`set_rcvar`
+rcvar="devd_enable"
 command="/sbin/${name}"
 
 start_precmd=${name}_prestart
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/dmesg
--- a/head/etc/rc.d/dmesg	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/dmesg	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/dmesg 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: dmesg
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="dmesg"
-rcvar=`set_rcvar`
+rcvar="dmesg_enable"
 dmesg_file="/var/run/dmesg.boot"
 start_cmd="do_dmesg"
 stop_cmd=":"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ftp-proxy
--- a/head/etc/rc.d/ftp-proxy	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ftp-proxy	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/ftp-proxy 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ftp-proxy
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="ftpproxy"
-rcvar=`set_rcvar`
+rcvar="ftpproxy_enable"
 command="/usr/sbin/ftp-proxy"
 
 load_rc_config $name
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ftpd
--- a/head/etc/rc.d/ftpd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ftpd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/ftpd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ftpd
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="ftpd"
-rcvar=`set_rcvar`
+rcvar="ftpd_enable"
 command="/usr/libexec/${name}"
 pidfile="/var/run/${name}.pid"
 start_precmd=ftpd_prestart
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/gptboot
--- a/head/etc/rc.d/gptboot	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/gptboot	Mon Jan 16 14:38:30 2012 +0200
@@ -24,7 +24,7 @@
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/gptboot 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: gptboot
@@ -34,7 +34,7 @@
 . /etc/rc.subr
 
 name="gptboot"
-rcvar=`set_rcvar`
+rcvar="gptboot_enable"
 start_cmd="gptboot_report"
 
 gptboot_report()
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/hastd
--- a/head/etc/rc.d/hastd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/hastd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/hastd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: hastd
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="hastd"
-rcvar=`set_rcvar`
+rcvar="hastd_enable"
 pidfile="/var/run/${name}.pid"
 command="/sbin/${name}"
 hastctl="/sbin/hastctl"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/hcsecd
--- a/head/etc/rc.d/hcsecd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/hcsecd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/hcsecd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: hcsecd
@@ -11,9 +11,9 @@
 . /etc/rc.subr
 
 name="hcsecd"
+rcvar="hcsecd_enable"
 command="/usr/sbin/${name}"
 pidfile="/var/run/${name}.pid"
-rcvar=`set_rcvar`
 required_modules="ng_btsocket"
 
 load_rc_config $name
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/hostapd
--- a/head/etc/rc.d/hostapd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/hostapd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/hostapd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: hostapd
@@ -10,8 +10,8 @@
 . /etc/rc.subr
 
 name="hostapd"
+rcvar="hostapd_enable"
 command="/usr/sbin/${name}"
-rcvar=`set_rcvar`
 
 conf_file="/etc/${name}.conf"
 pidfile="/var/run/${name}.pid"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/inetd
--- a/head/etc/rc.d/inetd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/inetd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/inetd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: inetd
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="inetd"
-rcvar=`set_rcvar`
+rcvar="inetd_enable"
 command="/usr/sbin/${name}"
 pidfile="/var/run/${name}.pid"
 required_files="/etc/${name}.conf"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ip6addrctl
--- a/head/etc/rc.d/ip6addrctl	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ip6addrctl	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/ip6addrctl 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ip6addrctl
@@ -12,7 +12,7 @@
 . /etc/network.subr
 
 name="ip6addrctl"
-rcvar=`set_rcvar`
+rcvar="ip6addrctl_enable"
 start_cmd="ip6addrctl_start"
 stop_cmd="ip6addrctl_stop"
 extra_commands="status prefer_ipv6 prefer_ipv4"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ipfilter
--- a/head/etc/rc.d/ipfilter	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ipfilter	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD: head/etc/rc.d/ipfilter 222007 2011-05-17 07:40:13Z hrs $
+# $FreeBSD: head/etc/rc.d/ipfilter 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ipfilter
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="ipfilter"
-rcvar=`set_rcvar`
+rcvar="ipfilter_enable"
 load_rc_config $name
 stop_precmd="test -f ${ipfilter_rules} -o -f ${ipv6_ipfilter_rules}"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ipfs
--- a/head/etc/rc.d/ipfs	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ipfs	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/ipfs 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ipfs
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="ipfs"
-rcvar=`set_rcvar`
+rcvar="ipfs_enable"
 start_cmd="ipfs_start"
 stop_cmd="ipfs_stop"
 start_precmd="ipfs_prestart"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ipmon
--- a/head/etc/rc.d/ipmon	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ipmon	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/ipmon 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ipmon
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="ipmon"
-rcvar=`set_rcvar`
+rcvar="ipmon_enable"
 command="/sbin/${name}"
 start_precmd="ipmon_precmd"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ipnat
--- a/head/etc/rc.d/ipnat	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ipnat	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/ipnat 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ipnat
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="ipnat"
-rcvar=`set_rcvar`
+rcvar="ipnat_enable"
 load_rc_config $name
 start_cmd="ipnat_start"
 stop_cmd="${ipnat_program} -F -C"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ipsec
--- a/head/etc/rc.d/ipsec	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ipsec	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/ipsec 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ipsec
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="ipsec"
-rcvar=`set_rcvar`
+rcvar="ipsec_enable"
 start_precmd="ipsec_prestart"
 start_cmd="ipsec_start"
 stop_precmd="test -f $ipsec_file"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ipxrouted
--- a/head/etc/rc.d/ipxrouted	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ipxrouted	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/ipxrouted 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ipxrouted
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="ipxrouted"
-rcvar=`set_rcvar`
+rcvar="ipxrouted_enable"
 command="/usr/sbin/IPXrouted"
 command_args="> /dev/null 2>&1"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/jail
--- a/head/etc/rc.d/jail	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/jail	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD: head/etc/rc.d/jail 220153 2011-03-30 01:19:00Z emaste $
+# $FreeBSD: head/etc/rc.d/jail 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: jail
@@ -17,7 +17,7 @@
 . /etc/rc.subr
 
 name="jail"
-rcvar=`set_rcvar`
+rcvar="jail_enable"
 
 start_precmd="jail_prestart"
 start_cmd="jail_start"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/keyserv
--- a/head/etc/rc.d/keyserv	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/keyserv	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/keyserv 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # Start keyserv if we are running Secure RPC
@@ -13,7 +13,7 @@
 . /etc/rc.subr
 
 name="keyserv"
-rcvar=`set_rcvar`
+rcvar="keyserv_enable"
 command="/usr/sbin/${name}"
 start_precmd="keyserv_prestart"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/lpd
--- a/head/etc/rc.d/lpd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/lpd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/lpd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: lpd
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="lpd"
-rcvar=`set_rcvar`
+rcvar="lpd_enable"
 command="/usr/sbin/${name}"
 required_files="/etc/printcap"
 start_precmd="chkprintcap"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/mountd
--- a/head/etc/rc.d/mountd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/mountd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD: head/etc/rc.d/mountd 223852 2011-07-08 00:49:50Z rmacklem $
+# $FreeBSD: head/etc/rc.d/mountd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: mountd
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="mountd"
-rcvar=`set_rcvar`
+rcvar="mountd_enable"
 command="/usr/sbin/${name}"
 pidfile="/var/run/${name}.pid"
 required_files="/etc/exports"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/moused
--- a/head/etc/rc.d/moused	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/moused	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/moused 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: moused
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="moused"
-rcvar=`set_rcvar`
+rcvar="moused_enable"
 command="/usr/sbin/${name}"
 start_cmd="moused_start"
 pidprefix="/var/run/moused"
@@ -23,7 +23,7 @@
 #
 if [ -n "$2" ]; then
 	eval moused_$2_enable=\${moused_$2_enable-${moused_nondefault_enable}}
-	rcvar=`set_rcvar moused_$2`
+	rcvar="moused_${2}_enable"
 	pidfile="${pidprefix}.$2.pid"
 	pidarg="-I $pidfile"
 fi
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/mroute6d
--- a/head/etc/rc.d/mroute6d	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/mroute6d	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/mroute6d 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: mroute6d
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="mroute6d"
-rcvar=`set_rcvar`
+rcvar="mroute6d_enable"
 command="/usr/local/sbin/pim6dd"
 
 load_rc_config $name
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/mrouted
--- a/head/etc/rc.d/mrouted	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/mrouted	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/mrouted 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: mrouted
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="mrouted"
-rcvar=`set_rcvar`
+rcvar="mrouted_enable"
 command="/usr/local/sbin/${name}"
 pidfile="/var/run/${name}.pid"
 required_files="/etc/${name}.conf"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/natd
--- a/head/etc/rc.d/natd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/natd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/natd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: natd
@@ -10,7 +10,7 @@
 . /etc/network.subr
 
 name="natd"
-rcvar=`set_rcvar`
+rcvar="natd_enable"
 command="/sbin/${name}"
 pidfile="/var/run/${name}.pid"
 start_precmd="natd_precmd"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/netwait
--- a/head/etc/rc.d/netwait	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/netwait	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# $FreeBSD: head/etc/rc.d/netwait 223408 2011-06-22 06:27:32Z dougb $
+# $FreeBSD: head/etc/rc.d/netwait 230099 2012-01-14 02:18:41Z dougb $
 #
 # PROVIDE: netwait
 # REQUIRE: NETWORKING
@@ -14,7 +14,7 @@
 . /etc/rc.subr
 
 name="netwait"
-rcvar=`set_rcvar`
+rcvar="netwait_enable"
 
 start_cmd="${name}_start"
 stop_cmd=":"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/newsyslog
--- a/head/etc/rc.d/newsyslog	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/newsyslog	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/newsyslog 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: newsyslog
@@ -9,7 +9,7 @@
 . /etc/rc.subr
 
 name="newsyslog"
-rcvar=`set_rcvar`
+rcvar="newsyslog_enable"
 required_files="/etc/newsyslog.conf"
 command="/usr/sbin/${name}"
 start_cmd="newsyslog_start"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/nfscbd
--- a/head/etc/rc.d/nfscbd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/nfscbd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/nfscbd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: nfscbd
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="nfscbd"
-rcvar=`set_rcvar`
+rcvar="nfscbd_enable"
 command="/usr/sbin/${name}"
 sig_stop="USR1"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/nfsd
--- a/head/etc/rc.d/nfsd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/nfsd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD: head/etc/rc.d/nfsd 227112 2011-11-05 16:47:47Z dim $
+# $FreeBSD: head/etc/rc.d/nfsd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: nfsd
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="nfsd"
-rcvar=`set_rcvar nfs_server`
+rcvar="nfs_server_enable"
 command="/usr/sbin/${name}"
 
 load_rc_config $name
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/nfsuserd
--- a/head/etc/rc.d/nfsuserd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/nfsuserd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/nfsuserd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: nfsuserd
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="nfsuserd"
-rcvar=`set_rcvar`
+rcvar="nfsuserd_enable"
 command="/usr/sbin/${name}"
 sig_stop="USR1"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/nscd
--- a/head/etc/rc.d/nscd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/nscd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/nscd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: nscd
@@ -19,7 +19,7 @@
 . /etc/rc.subr
 
 name="nscd"
-rcvar=`set_rcvar`
+rcvar="nscd_enable"
 
 command=/usr/sbin/nscd
 extra_commands="flush"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ntpd
--- a/head/etc/rc.d/ntpd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ntpd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/ntpd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ntpd
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="ntpd"
-rcvar=`set_rcvar`
+rcvar="ntpd_enable"
 command="/usr/sbin/${name}"
 pidfile="/var/run/${name}.pid"
 start_precmd="ntpd_precmd"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ntpdate
--- a/head/etc/rc.d/ntpdate	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ntpdate	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/ntpdate 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ntpdate
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="ntpdate"
-rcvar=`set_rcvar`
+rcvar="ntpdate_enable"
 stop_cmd=":"
 start_cmd="ntpdate_start"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/pf
--- a/head/etc/rc.d/pf	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/pf	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD: head/etc/rc.d/pf 222007 2011-05-17 07:40:13Z hrs $
+# $FreeBSD: head/etc/rc.d/pf 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: pf
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="pf"
-rcvar=`set_rcvar`
+rcvar="pf_enable"
 load_rc_config $name
 start_cmd="pf_start"
 stop_cmd="pf_stop"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/pflog
--- a/head/etc/rc.d/pflog	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/pflog	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/pflog 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: pflog
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="pflog"
-rcvar=`set_rcvar`
+rcvar="pflog_enable"
 command="/sbin/pflogd"
 pidfile="/var/run/pflogd.pid"
 start_precmd="pflog_prestart"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/pfsync
--- a/head/etc/rc.d/pfsync	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/pfsync	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD: head/etc/rc.d/pfsync 229850 2012-01-09 08:50:22Z glebius $
+# $FreeBSD: head/etc/rc.d/pfsync 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: pfsync
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="pfsync"
-rcvar=`set_rcvar`
+rcvar="pfsync_enable"
 start_precmd="pfsync_prestart"
 start_cmd="pfsync_start"
 stop_cmd="pfsync_stop"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/powerd
--- a/head/etc/rc.d/powerd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/powerd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/powerd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: powerd
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="powerd"
-rcvar=`set_rcvar`
+rcvar="powerd_enable"
 command="/usr/sbin/${name}"
 stop_postcmd=powerd_poststop
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ppp
--- a/head/etc/rc.d/ppp	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ppp	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/ppp 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ppp
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="ppp"
-rcvar=`set_rcvar`
+rcvar="ppp_enable"
 command="/usr/sbin/${name}"
 start_cmd="ppp_start"
 stop_cmd="ppp_stop"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/pppoed
--- a/head/etc/rc.d/pppoed	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/pppoed	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/pppoed 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: pppoed
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="pppoed"
-rcvar="`set_rcvar`"
+rcvar="pppoed_enable"
 start_cmd="pppoed_start"
 # XXX stop_cmd will not be straightforward
 stop_cmd=":"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/quota
--- a/head/etc/rc.d/quota	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/quota	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD: head/etc/rc.d/quota 223644 2011-06-28 14:26:34Z pluknet $
+# $FreeBSD: head/etc/rc.d/quota 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # Enable/Check the quotas (must be after ypbind if using NIS)
@@ -13,7 +13,7 @@
 . /etc/rc.subr
 
 name="quota"
-rcvar=`set_rcvar`
+rcvar="quota_enable"
 load_rc_config $name
 start_cmd="quota_start"
 stop_cmd="/usr/sbin/quotaoff ${quotaoff_flags}"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/rarpd
--- a/head/etc/rc.d/rarpd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/rarpd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/rarpd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: rarpd
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="rarpd"
-rcvar=`set_rcvar`
+rcvar="rarpd_enable"
 command="/usr/sbin/${name}"
 pidfile="/var/run/${name}.pid"
 required_files="/etc/ethers"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/rfcomm_pppd_server
--- a/head/etc/rc.d/rfcomm_pppd_server	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/rfcomm_pppd_server	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/rfcomm_pppd_server 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: rfcomm_pppd_server
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="rfcomm_pppd_server"
-rcvar=`set_rcvar`
+rcvar="rfcomm_pppd_server_enable"
 command="/usr/sbin/rfcomm_pppd"
 start_cmd="rfcomm_pppd_server_start"
 stop_cmd="rfcomm_pppd_server_stop"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/route6d
--- a/head/etc/rc.d/route6d	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/route6d	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/route6d 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: route6d
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="route6d"
-rcvar=`set_rcvar`
+rcvar="route6d_enable"
 
 set_rcvar_obsolete ipv6_router_enable route6d_enable
 set_rcvar_obsolete ipv6_router route6d_program
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/routed
--- a/head/etc/rc.d/routed	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/routed	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/routed 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: routed
@@ -10,8 +10,8 @@
 . /etc/rc.subr
 
 name="routed"
+rcvar="routed_enable"
 desc="network RIP and router discovery routing daemon"
-rcvar=`set_rcvar`
 
 set_rcvar_obsolete router_enable routed_enable
 set_rcvar_obsolete router routed_program
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/rpcbind
--- a/head/etc/rc.d/rpcbind	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/rpcbind	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/rpcbind 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: rpcbind
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="rpcbind"
-rcvar=`set_rcvar`
+rcvar="rpcbind_enable"
 command="/usr/sbin/${name}"
 
 stop_postcmd='/bin/rm -f /var/run/rpcbind.*'
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/rtadvd
--- a/head/etc/rc.d/rtadvd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/rtadvd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD: head/etc/rc.d/rtadvd 222997 2011-06-11 21:41:44Z hrs $
+# $FreeBSD: head/etc/rc.d/rtadvd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: rtadvd
@@ -12,7 +12,7 @@
 . /etc/network.subr
 
 name="rtadvd"
-rcvar=`set_rcvar`
+rcvar="rtadvd_enable"
 command="/usr/sbin/${name}"
 start_precmd="rtadvd_precmd"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/rtsold
--- a/head/etc/rc.d/rtsold	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/rtsold	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/rtsold 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: rtsold
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="rtsold"
-rcvar=`set_rcvar`
+rcvar="rtsold_enable"
 command="/usr/sbin/${name}"
 pidfile="/var/run/${name}.pid"
 start_postcmd="rtsold_poststart"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/rwho
--- a/head/etc/rc.d/rwho	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/rwho	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/rwho 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: rwho
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="rwhod"
-rcvar="`set_rcvar`"
+rcvar="rwhod_enable"
 command="/usr/sbin/${name}"
 
 load_rc_config $name
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/sdpd
--- a/head/etc/rc.d/sdpd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/sdpd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/sdpd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: sdpd
@@ -12,7 +12,7 @@
 
 name="sdpd"
 command="/usr/sbin/${name}"
-rcvar=`set_rcvar`
+rcvar="sdpd_enable"
 required_modules="ng_btsocket"
 
 load_rc_config $name
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/sendmail
--- a/head/etc/rc.d/sendmail	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/sendmail	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/sendmail 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: mail
@@ -15,7 +15,7 @@
 . /etc/rc.subr
 
 name="sendmail"
-rcvar=`set_rcvar`
+rcvar="sendmail_enable"
 required_files="/etc/mail/${name}.cf"
 start_precmd="sendmail_precmd"
 
@@ -79,14 +79,14 @@
 
 if checkyesno sendmail_submit_enable; then
 	name="sendmail_submit"
-	rcvar=`set_rcvar`
+	rcvar="sendmail_submit_enable"
 	start_cmd="${command} ${sendmail_submit_flags}"
 	run_rc_command "$1"
 fi
 
 if checkyesno sendmail_outbound_enable; then
 	name="sendmail_outbound"
-	rcvar=`set_rcvar`
+	rcvar="sendmail_outbound_enable"
 	start_cmd="${command} ${sendmail_outbound_flags}"
 	run_rc_command "$1"
 fi
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/sshd
--- a/head/etc/rc.d/sshd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/sshd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD: head/etc/rc.d/sshd 221420 2011-05-04 07:34:44Z des $
+# $FreeBSD: head/etc/rc.d/sshd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: sshd
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="sshd"
-rcvar=`set_rcvar`
+rcvar="sshd_enable"
 command="/usr/sbin/${name}"
 keygen_cmd="sshd_keygen"
 start_precmd="sshd_precmd"
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/syslogd
--- a/head/etc/rc.d/syslogd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/syslogd	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/syslogd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: syslogd
@@ -10,7 +10,7 @@
 . /etc/rc.subr
 
 name="syslogd"
-rcvar=`set_rcvar`
+rcvar="syslogd_enable"
 pidfile="/var/run/syslog.pid"
 command="/usr/sbin/${name}"
 required_files="/etc/syslog.conf"
@@ -41,7 +41,7 @@
 	#
 	for _l in $altlog_proglist; do
 		eval _ldir=\$${_l}_chrootdir
-		if checkyesno `set_rcvar $_l` && [ -n "$_ldir" ]; then
+		if checkyesno ${_l}_enable && [ -n "$_ldir" ]; then
 			echo "${_ldir}/var/run/log" >> $sockfile
 		fi
 	done
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/timed
--- a/head/etc/rc.d/timed	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/timed	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/timed 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: timed
@@ -11,7 +11,7 @@
 . /etc/rc.subr
 
 name="timed"
-rcvar=`set_rcvar`
+rcvar="timed_enable"
 command="/usr/sbin/${name}"
 
 load_rc_config $name
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/ubthidhci
--- a/head/etc/rc.d/ubthidhci	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/ubthidhci	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/ubthidhci 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: ubthidhci
@@ -11,8 +11,8 @@
 . /etc/rc.subr
 
 name="ubthidhci"
+rcvar="ubthidhci_enable"
 command="/usr/sbin/usbconfig"
-rcvar=`set_rcvar`
 start_precmd="ubthidhci_prestart"
 
 ubthidhci_prestart()
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/virecover
--- a/head/etc/rc.d/virecover	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/virecover	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/virecover 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: virecover
@@ -12,7 +12,7 @@
 . /etc/rc.subr
 
 name="virecover"
-rcvar="`set_rcvar`"
+rcvar="virecover_enable"
 stop_cmd=":"
 start_cmd="virecover_start"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.d/watchdogd
--- a/head/etc/rc.d/watchdogd	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.d/watchdogd	Mon Jan 16 14:38:30 2012 +0200
@@ -24,7 +24,7 @@
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 #
-# $FreeBSD$
+# $FreeBSD: head/etc/rc.d/watchdogd 230099 2012-01-14 02:18:41Z dougb $
 #
 
 # PROVIDE: watchdogd
@@ -34,7 +34,7 @@
 . /etc/rc.subr
 
 name="watchdogd"
-rcvar="`set_rcvar`"
+rcvar="watchdogd_enable"
 command="/usr/sbin/${name}"
 pidfile="/var/run/${name}.pid"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/etc/rc.subr
--- a/head/etc/rc.subr	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/etc/rc.subr	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 # $NetBSD: rc.subr,v 1.67 2006/10/07 11:25:15 elad Exp $
-# $FreeBSD: head/etc/rc.subr 230007 2012-01-12 06:48:11Z rea $
+# $FreeBSD: head/etc/rc.subr 230103 2012-01-14 08:59:02Z dougb $
 #
 # Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -54,47 +54,6 @@
 #	functions
 #	---------
 
-# set_rcvar [var] [defval] [desc]
-#
-#	Echo or define a rc.conf(5) variable name.  Global variable
-#	$rcvars is used.
-#
-#	If no argument is specified, echo "${name}_enable".
-#
-#	If only a var is specified, echo "${var}_enable".
-#
-#	If var and defval are specified, the ${var} is defined as
-#	rc.conf(5) variable and the default value is ${defvar}.  An
-#	optional argument $desc can also be specified to add a
-#	description for that.
-#
-set_rcvar()
-{
-	case $# in
-	0)
-		echo ${name}_enable
-		;;
-	1)
-		echo ${1}_enable
-		;;
-	*)
-		debug "rcvar_define: \$$1=$2 is added" \
-		    " as a rc.conf(5) variable."
-
-		local _var
-		_var=$1
-		rcvars="${rcvars# } $_var"
-		eval ${_var}_defval=\"$2\"
-		shift 2
-		# encode multiple lines of _desc
-		for l in "$@"; do
-			eval ${_var}_desc=\"\${${_var}_desc#^^}^^$l\"
-		done
-		eval ${_var}_desc=\"\${${_var}_desc#^^}\"
-		;;
-	esac
-}
-
 # set_rcvar_obsolete oldvar [newvar] [msg]
 #	Define obsolete variable.
 #	Global variable $rcvars_obsolete is used.
@@ -856,8 +815,8 @@
 				echo ""
 			fi
 			echo "#"
-			# Get unique vars in $rcvar $rcvars
-			for _v in $rcvar $rcvars; do
+			# Get unique vars in $rcvar
+			for _v in $rcvar; do
 				case $v in
 				$_v\ *|\ *$_v|*\ $_v\ *) ;;
 				*)	v="${v# } $_v" ;;
@@ -1003,7 +962,7 @@
 
 	unset	name command command_args command_interpreter \
 		extra_commands pidfile procname \
-		rcvar rcvars rcvars_obsolete required_dirs required_files \
+		rcvar rcvars_obsolete required_dirs required_files \
 		required_vars
 	eval unset ${_arg}_cmd ${_arg}_precmd ${_arg}_postcmd
 
@@ -1035,7 +994,7 @@
 #
 load_rc_config()
 {
-	local _name _var _defval _v _msg _new
+	local _name _rcvar_val _var _defval _v _msg _new
 	_name=$1
 	if [ -z "$_name" ]; then
 		err 3 'USAGE: load_rc_config name'
@@ -1060,7 +1019,7 @@
 	fi
 
 	# Set defaults if defined.
-	for _var in $rcvar $rcvars; do
+	for _var in $rcvar; do
 		eval _defval=\$${_var}_defval
 		if [ -n "$_defval" ]; then
 			eval : \${$_var:=\$${_var}_defval}
diff -r b112b8e55492 -r 484dfe564ae6 head/games/morse/morse.c
--- a/head/games/morse/morse.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/games/morse/morse.c	Mon Jan 16 14:38:30 2012 +0200
@@ -43,7 +43,7 @@
 static char sccsid[] = "@(#)morse.c	8.1 (Berkeley) 5/31/93";
 #endif
 static const char rcsid[] =
- "$FreeBSD: head/games/morse/morse.c 227101 2011-11-05 07:18:53Z ed $";
+ "$FreeBSD: head/games/morse/morse.c 230131 2012-01-15 13:23:01Z uqs $";
 #endif /* not lint */
 
 #include <sys/time.h>
@@ -143,26 +143,31 @@
 	{'\0', ""}
 };
 
-
+/*
+ * Code-points for some Latin1 chars in ISO-8859-1 encoding.
+ * UTF-8 encoded chars in the comments.
+ */
 static const struct morsetab iso8859_1tab[] = {
-	{'á', ".--.-"},
-	{'à', ".--.-"},
-	{'â', ".--.-"},
-	{'ä', ".-.-"},
-	{'ç', "-.-.."},
-	{'é', "..-.."},
-	{'è', "..-.."},
-	{'ê', "-..-."},
-	{'ö', "---."},
-	{'ü', "..--"},
+	{'\340', ".--.-"},	/* à */
+	{'\341', ".--.-"},	/* á */
+	{'\342', ".--.-"},	/* â */
+	{'\344', ".-.-"},	/* ä */
+	{'\347', "-.-.."},	/* ç */
+	{'\350', "..-.."},	/* è */
+	{'\351', "..-.."},	/* é */
+	{'\352', "-..-."},	/* ê */
+	{'\366', "---."},	/* ö */
+	{'\374', "..--"},	/* ü */
 
 	{'\0', ""}
 };
 
+/*
+ * Code-points for some Greek chars in ISO-8859-7 encoding.
+ * UTF-8 encoded chars in the comments.
+ */
 static const struct morsetab iso8859_7tab[] = {
 	/*
-	 * The Greek alphabet; you'll need an ISO8859-7 font in order
-	 * to see the actual characters.
 	 * This table does not implement:
 	 * - the special sequences for the seven diphthongs,
 	 * - the punctuation differences.
@@ -180,83 +185,83 @@
 	 * ;	..-.-
 	 * !	--..--
 	 */
-	{'á', ".-"},	/* alpha */
-	{'Ü', ".-"},	/* alpha with acute */
-	{'â', "-..."},	/* beta */
-	{'ã', "--."},	/* gamma */
-	{'ä', "-.."},	/* delta */
-	{'å', "."},	/* epsilon */
-	{'Ý', "."},	/* epsilon with acute */
-	{'æ', "--.."},	/* zeta */
-	{'ç', "...."},	/* eta */
-	{'Þ', "...."},	/* eta with acute */
-	{'è', "-.-."},	/* theta */
-	{'é', ".."},	/* iota */
-	{'ß', ".."},	/* iota with acute */
-	{'ú', ".."},	/* iota with diaeresis */
-	{'À', ".."},	/* iota with acute and diaeresis */
-	{'ê', "-.-"},	/* kappa */
-	{'ë', ".-.."},	/* lambda */
-	{'ì', "--"},	/* mu */
-	{'í', "-."},	/* nu */
-	{'î', "-..-"},	/* xi */
-	{'ï', "---"},	/* omicron */
-	{'ü', "---"},	/* omicron with acute */
-	{'ð', ".--."},	/* pi */
-	{'ñ', ".-."},	/* rho */
-	{'ó', "..."},	/* sigma */
-	{'ò', "..."},	/* final sigma */
-	{'ô', "-"},	/* tau */
-	{'õ', "-.--"},	/* upsilon */
-	{'ý', "-.--"},	/* upsilon with acute */
-	{'û', "-.--"},	/* upsilon and diaeresis */
-	{'à', "-.--"},	/* upsilon with acute and diaeresis */
-	{'ö', "..-."},	/* phi */
-	{'÷', "----"},	/* chi */
-	{'ø', "--.-"},	/* psi */
-	{'ù', ".--"},	/* omega */
-	{'þ', ".--"},	/* omega with acute */
+	{'\341', ".-"},		/* α, alpha */
+	{'\334', ".-"},		/* ά, alpha with acute */
+	{'\342', "-..."},	/* β, beta */
+	{'\343', "--."},	/* γ, gamma */
+	{'\344', "-.."},	/* δ, delta */
+	{'\345', "."},		/* ε, epsilon */
+	{'\335', "."},		/* έ, epsilon with acute */
+	{'\346', "--.."},	/* ζ, zeta */
+	{'\347', "...."},	/* η, eta */
+	{'\336', "...."},	/* ή, eta with acute */
+	{'\350', "-.-."},	/* θ, theta */
+	{'\351', ".."},		/* ι, iota */
+	{'\337', ".."},		/* ί, iota with acute */
+	{'\372', ".."},		/* ÏŠ, iota with diaeresis */
+	{'\300', ".."},		/* ΐ, iota with acute and diaeresis */
+	{'\352', "-.-"},	/* κ, kappa */
+	{'\353', ".-.."},	/* λ, lambda */
+	{'\354', "--"},		/* μ, mu */
+	{'\355', "-."},		/* ν, nu */
+	{'\356', "-..-"},	/* ξ, xi */
+	{'\357', "---"},	/* ο, omicron */
+	{'\374', "---"},	/* ό, omicron with acute */
+	{'\360', ".--."},	/* π, pi */
+	{'\361', ".-."},	/* ρ, rho */
+	{'\363', "..."},	/* σ, sigma */
+	{'\362', "..."},	/* Ï‚, final sigma */
+	{'\364', "-"},		/* Ï„, tau */
+	{'\365', "-.--"},	/* Ï
, upsilon */
+	{'\375', "-.--"},	/* ύ, upsilon with acute */
+	{'\373', "-.--"},	/* Ï‹, upsilon and diaeresis */
+	{'\340', "-.--"},	/* ΰ, upsilon with acute and diaeresis */
+	{'\366', "..-."},	/* φ, phi */
+	{'\367', "----"},	/* χ, chi */
+	{'\370', "--.-"},	/* ψ, psi */
+	{'\371', ".--"},	/* ω, omega */
+	{'\376', ".--"},	/* ÏŽ, omega with acute */
 
 	{'\0', ""}
 };
 
+/*
+ * Code-points for the Cyrillic alphabet in KOI8-R encoding.
+ * UTF-8 encoded chars in the comments.
+ */
 static const struct morsetab koi8rtab[] = {
-	/*
-	 * The Cyrillic alphabet; you'll need a KOI8-R font in order
-	 * to see the actual characters
-	 */
-	{'Á', ".-"},	/* a */
-	{'Â', "-..."},	/* be */
-	{'×', ".--"},	/* ve */
-	{'Ç', "--."},	/* ge */
-	{'Ä', "-.."},	/* de */
-	{'Å', "."},	/* ye */
-	{'£', "."},	/* yo, the same as ye */
-	{'Ö', "...-"},	/* she */
-	{'Ú', "--.."},	/* ze */
-	{'É', ".."},	/* i */
-	{'Ê', ".---"},	/* i kratkoye */
-	{'Ë', "-.-"},	/* ka */
-	{'Ì', ".-.."},	/* el */
-	{'Í', "--"},	/* em */
-	{'Î', "-."},	/* en */
-	{'Ï', "---"},	/* o */
-	{'Ð', ".--."},	/* pe */
-	{'Ò', ".-."},	/* er */
-	{'Ó', "..."},	/* es */
-	{'Ô', "-"},	/* te */
-	{'Õ', "..-"},	/* u */
-	{'Æ', "..-."},	/* ef */
-	{'È', "...."},	/* kha */
-	{'Ã', "-.-."},	/* ce */
-	{'Þ', "---."},	/* che */
-	{'Û', "----"},	/* sha */
-	{'Ý', "--.-"},	/* shcha */
-	{'Ù', "-.--"},	/* yi */
-	{'Ø', "-..-"},	/* myakhkij znak */
-	{'Ü', "..-.."},	/* ae */
-	{'À', "..--"},	/* yu */
-	{'Ñ', ".-.-"},	/* ya */
+	{'\301', ".-"},		/* а, a */
+	{'\302', "-..."},	/* б, be */
+	{'\327', ".--"},	/* в, ve */
+	{'\307', "--."},	/* г, ge */
+	{'\304', "-.."},	/* д, de */
+	{'\305', "."},		/* е, ye */
+	{'\243', "."},		/* Ñ‘, yo, the same as ye */
+	{'\326', "...-"},	/* ж, she */
+	{'\332', "--.."},	/* з, ze */
+	{'\311', ".."},		/* и, i */
+	{'\312', ".---"},	/* й, i kratkoye */
+	{'\313', "-.-"},	/* к, ka */
+	{'\314', ".-.."},	/* л, el */
+	{'\315', "--"},		/* м, em */
+	{'\316', "-."},		/* н, en */
+	{'\317', "---"},	/* о, o */
+	{'\320', ".--."},	/* п, pe */
+	{'\322', ".-."},	/* р, er */
+	{'\323', "..."},	/* с, es */
+	{'\324', "-"},		/* Ñ‚, te */
+	{'\325', "..-"},	/* у, u */
+	{'\306', "..-."},	/* Ñ„, ef */
+	{'\310', "...."},	/* Ñ
, kha */
+	{'\303', "-.-."},	/* ц, ce */
+	{'\336', "---."},	/* ч, che */
+	{'\333', "----"},	/* ш, sha */
+	{'\335', "--.-"},	/* щ, shcha */
+	{'\331', "-.--"},	/* Ñ‹, yi */
+	{'\330', "-..-"},	/* ь, myakhkij znak */
+	{'\334', "..-.."},	/* э, ae */
+	{'\300', "..--"},	/* ÑŽ, yu */
+	{'\321', ".-.-"},	/* я, ya */
 
 	{'\0', ""}
 };
diff -r b112b8e55492 -r 484dfe564ae6 head/include/stdatomic.h
--- a/head/include/stdatomic.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/include/stdatomic.h	Mon Jan 16 14:38:30 2012 +0200
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/include/stdatomic.h 229332 2012-01-02 22:58:32Z ed $
+ * $FreeBSD: head/include/stdatomic.h 230062 2012-01-13 16:01:34Z ed $
  */
 
 #ifndef _STDATOMIC_H_
@@ -325,9 +325,8 @@
 	atomic_compare_exchange_strong_explicit(object, 0, 1, order, order)
 
 #define	atomic_flag_clear(object)					\
-	atomic_flag_clear_explicit(object, 0, memory_order_seq_cst)
+	atomic_flag_clear_explicit(object, memory_order_seq_cst)
 #define	atomic_flag_test_and_set(object)				\
-	atomic_flag_test_and_set_explicit(object, 0, 1,			\
-	    memory_order_seq_cst, memory_order_seq_cst)
+	atomic_flag_test_and_set_explicit(object, memory_order_seq_cst)
 
 #endif /* !_STDATOMIC_H_ */
diff -r b112b8e55492 -r 484dfe564ae6 head/include/xlocale.h
--- a/head/include/xlocale.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/include/xlocale.h	Mon Jan 16 14:38:30 2012 +0200
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/include/xlocale.h 227753 2011-11-20 14:45:42Z theraven $
+ * $FreeBSD: head/include/xlocale.h 230156 2012-01-15 20:37:39Z avg $
  */
 
 #ifndef _XLOCALE_H_
@@ -157,9 +157,9 @@
 		__scanflike(3, 0);
 int	 vscanf_l(locale_t, const char * __restrict, __va_list) __scanflike(2, 0);
 int	 vsnprintf_l(char * __restrict, size_t, locale_t, const char * __restrict,
-		va_list) __printflike(4, 0);
+		__va_list) __printflike(4, 0);
 int	 vsscanf_l(const char * __restrict, locale_t, const char * __restrict,
-		va_list) __scanflike(3, 0);
+		__va_list) __scanflike(3, 0);
 int	 dprintf_l(int, locale_t, const char * __restrict, ...) __printflike(3, 4);
 int	 vdprintf_l(int, locale_t, const char * __restrict, __va_list)
 		__printflike(3, 0);
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/arm/_fpmath.h
--- a/head/lib/libc/arm/_fpmath.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/arm/_fpmath.h	Mon Jan 16 14:38:30 2012 +0200
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/lib/libc/arm/_fpmath.h 230188 2012-01-16 04:04:35Z das $
  */
 
 #if defined(__VFP_FP__)
@@ -55,9 +55,10 @@
 };
 
 #define	LDBL_NBIT	0
+#define	LDBL_IMPLICIT_NBIT
 #define	mask_nbit_l(u)	((void)0)
 
-#define	LDBL_MANH_SIZE	32
+#define	LDBL_MANH_SIZE	20
 #define	LDBL_MANL_SIZE	32
 
 #define	LDBL_TO_ARRAY32(u, a) do {			\
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/arm/gen/Makefile.inc
--- a/head/lib/libc/arm/gen/Makefile.inc	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/arm/gen/Makefile.inc	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 #	@(#)Makefile.inc	8.1 (Berkeley) 6/4/93
-# $FreeBSD: head/lib/libc/arm/gen/Makefile.inc 226606 2011-10-21 06:40:36Z das $
+# $FreeBSD: head/lib/libc/arm/gen/Makefile.inc 230191 2012-01-16 04:08:29Z das $
 
 SRCS+=	_ctx_start.S _setjmp.S _set_tp.c alloca.S fabs.c \
 	infinity.c ldexp.c makecontext.c \
-	setjmp.S signalcontext.c sigsetjmp.S divsi3.S
+	setjmp.S signalcontext.c sigsetjmp.S divsi3.S flt_rounds.c
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/arm/gen/flt_rounds.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/lib/libc/arm/gen/flt_rounds.c	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2012 Ian Lepore <freebsd at damnhippie.dyndns.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/lib/libc/arm/gen/flt_rounds.c 230191 2012-01-16 04:08:29Z das $");
+
+#include <fenv.h>
+#include <float.h>
+
+#include "softfloat.h"
+
+int
+__flt_rounds(void)
+{
+
+#ifndef ARM_HARD_FLOAT
+	/*
+	 * Translate our rounding modes to the unnamed
+	 * manifest constants required by C99 et. al.
+	 */
+	switch (__softfloat_float_rounding_mode) {
+	case FE_TOWARDZERO:
+		return (0);
+	case FE_TONEAREST:
+		return (1);
+	case FE_UPWARD:
+		return (2);
+	case FE_DOWNWARD:
+		return (3);
+	}
+	return (-1);
+#else /* ARM_HARD_FLOAT */
+	/*
+	 * Apparently, the rounding mode is specified as part of the
+	 * instruction format on ARM, so the dynamic rounding mode is
+	 * indeterminate.  Some FPUs may differ.
+	 */
+	return (-1);
+#endif /* ARM_HARD_FLOAT */
+}
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/arm/softfloat/softfloat.h
--- a/head/lib/libc/arm/softfloat/softfloat.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/arm/softfloat/softfloat.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*	$NetBSD: softfloat.h,v 1.6 2002/05/12 13:12:46 bjh21 Exp $	*/
-/* $FreeBSD$ */
+/* $FreeBSD: head/lib/libc/arm/softfloat/softfloat.h 230189 2012-01-16 04:05:53Z das $ */
 
 /* This is a derivative work. */
 
@@ -45,7 +45,7 @@
 /* #define FLOATX80 */
 /* #define FLOAT128 */
 
-#include <machine/ieeefp.h>
+#include <fenv.h>
 
 /*
 -------------------------------------------------------------------------------
@@ -84,12 +84,12 @@
 Software IEC/IEEE floating-point rounding mode.
 -------------------------------------------------------------------------------
 */
-extern fp_rnd_t float_rounding_mode;
+extern int float_rounding_mode;
 enum {
-    float_round_nearest_even = FP_RN,
-    float_round_to_zero      = FP_RZ,
-    float_round_down         = FP_RM,
-    float_round_up           = FP_RP
+    float_round_nearest_even = FE_TONEAREST,
+    float_round_to_zero      = FE_TOWARDZERO,
+    float_round_down         = FE_DOWNWARD,
+    float_round_up           = FE_UPWARD
 };
 
 /*
@@ -97,14 +97,14 @@
 Software IEC/IEEE floating-point exception flags.
 -------------------------------------------------------------------------------
 */
-extern fp_except float_exception_flags;
-extern fp_except float_exception_mask;
+extern int float_exception_flags;
+extern int float_exception_mask;
 enum {
-    float_flag_inexact   = FP_X_IMP,
-    float_flag_underflow = FP_X_UFL,
-    float_flag_overflow  = FP_X_OFL,
-    float_flag_divbyzero = FP_X_DZ,
-    float_flag_invalid   = FP_X_INV
+    float_flag_inexact   = FE_INEXACT,
+    float_flag_underflow = FE_UNDERFLOW,
+    float_flag_overflow  = FE_OVERFLOW,
+    float_flag_divbyzero = FE_DIVBYZERO,
+    float_flag_invalid   = FE_INVALID
 };
 
 /*
@@ -113,7 +113,7 @@
 exception flags.
 -------------------------------------------------------------------------------
 */
-void float_raise( fp_except );
+void float_raise( int );
 
 /*
 -------------------------------------------------------------------------------
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/gen/getutxent.3
--- a/head/lib/libc/gen/getutxent.3	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/gen/getutxent.3	Mon Jan 16 14:38:30 2012 +0200
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/lib/libc/gen/getutxent.3 226847 2011-10-27 17:21:41Z ed $
+.\" $FreeBSD: head/lib/libc/gen/getutxent.3 230060 2012-01-13 15:40:49Z ed $
 .\"
 .Dd October 27, 2011
 .Dt GETUTXENT 3
@@ -418,7 +418,6 @@
 .Sh SEE ALSO
 .Xr last 1 ,
 .Xr write 1 ,
-.Xr wtmpcvt 1 ,
 .Xr getpid 2 ,
 .Xr gettimeofday 2 ,
 .Xr tty 4 ,
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/gen/sem.c
--- a/head/lib/libc/gen/sem.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/gen/sem.c	Mon Jan 16 14:38:30 2012 +0200
@@ -27,7 +27,7 @@
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/lib/libc/gen/sem.c 230201 2012-01-16 06:15:14Z davidxu $
  */
 
 /*
@@ -434,7 +434,7 @@
 		return ksem_post((*sem)->semid);
 
 	atomic_add_rel_int(&(*sem)->count, 1);
-
+	rmb();
 	if ((*sem)->nwaiters)
 		return _umtx_wake(&(*sem)->count);
 	return (0);
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/gen/sem_new.c
--- a/head/lib/libc/gen/sem_new.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/gen/sem_new.c	Mon Jan 16 14:38:30 2012 +0200
@@ -26,7 +26,7 @@
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/lib/libc/gen/sem_new.c 230201 2012-01-16 06:15:14Z davidxu $
  */
 
 #include "namespace.h"
@@ -332,6 +332,7 @@
 static __inline int
 usem_wake(struct _usem *sem)
 {
+	rmb();
 	if (!sem->_has_waiters)
 		return (0);
 	return _umtx_op(sem, UMTX_OP_SEM_WAKE, 0, NULL, NULL);
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/mips/softfloat/softfloat.h
--- a/head/lib/libc/mips/softfloat/softfloat.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/mips/softfloat/softfloat.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*	$NetBSD: softfloat.h,v 1.6 2002/05/12 13:12:46 bjh21 Exp $	*/
-/* $FreeBSD$ */
+/* $FreeBSD: head/lib/libc/mips/softfloat/softfloat.h 230189 2012-01-16 04:05:53Z das $ */
 
 /* This is a derivative work. */
 
@@ -45,7 +45,7 @@
 /* #define FLOATX80 */
 /* #define FLOAT128 */
 
-#include <machine/ieeefp.h>
+#include <fenv.h>
 
 /*
 -------------------------------------------------------------------------------
@@ -84,12 +84,12 @@
 Software IEC/IEEE floating-point rounding mode.
 -------------------------------------------------------------------------------
 */
-extern fp_rnd_t float_rounding_mode;
+extern int float_rounding_mode;
 enum {
-    float_round_nearest_even = FP_RN,
-    float_round_to_zero      = FP_RZ,
-    float_round_down         = FP_RM,
-    float_round_up           = FP_RP
+    float_round_nearest_even = FE_TONEAREST,
+    float_round_to_zero      = FE_TOWARDZERO,
+    float_round_down         = FE_DOWNWARD,
+    float_round_up           = FE_UPWARD
 };
 
 /*
@@ -97,14 +97,14 @@
 Software IEC/IEEE floating-point exception flags.
 -------------------------------------------------------------------------------
 */
-extern fp_except float_exception_flags;
-extern fp_except float_exception_mask;
+extern int float_exception_flags;
+extern int float_exception_mask;
 enum {
-    float_flag_inexact   = FP_X_IMP,
-    float_flag_underflow = FP_X_UFL,
-    float_flag_overflow  = FP_X_OFL,
-    float_flag_divbyzero = FP_X_DZ,
-    float_flag_invalid   = FP_X_INV
+    float_flag_inexact   = FE_INEXACT,
+    float_flag_underflow = FE_UNDERFLOW,
+    float_flag_overflow  = FE_OVERFLOW,
+    float_flag_divbyzero = FE_DIVBYZERO,
+    float_flag_invalid   = FE_INVALID
 };
 
 /*
@@ -113,7 +113,7 @@
 exception flags.
 -------------------------------------------------------------------------------
 */
-void float_raise( fp_except );
+void float_raise( int );
 
 /*
 -------------------------------------------------------------------------------
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/softfloat/Symbol.map
--- a/head/lib/libc/softfloat/Symbol.map	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/softfloat/Symbol.map	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*
- * $FreeBSD$
+ * $FreeBSD: head/lib/libc/softfloat/Symbol.map 230190 2012-01-16 04:06:56Z das $
  */
 
 FBSD_1.0 {
@@ -18,16 +18,10 @@
 };
 
 FBSDprivate_1.0 {
-	_softfloat_float_exception_flags;
-	_softfloat_float_exception_mask;
-	_softfloat_float_rounding_mode;
-	_softfloat_float_raise;
-	_softfloat_float32_eq;
-	_softfloat_float32_le;
-	_softfloat_float32_lt;
-	_softfloat_float64_eq;
-	_softfloat_float64_le;
-	_softfloat_float64_lt;
+	__softfloat_float_exception_flags;
+	__softfloat_float_exception_mask;
+	__softfloat_float_rounding_mode;
+	__softfloat_float_raise;
 	__eqdf2;
 	__eqsf2;
 	__gedf2;
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/softfloat/bits32/softfloat.c
--- a/head/lib/libc/softfloat/bits32/softfloat.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/softfloat/bits32/softfloat.c	Mon Jan 16 14:38:30 2012 +0200
@@ -52,7 +52,7 @@
 */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/libc/softfloat/bits32/softfloat.c 230189 2012-01-16 04:05:53Z das $");
 
 #ifdef SOFTFLOAT_FOR_GCC
 #include "softfloat-for-gcc.h"
@@ -77,8 +77,8 @@
 Floating-point rounding mode and exception flags.
 -------------------------------------------------------------------------------
 */
-fp_rnd_t float_rounding_mode = float_round_nearest_even;
-fp_except float_exception_flags = 0;
+int float_rounding_mode = float_round_nearest_even;
+int float_exception_flags = 0;
 
 /*
 -------------------------------------------------------------------------------
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/softfloat/bits64/softfloat.c
--- a/head/lib/libc/softfloat/bits64/softfloat.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/softfloat/bits64/softfloat.c	Mon Jan 16 14:38:30 2012 +0200
@@ -45,7 +45,7 @@
 */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/libc/softfloat/bits64/softfloat.c 230189 2012-01-16 04:05:53Z das $");
 
 #ifdef SOFTFLOAT_FOR_GCC
 #include "softfloat-for-gcc.h"
@@ -71,8 +71,8 @@
 and exception flags.
 -------------------------------------------------------------------------------
 */
-fp_rnd_t float_rounding_mode = float_round_nearest_even;
-fp_except float_exception_flags = 0;
+int float_rounding_mode = float_round_nearest_even;
+int float_exception_flags = 0;
 #ifdef FLOATX80
 int8 floatx80_rounding_precision = 80;
 #endif
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/softfloat/softfloat-for-gcc.h
--- a/head/lib/libc/softfloat/softfloat-for-gcc.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/softfloat/softfloat-for-gcc.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,21 +1,21 @@
 /* $NetBSD: softfloat-for-gcc.h,v 1.6 2003/07/26 19:24:51 salo Exp $ */
-/* $FreeBSD$ */
+/* $FreeBSD: head/lib/libc/softfloat/softfloat-for-gcc.h 230190 2012-01-16 04:06:56Z das $ */
 
 /*
  * Move private identifiers with external linkage into implementation
  * namespace.  -- Klaus Klein <kleink at NetBSD.org>, May 5, 1999
  */
-#define float_exception_flags	_softfloat_float_exception_flags
-#define float_exception_mask	_softfloat_float_exception_mask
-#define float_rounding_mode	_softfloat_float_rounding_mode
-#define float_raise		_softfloat_float_raise
+#define float_exception_flags	__softfloat_float_exception_flags
+#define float_exception_mask	__softfloat_float_exception_mask
+#define float_rounding_mode	__softfloat_float_rounding_mode
+#define float_raise		__softfloat_float_raise
 /* The following batch are called by GCC through wrappers */
-#define float32_eq		_softfloat_float32_eq
-#define float32_le		_softfloat_float32_le
-#define float32_lt		_softfloat_float32_lt
-#define float64_eq		_softfloat_float64_eq
-#define float64_le		_softfloat_float64_le
-#define float64_lt		_softfloat_float64_lt
+#define float32_eq		__softfloat_float32_eq
+#define float32_le		__softfloat_float32_le
+#define float32_lt		__softfloat_float32_lt
+#define float64_eq		__softfloat_float64_eq
+#define float64_le		__softfloat_float64_le
+#define float64_lt		__softfloat_float64_lt
 
 /*
  * Macros to define functions with the GCC expected names
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/softfloat/softfloat-specialize
--- a/head/lib/libc/softfloat/softfloat-specialize	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/softfloat/softfloat-specialize	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*	$NetBSD: softfloat-specialize,v 1.3 2002/05/12 13:12:45 bjh21 Exp $	*/
-/* $FreeBSD$ */
+/* $FreeBSD: head/lib/libc/softfloat/softfloat-specialize 230189 2012-01-16 04:05:53Z das $ */
 
 /* This is a derivative work. */
 
@@ -58,8 +58,8 @@
 should be simply `float_exception_flags |= flags;'.
 -------------------------------------------------------------------------------
 */
-fp_except float_exception_mask = 0;
-void float_raise( fp_except flags )
+int float_exception_mask = 0;
+void float_raise( int flags )
 {
 
     float_exception_flags |= flags;
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/sparc64/fpu/fpu_emu.h
--- a/head/lib/libc/sparc64/fpu/fpu_emu.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/sparc64/fpu/fpu_emu.h	Mon Jan 16 14:38:30 2012 +0200
@@ -32,7 +32,7 @@
  *
  *	@(#)fpu_emu.h	8.1 (Berkeley) 6/11/93
  *	$NetBSD: fpu_emu.h,v 1.4 2000/08/03 18:32:07 eeh Exp $
- * $FreeBSD$
+ * $FreeBSD: head/lib/libc/sparc64/fpu/fpu_emu.h 230193 2012-01-16 04:09:45Z das $
  */
 
 /*
@@ -159,7 +159,8 @@
  * Each of these may modify its inputs (f1,f2) and/or the temporary.
  * Each returns a pointer to the result and/or sets exceptions.
  */
-#define	__fpu_sub(fe) ((fe)->fe_f2.fp_sign ^= 1, __fpu_add(fe))
+#define	__fpu_sub(fe)	(ISNAN(&(fe)->fe_f2) ? 0 : ((fe)->fe_f2.fp_sign ^= 1), \
+			    __fpu_add(fe))
 
 #ifdef FPU_DEBUG
 #define	FPE_INSN	0x1
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/sparc64/fpu/fpu_mul.c
--- a/head/lib/libc/sparc64/fpu/fpu_mul.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/sparc64/fpu/fpu_mul.c	Mon Jan 16 14:38:30 2012 +0200
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/lib/libc/sparc64/fpu/fpu_mul.c 230193 2012-01-16 04:09:45Z das $");
 
 /*
  * Perform an FPU multiply (return x * y).
@@ -125,10 +125,8 @@
 	 *	The result is x * y (XOR sign, multiply bits, add exponents).
 	 */
 	ORDER(x, y);
-	if (ISNAN(y)) {
-		y->fp_sign ^= x->fp_sign;
+	if (ISNAN(y))
 		return (y);
-	}
 	if (ISINF(y)) {
 		if (ISZERO(x))
 			return (__fpu_newnan(fe));
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libc/sys/setuid.2
--- a/head/lib/libc/sys/setuid.2	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libc/sys/setuid.2	Mon Jan 16 14:38:30 2012 +0200
@@ -26,7 +26,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)setuid.2	8.1 (Berkeley) 6/4/93
-.\" $FreeBSD$
+.\" $FreeBSD: head/lib/libc/sys/setuid.2 230155 2012-01-15 20:14:52Z eadler $
 .\"
 .Dd June 4, 1993
 .Dt SETUID 2
@@ -170,7 +170,7 @@
 .Pp
 To prevent these files from remaining open after an
 .Xr exec 3
-call, be sure to set the close-on-exec flag is set:
+call, be sure to set the close-on-exec flag:
 .Bd -literal
 void
 pseudocode(void)
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libkvm/kvm_proc.c
--- a/head/lib/libkvm/kvm_proc.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libkvm/kvm_proc.c	Mon Jan 16 14:38:30 2012 +0200
@@ -38,7 +38,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libkvm/kvm_proc.c 227839 2011-11-22 21:12:28Z trociny $");
+__FBSDID("$FreeBSD: head/lib/libkvm/kvm_proc.c 230146 2012-01-15 18:51:07Z trociny $");
 
 /*
  * Proc traversal interface for kvm.  ps and w are (probably) the exclusive
@@ -658,30 +658,38 @@
 			buflen = nchr;
 		}
 	}
-	if (buf != NULL) {
-		oid[0] = CTL_KERN;
-		oid[1] = KERN_PROC;
-		oid[2] = env ? KERN_PROC_ENV : KERN_PROC_ARGS;
-		oid[3] = kp->ki_pid;
-		bufsz = buflen;
-		i = sysctl(oid, 4, buf, &bufsz, 0, 0);
-		if (i == 0 && bufsz > 0) {
-			i = 0;
-			p = buf;
-			do {
-				bufp[i++] = p;
-				p += strlen(p) + 1;
-				if (i >= argc) {
-					argc += argc;
-					bufp = realloc(bufp,
-					    sizeof(char *) * argc);
-				}
-			} while (p < buf + bufsz);
-			bufp[i++] = 0;
-			return (bufp);
+	oid[0] = CTL_KERN;
+	oid[1] = KERN_PROC;
+	oid[2] = env ? KERN_PROC_ENV : KERN_PROC_ARGS;
+	oid[3] = kp->ki_pid;
+	bufsz = buflen;
+	if (sysctl(oid, 4, buf, &bufsz, 0, 0) == -1) {
+		/*
+		 * If the supplied buf is too short to hold the requested
+		 * value the sysctl returns with ENOMEM. The buf is filled
+		 * with the truncated value and the returned bufsz is equal
+		 * to the requested len.
+		 */
+		if (errno != ENOMEM || bufsz != (size_t)buflen)
+			return (0);
+		buf[bufsz - 1] = '\0';
+		errno = 0;
+	} else if (bufsz == 0) {
+		return (0);
+	}
+	i = 0;
+	p = buf;
+	do {
+		bufp[i++] = p;
+		p += strlen(p) + 1;
+		if (i >= argc) {
+			argc += argc;
+			bufp = realloc(bufp,
+			    sizeof(char *) * argc);
 		}
-	}
-	return (NULL);
+	} while (p < buf + bufsz);
+	bufp[i++] = 0;
+	return (bufp);
 }
 
 char **
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libutil/Makefile
--- a/head/lib/libutil/Makefile	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libutil/Makefile	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 #	@(#)Makefile	8.1 (Berkeley) 6/4/93
-#	$FreeBSD: head/lib/libutil/Makefile 229943 2012-01-10 22:22:35Z ghelmer $
+#	$FreeBSD: head/lib/libutil/Makefile 230016 2012-01-12 15:45:08Z ghelmer $
 
 SHLIBDIR?= /lib
 
@@ -25,48 +25,48 @@
 
 CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../libc/gen/
 
-MAN+=	kld.3 login_auth.3 login_tty.3 pty.3 \
-	login_cap.3 login_class.3 login_times.3 login_ok.3 \
-	_secure_path.3 uucplock.3 property.3 auth.3 realhostname.3 \
-	realhostname_sa.3 trimdomain.3 fparseln.3 humanize_number.3 \
-	pidfile.3 flopen.3 expand_number.3 hexdump.3 \
-	kinfo_getfile.3 kinfo_getallproc.3 kinfo_getproc.3 \
-	kinfo_getvmmap.3 quotafile.3
-MAN+=	login.conf.5 auth.conf.5
+MAN+=	auth.3 expand_number.3 flopen.3 fparseln.3 hexdump.3 \
+	humanize_number.3 kinfo_getallproc.3 kinfo_getfile.3 \
+	kinfo_getproc.3 kinfo_getvmmap.3 kld.3 login_auth.3 login_cap.3 \
+	login_class.3 login_ok.3 login_times.3 login_tty.3 pidfile.3 \
+	property.3 pty.3 quotafile.3 realhostname.3 realhostname_sa.3 \
+	_secure_path.3 trimdomain.3 uucplock.3
+MAN+=	auth.conf.5 login.conf.5
+MLINKS+= auth.3 auth_getval.3
 MLINKS+= kld.3 kld_isloaded.3 kld.3 kld_load.3
-MLINKS+= property.3 properties_read.3  property.3 properties_free.3
-MLINKS+= property.3 property_find.3
-MLINKS+= auth.3 auth_getval.3
-MLINKS+= pty.3 openpty.3  pty.3 forkpty.3
-MLINKS+=login_cap.3 login_getclassbyname.3 login_cap.3 login_close.3 \
-	login_cap.3 login_getclass.3 login_cap.3 login_getuserclass.3 \
-	login_cap.3 login_getcapstr.3 login_cap.3 login_getcaplist.3 \
-	login_cap.3 login_getstyle.3 login_cap.3 login_getcaptime.3 \
-	login_cap.3 login_getcapnum.3 login_cap.3 login_getcapsize.3 \
-	login_cap.3 login_getcapbool.3 login_cap.3 login_getpath.3 \
-	login_cap.3 login_getpwclass.3 login_cap.3 login_setcryptfmt.3
-MLINKS+=login_class.3 setusercontext.3 login_class.3 setclasscontext.3 \
-	login_class.3 setclassenvironment.3 login_class.3 setclassresources.3
-MLINKS+=login_times.3 parse_lt.3 login_times.3 in_ltm.3 \
-	login_times.3 in_lt.3 login_times.3 in_ltms.3 \
-	login_times.3 in_lts.3
-MLINKS+=login_ok.3 auth_ttyok.3 login_ok.3 auth_hostok.3 \
-	login_ok.3 auth_timeok.3
-MLINKS+=login_auth.3 auth_checknologin.3 login_auth.3 auth_cat.3
+MLINKS+=login_auth.3 auth_cat.3 login_auth.3 auth_checknologin.3
+MLINKS+=login_cap.3 login_close.3 login_cap.3 login_getcapbool.3 \
+	login_cap.3 login_getcaplist.3 login_cap.3 login_getcapnum.3 \
+	login_cap.3 login_getcapsize.3 login_cap.3 login_getcapstr.3 \
+	login_cap.3 login_getcaptime.3 login_cap.3 login_getclass.3 \
+	login_cap.3 login_getclassbyname.3 login_cap.3 login_getpath.3 \
+	login_cap.3 login_getpwclass.3 login_cap.3 login_getstyle.3 \
+	login_cap.3 login_getuserclass.3 login_cap.3 login_setcryptfmt.3
+MLINKS+=login_class.3 setclasscontext.3 login_class.3 setclassenvironment.3 \
+	login_class.3 setclassresources.3 login_class.3 setusercontext.3
+MLINKS+=login_ok.3 auth_hostok.3 login_ok.3 auth_timeok.3 \
+	login_ok.3 auth_ttyok.3
+MLINKS+=login_times.3 in_lt.3 login_times.3 in_ltm.3 \
+	login_times.3 in_ltms.3 \
+	login_times.3 in_lts.3 \
+	login_times.3 parse_lt.3
+MLINKS+=pidfile.3 pidfile_close.3 \
+	pidfile.3 pidfile_fileno.3 \
+	pidfile.3 pidfile_open.3 \
+	pidfile.3 pidfile_remove.3 \
+	pidfile.3 pidfile_write.3
+MLINKS+= property.3 property_find.3  property.3 properties_free.3
+MLINKS+= property.3 properties_read.3
+MLINKS+= pty.3 forkpty.3  pty.3 openpty.3
+MLINKS+=quotafile.3 quota_close.3 \
+	quotafile.3 quota_fsname.3 \
+	quotafile.3 quota_open.3 \
+	quotafile.3 quota_qfname.3 \
+	quotafile.3 quota_read.3 \
+	quotafile.3 quota_statfs.3 \
+	quotafile.3 quota_write_limits.3 \
+	quotafile.3 quota_write_usage.3
 MLINKS+=uucplock.3 uu_lock.3 uucplock.3 uu_lock_txfr.3 \
-	uucplock.3 uu_unlock.3 uucplock.3 uu_lockerr.3
-MLINKS+=pidfile.3 pidfile_open.3 \
-	pidfile.3 pidfile_write.3 \
-	pidfile.3 pidfile_close.3 \
-	pidfile.3 pidfile_remove.3 \
-	pidfile.3 pidfile_fileno.3
-MLINKS+=quotafile.3 quota_open.3 \
-	quotafile.3 quota_fsname.3 \
-	quotafile.3 quota_qfname.3 \
-	quotafile.3 quota_statfs.3 \
-	quotafile.3 quota_read.3 \
-	quotafile.3 quota_write_limits.3 \
-	quotafile.3 quota_write_usage.3 \
-	quotafile.3 quota_close.3
+	uucplock.3 uu_lockerr.3 uucplock.3 uu_unlock.3 
 
 .include <bsd.lib.mk>
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libutil/libutil.h
--- a/head/lib/libutil/libutil.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libutil/libutil.h	Mon Jan 16 14:38:30 2012 +0200
@@ -33,7 +33,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/lib/libutil/libutil.h 229988 2012-01-11 22:45:15Z ghelmer $
+ * $FreeBSD: head/lib/libutil/libutil.h 230037 2012-01-12 22:49:36Z ghelmer $
  */
 
 #ifndef _LIBUTIL_H_
@@ -48,6 +48,11 @@
 #define	_GID_T_DECLARED
 #endif
 
+#ifndef _MODE_T_DECLARED
+typedef __mode_t	mode_t;
+#define _MODE_T_DECLARED
+#endif
+
 #ifndef _PID_T_DECLARED
 typedef	__pid_t		pid_t;
 #define	_PID_T_DECLARED
@@ -69,25 +74,16 @@
 /* for properties.c */
 typedef struct _property {
 	struct _property *next;
-	char *name;
-	char *value;
+	char	*name;
+	char	*value;
 } *properties;
 
-#ifdef _SYS_PARAM_H_
-/* for pidfile.c */
-struct pidfh {
-	int	pf_fd;
-	char	pf_path[MAXPATHLEN + 1];
-	__dev_t	pf_dev;
-	ino_t	pf_ino;
-};
-#endif
-
 /* Avoid pulling in all the include files for no need */
 struct in_addr;
 struct kinfo_file;
 struct kinfo_proc;
 struct kinfo_vmentry;
+struct pidfh;
 struct sockaddr;
 struct termios;
 struct winsize;
@@ -121,7 +117,7 @@
 void	properties_free(properties _list);
 char	*property_find(properties _list, const char *_name);
 properties
-	properties_read(int fd);
+	properties_read(int _fd);
 int	realhostname(char *_host, size_t _hsize, const struct in_addr *_ip);
 int	realhostname_sa(char *_host, size_t _hsize, struct sockaddr *_addr,
 	    int _addrlen);
@@ -139,8 +135,10 @@
 #endif
 
 #ifdef _PWD_H_
-int	pw_copy(int _ffd, int _tfd, const struct passwd *_pw, struct passwd *_old_pw);
-struct passwd *pw_dup(const struct passwd *_pw);
+int	pw_copy(int _ffd, int _tfd, const struct passwd *_pw,
+	    struct passwd *_old_pw);
+struct passwd
+	*pw_dup(const struct passwd *_pw);
 int	pw_edit(int _notsetuid);
 int	pw_equal(const struct passwd *_pw1, const struct passwd *_pw2);
 void	pw_fini(void);
@@ -149,32 +147,35 @@
 char	*pw_make_v7(const struct passwd *_pw);
 int	pw_mkdb(const char *_user);
 int	pw_lock(void);
-struct passwd *pw_scan(const char *_line, int _flags);
-const char *pw_tempname(void);
+struct passwd
+	*pw_scan(const char *_line, int _flags);
+const char
+	*pw_tempname(void);
 int	pw_tmp(int _mfd);
 #endif
 
 #ifdef _GRP_H_
-int 	gr_copy(int __ffd, int _tfd, const struct group *_gr, struct group *_old_gr);
-struct group *gr_dup(const struct group *_gr);
+int 	gr_copy(int __ffd, int _tfd, const struct group *_gr,
+	    struct group *_old_gr);
+struct group
+	*gr_dup(const struct group *_gr);
 int	gr_equal(const struct group *_gr1, const struct group *_gr2);
 void	gr_fini(void);
 int	gr_init(const char *_dir, const char *_master);
 int	gr_lock(void);
 char	*gr_make(const struct group *_gr);
 int	gr_mkdb(void);
-struct group *gr_scan(const char *_line);
+struct group
+	*gr_scan(const char *_line);
 int	gr_tmp(int _mdf);
 #endif
 
-#ifdef _SYS_PARAM_H_
 int	pidfile_close(struct pidfh *_pfh);
 int	pidfile_fileno(const struct pidfh *_pfh);
 struct pidfh *
 	pidfile_open(const char *_path, mode_t _mode, pid_t *_pidptr);
 int	pidfile_remove(struct pidfh *_pfh);
 int	pidfile_write(struct pidfh *_pfh);
-#endif
 
 #ifdef _UFS_UFS_QUOTA_H_
 struct fstab;
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libutil/pidfile.3
--- a/head/lib/libutil/pidfile.3	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libutil/pidfile.3	Mon Jan 16 14:38:30 2012 +0200
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/lib/libutil/pidfile.3 229942 2012-01-10 21:47:58Z ghelmer $
+.\" $FreeBSD: head/lib/libutil/pidfile.3 230010 2012-01-12 14:13:49Z ghelmer $
 .\"
 .Dd October 16, 2011
 .Dt PIDFILE 3
@@ -81,7 +81,7 @@
 file will be used.
 The
 .Fn pidfile_open
-function sets the FD_CLOEXEC close-on-exec flag on the open file descriptor.
+function sets the O_CLOEXEC close-on-exec flag when opening the pidfile.
 .Pp
 The
 .Fn pidfile_write
@@ -205,7 +205,6 @@
 function may also fail and set
 .Va errno
 for any errors specified for the
-.Xr fcntl 2 ,
 .Xr fstat 2 ,
 .Xr open 2 ,
 and
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/libutil/pidfile.c
--- a/head/lib/libutil/pidfile.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/libutil/pidfile.c	Mon Jan 16 14:38:30 2012 +0200
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libutil/pidfile.c 229966 2012-01-11 16:35:26Z ghelmer $");
+__FBSDID("$FreeBSD: head/lib/libutil/pidfile.c 230037 2012-01-12 22:49:36Z ghelmer $");
 
 #include <sys/param.h>
 #include <sys/file.h>
@@ -41,6 +41,13 @@
 #include <errno.h>
 #include <libutil.h>
 
+struct pidfh {
+	int	pf_fd;
+	char	pf_path[MAXPATHLEN + 1];
+	dev_t	pf_dev;
+	ino_t	pf_ino;
+};
+
 static int _pidfile_remove(struct pidfh *pfh, int freeit);
 
 static int
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/msun/Makefile
--- a/head/lib/msun/Makefile	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/msun/Makefile	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 #  @(#)Makefile 5.1beta 93/09/24
-# $FreeBSD: head/lib/msun/Makefile 226597 2011-10-21 06:27:56Z das $
+# $FreeBSD: head/lib/msun/Makefile 230192 2012-01-16 04:09:17Z das $
 #
 #  ====================================================
 #  Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -125,7 +125,7 @@
 
 SRCS=	${COMMON_SRCS} ${ARCH_SRCS}
 
-INCS=	fenv.h math.h
+INCS+=	fenv.h math.h
 
 MAN=	acos.3 acosh.3 asin.3 asinh.3 atan.3 atan2.3 atanh.3 \
 	ceil.3 ccos.3 ccosh.3 cexp.3 \
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/msun/arm/Makefile.inc
--- a/head/lib/msun/arm/Makefile.inc	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/msun/arm/Makefile.inc	Mon Jan 16 14:38:30 2012 +0200
@@ -1,4 +1,5 @@
-# $FreeBSD$
+# $FreeBSD: head/lib/msun/arm/Makefile.inc 230192 2012-01-16 04:09:17Z das $
 
+INCS += fenv-softfloat.h
 LDBL_PREC = 53
 SYM_MAPS += ${.CURDIR}/arm/Symbol.map
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/msun/arm/fenv.h
--- a/head/lib/msun/arm/fenv.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/lib/msun/arm/fenv.h	Mon Jan 16 14:38:30 2012 +0200
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/lib/msun/arm/fenv.h 226218 2011-10-10 15:43:09Z das $
+ * $FreeBSD: head/lib/msun/arm/fenv.h 230192 2012-01-16 04:09:17Z das $
  */
 
 #ifndef	_FENV_H_
@@ -64,13 +64,25 @@
 #define _FPUSW_SHIFT	16
 #define	_ENABLE_MASK	(FE_ALL_EXCEPT << _FPUSW_SHIFT)
 
-#ifdef	ARM_HARD_FLOAT
+#ifndef	ARM_HARD_FLOAT
+/*
+ * The following macros map between the softfloat emulator's flags and
+ * the hardware's FPSR.  The hardware this file was written for doesn't
+ * have rounding control bits, so we stick those in the system ID byte.
+ */
+#define	__set_env(env, flags, mask, rnd) env = ((flags)			\
+						| (mask)<<_FPUSW_SHIFT	\
+						| (rnd) << 24)
+#define	__env_flags(env)		((env) & FE_ALL_EXCEPT)
+#define	__env_mask(env)			(((env) >> _FPUSW_SHIFT)	\
+						& FE_ALL_EXCEPT)
+#define	__env_round(env)		(((env) >> 24) & _ROUND_MASK)
+#include <fenv-softfloat.h>
+
+#else	/* ARM_HARD_FLOAT */
+
 #define	__rfs(__fpsr)	__asm __volatile("rfs %0" : "=r" (*(__fpsr)))
 #define	__wfs(__fpsr)	__asm __volatile("wfs %0" : : "r" (__fpsr))
-#else
-#define __rfs(__fpsr)
-#define __wfs(__fpsr)
-#endif
 
 __fenv_static inline int
 feclearexcept(int __excepts)
@@ -218,6 +230,8 @@
 
 #endif /* __BSD_VISIBLE */
 
+#endif	/* ARM_HARD_FLOAT */
+
 __END_DECLS
 
 #endif	/* !_FENV_H_ */
diff -r b112b8e55492 -r 484dfe564ae6 head/lib/msun/src/fenv-softfloat.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/lib/msun/src/fenv-softfloat.h	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,184 @@
+/*-
+ * Copyright (c) 2004-2011 David Schultz <das at FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: head/lib/msun/src/fenv-softfloat.h 230192 2012-01-16 04:09:17Z das $
+ */
+
+#ifndef	_FENV_H_
+#error "This file is meant to be included only by <fenv.h>."
+#endif
+
+/*
+ * This file implements the functionality of <fenv.h> on platforms that
+ * lack an FPU and use softfloat in libc for floating point.  To use it,
+ * you must write an <fenv.h> that provides the following:
+ *
+ *   - a typedef for fenv_t, which may be an integer or struct type
+ *   - a typedef for fexcept_t (XXX This file assumes fexcept_t is a
+ *     simple integer type containing the exception mask.)
+ *   - definitions of FE_* constants for the five exceptions and four
+ *     rounding modes in IEEE 754, as described in fenv(3)
+ *   - a definition, and the corresponding external symbol, for FE_DFL_ENV
+ *   - a macro __set_env(env, flags, mask, rnd), which sets the given fenv_t
+ *     from the exception flags, mask, and rounding mode
+ *   - macros __env_flags(env), __env_mask(env), and __env_round(env), which
+ *     extract fields from an fenv_t
+ *   - a definition of __fenv_static
+ *
+ * If the architecture supports an optional FPU, it's recommended that you
+ * define fenv_t and fexcept_t to match the hardware ABI.  Otherwise, it
+ * doesn't matter how you define them.
+ */
+
+extern int __softfloat_float_exception_flags;
+extern int __softfloat_float_exception_mask;
+extern int __softfloat_float_rounding_mode;
+void __softfloat_float_raise(int);
+
+__fenv_static inline int
+feclearexcept(int __excepts)
+{
+
+	__softfloat_float_exception_flags &= ~__excepts;
+	return (0);
+}
+
+__fenv_static inline int
+fegetexceptflag(fexcept_t *__flagp, int __excepts)
+{
+
+	*__flagp = __softfloat_float_exception_flags & __excepts;
+	return (0);
+}
+
+__fenv_static inline int
+fesetexceptflag(const fexcept_t *__flagp, int __excepts)
+{
+
+	__softfloat_float_exception_flags &= ~__excepts;
+	__softfloat_float_exception_flags |= *__flagp & __excepts;
+	return (0);
+}
+
+__fenv_static inline int
+feraiseexcept(int __excepts)
+{
+
+	__softfloat_float_raise(__excepts);
+	return (0);
+}
+
+__fenv_static inline int
+fetestexcept(int __excepts)
+{
+
+	return (__softfloat_float_exception_flags & __excepts);
+}
+
+__fenv_static inline int
+fegetround(void)
+{
+
+	return (__softfloat_float_rounding_mode);
+}
+
+__fenv_static inline int
+fesetround(int __round)
+{
+
+	__softfloat_float_rounding_mode = __round;
+	return (0);
+}
+
+__fenv_static inline int
+fegetenv(fenv_t *__envp)
+{
+
+	__set_env(*__envp, __softfloat_float_exception_flags,
+	    __softfloat_float_exception_mask, __softfloat_float_rounding_mode);
+	return (0);
+}
+
+__fenv_static inline int
+feholdexcept(fenv_t *__envp)
+{
+	fenv_t __env;
+
+	fegetenv(__envp);
+	__softfloat_float_exception_flags = 0;
+	__softfloat_float_exception_mask = 0;
+	return (0);
+}
+
+__fenv_static inline int
+fesetenv(const fenv_t *__envp)
+{
+
+	__softfloat_float_exception_flags = __env_flags(*__envp);
+	__softfloat_float_exception_mask = __env_mask(*__envp);
+	__softfloat_float_rounding_mode = __env_round(*__envp);
+	return (0);
+}
+
+__fenv_static inline int
+feupdateenv(const fenv_t *__envp)
+{
+	int __oflags = __softfloat_float_exception_flags;
+
+	fesetenv(__envp);
+	feraiseexcept(__oflags);
+	return (0);
+}
+
+#if __BSD_VISIBLE
+
+/* We currently provide no external definitions of the functions below. */
+
+static inline int
+feenableexcept(int __mask)
+{
+	int __omask = __softfloat_float_exception_mask;
+
+	__softfloat_float_exception_mask |= __mask;
+	return (__omask);
+}
+
+static inline int
+fedisableexcept(int __mask)
+{
+	int __omask = __softfloat_float_exception_mask;
+
+	__softfloat_float_exception_mask &= ~__mask;
+	return (__omask);
+}
+
+static inline int
+fegetexcept(void)
+{
+
+	return (__softfloat_float_exception_mask);
+}
+
+#endif /* __BSD_VISIBLE */
diff -r b112b8e55492 -r 484dfe564ae6 head/release/Makefile
--- a/head/release/Makefile	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/release/Makefile	Mon Jan 16 14:38:30 2012 +0200
@@ -1,4 +1,4 @@
-# $FreeBSD: head/release/Makefile 224978 2011-08-18 16:54:04Z sbruno $
+# $FreeBSD: head/release/Makefile 230127 2012-01-15 08:36:25Z glebius $
 #
 # Makefile for building releases and release media.
 # 
@@ -75,7 +75,7 @@
 kernel.txz:
 	-mkdir ${DISTDIR}
 	cd ${WORLDDIR} && ${IMAKE} distributekernel packagekernel DISTDIR=${DISTDIR}
-	mv ${DISTDIR}/kernel.txz ${.OBJDIR}
+	mv ${DISTDIR}/kernel*.txz ${.OBJDIR}
 
 src.txz:
 	-mkdir -p ${DISTDIR}/usr
diff -r b112b8e55492 -r 484dfe564ae6 head/release/generate-release.sh
--- a/head/release/generate-release.sh	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/release/generate-release.sh	Mon Jan 16 14:38:30 2012 +0200
@@ -3,7 +3,7 @@
 # generate-release.sh: check out source trees, and build release components with
 #  totally clean, fresh trees.
 #
-#  Usage: generate-release.sh svn-branch scratch-dir
+#  Usage: generate-release.sh [-r revision] svn-branch scratch-dir
 #
 # Environment variables:
 #  CVSUP_HOST: Host of a cvsup server to obtain the ports and documentation
@@ -18,13 +18,45 @@
 # 
 #  Note: Since this requires a chroot, release cross-builds will not work!
 #
-# $FreeBSD: head/release/generate-release.sh 227536 2011-11-15 18:49:27Z nwhitehorn $
+# $FreeBSD: head/release/generate-release.sh 230128 2012-01-15 09:27:00Z glebius $
 #
 
-mkdir -p $2/usr/src
+usage()
+{
+	echo "Usage: $0 [-r revision] svn-branch scratch-dir"
+	exit 1
+}
+
+REVISION=
+while getopts r: opt; do
+	case $opt in
+	r)
+		REVISION="-r $OPTARG"
+		;;
+	\?)
+		usage
+		;;
+	esac
+done
+shift $(($OPTIND - 1))
+
+if [ $# -lt 2 ]; then
+	usage
+fi
+
 set -e # Everything must succeed
 
-svn co ${SVNROOT:-svn://svn.freebsd.org/base}/$1 $2/usr/src
+case $MAKE_FLAGS in
+	*-j*)
+		;;
+	*)
+		MAKE_FLAGS="$MAKE_FLAGS -j "$(sysctl -n hw.ncpu)
+		;;
+esac
+
+mkdir -p $2/usr/src
+
+svn co ${SVNROOT:-svn://svn.freebsd.org/base}/$1 $2/usr/src $REVISION
 if [ ! -z $CVSUP_HOST ]; then
 	cat > $2/docports-supfile << EOF
 	*default host=$CVSUP_HOST
diff -r b112b8e55492 -r 484dfe564ae6 head/sbin/geom/class/part/gpart.8
--- a/head/sbin/geom/class/part/gpart.8	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sbin/geom/class/part/gpart.8	Mon Jan 16 14:38:30 2012 +0200
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/sbin/geom/class/part/gpart.8 229847 2012-01-09 05:51:33Z wblock $
+.\" $FreeBSD: head/sbin/geom/class/part/gpart.8 230059 2012-01-13 12:40:33Z des $
 .\"
 .Dd January 8, 2012
 .Dt GPART 8
@@ -960,17 +960,21 @@
 from a
 .Cm freebsd-ufs
 partition, and install bootstrap code into it.
-This partition must be larger than
-.Pa /boot/gptboot ,
-or the GPT boot you are planning to write, but smaller than 545 KB.
-A size of 15 blocks (7680 bytes) would be sufficient for
-booting from UFS but 128 blocks (64 KB) is used in
-this example to reserve some space for potential
-future need (e.g.\& a larger
+This partition must be larger than the bootstrap code
+.Po
+usually either
+.Pa /boot/gptboot
+or
 .Pa /boot/gptzfsboot
-for booting from a ZFS partition).
+.Pc ,
+but smaller than 545 kB since the first-stage loader will load the
+entire partition into memory during boot, regardless of how much data
+it actually contains.
+This example uses 94 blocks (47 kB) so the next partition will be
+aligned on a 64 kB boundary without the need to specify an explicit
+offset or alignment.
 .Bd -literal -offset indent
-/sbin/gpart add -b 34 -s 128 -t freebsd-boot ad0
+/sbin/gpart add -b 34 -s 94 -t freebsd-boot ad0
 /sbin/gpart bootcode -p /boot/gptboot -i 1 ad0
 .Ed
 .Pp
@@ -978,7 +982,7 @@
 .Cm freebsd-ufs
 partition to contain a UFS filesystem from which the system can boot.
 .Bd -literal -offset indent
-/sbin/gpart add -b 162 -s 1048576 -t freebsd-ufs ad0
+/sbin/gpart add -s 512M -t freebsd-ufs ad0
 .Ed
 .Pp
 Create an MBR scheme on
diff -r b112b8e55492 -r 484dfe564ae6 head/sbin/hastd/secondary.c
--- a/head/sbin/hastd/secondary.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sbin/hastd/secondary.c	Mon Jan 16 14:38:30 2012 +0200
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sbin/hastd/secondary.c 229945 2012-01-10 22:39:07Z pjd $");
+__FBSDID("$FreeBSD: head/sbin/hastd/secondary.c 230092 2012-01-13 23:25:35Z pjd $");
 
 #include <sys/param.h>
 #include <sys/time.h>
@@ -282,8 +282,10 @@
 		    (uintmax_t)resuid, (uintmax_t)res->hr_resuid);
 		pjdlog_error("%s", errmsg);
 		nv_add_string(nvout, errmsg, "errmsg");
-		if (hast_proto_send(res, res->hr_remotein, nvout, NULL, 0) == -1) {
-			pjdlog_exit(EX_TEMPFAIL, "Unable to send response to %s",
+		if (hast_proto_send(res, res->hr_remotein, nvout,
+		    NULL, 0) == -1) {
+			pjdlog_exit(EX_TEMPFAIL,
+			    "Unable to send response to %s",
 			    res->hr_remoteaddr);
 		}
 		nv_free(nvout);
@@ -327,8 +329,10 @@
 		free(map);
 		pjdlog_error("Split-brain detected, exiting.");
 		nv_add_string(nvout, "Split-brain condition!", "errmsg");
-		if (hast_proto_send(res, res->hr_remotein, nvout, NULL, 0) == -1) {
-			pjdlog_exit(EX_TEMPFAIL, "Unable to send response to %s",
+		if (hast_proto_send(res, res->hr_remotein, nvout,
+		    NULL, 0) == -1) {
+			pjdlog_exit(EX_TEMPFAIL,
+			    "Unable to send response to %s",
 			    res->hr_remoteaddr);
 		}
 		nv_free(nvout);
@@ -475,7 +479,8 @@
 }
 
 static void
-reqlog(int loglevel, int debuglevel, int error, struct hio *hio, const char *fmt, ...)
+reqlog(int loglevel, int debuglevel, int error, struct hio *hio,
+    const char *fmt, ...)
 {
 	char msg[1024];
 	va_list ap;
@@ -838,7 +843,7 @@
 			nv_add_int16(nvout, hio->hio_error, "error");
 		if (hast_proto_send(res, res->hr_remoteout, nvout, data,
 		    length) == -1) {
-			secondary_exit(EX_TEMPFAIL, "Unable to send reply.");
+			secondary_exit(EX_TEMPFAIL, "Unable to send reply");
 		}
 		nv_free(nvout);
 		pjdlog_debug(2, "send: (%p) Moving request to the free queue.",
diff -r b112b8e55492 -r 484dfe564ae6 head/sbin/routed/parms.c
--- a/head/sbin/routed/parms.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sbin/routed/parms.c	Mon Jan 16 14:38:30 2012 +0200
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sbin/routed/parms.c 230045 2012-01-13 06:56:59Z kevlo $
  */
 
 #include "defs.h"
@@ -36,7 +36,7 @@
 #ifdef __NetBSD__
 __RCSID("$NetBSD$");
 #elif defined(__FreeBSD__)
-__RCSID("$FreeBSD$");
+__RCSID("$FreeBSD: head/sbin/routed/parms.c 230045 2012-01-13 06:56:59Z kevlo $");
 #else
 __RCSID("$Revision: 2.26 $");
 #ident "$Revision: 2.26 $"
@@ -188,7 +188,7 @@
 	}
 
 	for (lnum = 1; ; lnum++) {
-		if (0 == fgets(lbuf, sizeof(lbuf), fp))
+		if (fgets(lbuf, sizeof(lbuf), fp) == NULL)
 			break;
 		lptr = lbuf;
 		while (*lptr == ' ')
diff -r b112b8e55492 -r 484dfe564ae6 head/share/man/man4/snd_hda.4
--- a/head/share/man/man4/snd_hda.4	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/share/man/man4/snd_hda.4	Mon Jan 16 14:38:30 2012 +0200
@@ -23,9 +23,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/share/man/man4/snd_hda.4 223160 2011-06-16 19:57:07Z bcr $
+.\" $FreeBSD: head/share/man/man4/snd_hda.4 230130 2012-01-15 13:21:36Z mav $
 .\"
-.Dd January 22, 2010
+.Dd January 11, 2012
 .Dt SND_HDA 4
 .Os
 .Sh NAME
@@ -53,8 +53,9 @@
 .Pp
 The
 .Nm
-driver is a HDA bus controller driver and HDA codecs audio functions bridge
-driver that allows the generic audio driver,
+driver includes HDA bus controller driver (hdac), HDA codec driver (hdacc)
+and HDA codecs audio functions bridge driver (hdaa) that allows
+the generic audio driver,
 .Xr sound 4 ,
 to be used with this hardware.
 Only audio functions are supported by
@@ -77,7 +78,9 @@
 for independent headset connectors at front and one device for SPDIF or
 HDMI audio input/output.
 The assignment of audio inputs and outputs may be tuned with
-.Xr device.hints 5 .
+.Xr device.hints 5
+or
+.Xr sysctl 8 .
 The driver's verbose boot messages provide a lot of information about
 the operation of the driver and present audio setup.
 .Pp
@@ -92,19 +95,26 @@
 file:
 .Bl -tag -width ".Va hint.hdac.%d.config"-offset indent
 .It Va hint.hdac.%d.config
-Configures a range of possible options.
+Configures a range of possible controller options.
 Possible values are:
+.Dq Li 64bit ,
 .Dq Li dmapos ,
+.Dq Li msi .
+An option prefixed with
+.Dq Li no ,
+such as
+.Dq Li nomsi ,
+will do the opposite and takes precedence.
+Options can be separated by whitespace and commas.
+.It Va hint.hdac.%d.msi
+Controls MSI (Message Signaled Interrupts) support.
+.It Va hint.hdac.%d.cad%d.nid%d.config
+Same as
+.Va hint.hdaa.%d.nid%d.config
+.It Va hint.hdaa.%d.config
+Configures a range of possible audio function options.
+Possible values are:
 .Dq Li eapdinv ,
-.Dq Li gpio0 ,
-.Dq Li gpio1 ,
-.Dq Li gpio2 ,
-.Dq Li gpio3 ,
-.Dq Li gpio4 ,
-.Dq Li gpio5 ,
-.Dq Li gpio6 ,
-.Dq Li gpio7 ,
-.Dq Li gpioflush ,
 .Dq Li ivref ,
 .Dq Li ivref50 ,
 .Dq Li ivref80 ,
@@ -126,22 +136,47 @@
 will do the opposite and takes precedence.
 Options can be separated by whitespace and commas.
 .Pp
+The
+.Dq Li eapdinv
+option inverts External Amplifier Power Down signal.
+The
+.Dq Li fixedrate
+denies all sampling rates except 48KHz.
+The
+.Dq Li forcestereo
+denies mono playback/recording.
+The
+.Dq Li senseinv
+option inverts jack sensing logic.
+The
+.Dq Li ivref Ns Ar X
+and
+.Dq Li ovref Ns Ar X
+options control the voltage used to power external microphones.
+.It Va hint.hdaa.%d.gpio_config
+Overrides audio function GPIO pins configuration set by BIOS.
+May be specified as a set of space-separated
+.Dq Ar num Ns = Ns Ar value
+pairs, where
+.Ar num
+is GPIO line number, and
+.Ar value
+is one of:
+.Dq Li keep ,
+.Dq Li set ,
+.Dq Li clear ,
+.Dq Li disable
+and
+.Dq Li input .
+.Pp
 .Dq Li GPIO Ns s
 are a codec's General Purpose I/O pins which system integrators sometimes
 use to control external muters, amplifiers and so on.
 If you have no sound, or sound volume is not adequate, you may have to
 experiment a bit with the GPIO setup to find the optimal setup for your
 system.
-.Pp
-The
-.Dq Li ivref Ns Ar X
-and
-.Dq Li ovref Ns Ar X
-options control the voltage used to power external microphones.
-.It Va hint.hdac.%d.msi
-Controls MSI (Message Signaled Interrupts) support.
-.It Va hint.hdac.%d.cad%d.nid%d.config
-Overrides codec pin configuration set by BIOS.
+.It Va hint.hdaa.%d.nid%d.config
+Overrides audio function pin configuration set by BIOS.
 May be specified as a 32-bit hexadecimal value with a leading
 .Dq 0x ,
 or as a set of space-separated
@@ -165,7 +200,7 @@
 Association number.
 Associations are used to group individual pins to form a complex multi-pin
 device.
-For example, to group 4 connectors for 7.1 output, or to treat several
+For example, to group 4 connectors for 7.1 input/output, or to treat several
 input connectors as sources for the same input device.
 Association numbers can be specified as numeric values from 0 to 15.
 A value of 0 means disabled pin.
@@ -180,16 +215,22 @@
 particular association.
 Sequence numbers can be specified as numeric values from 0 to 15.
 .Pp
-For output assotiations sequence numbers encode speaker pairs positions:
-0 - Front, 1 - Center/LFE, 2 - Back, 3 - Front Wide Center, 4 - Side.
-Standard combinations are: (0) - Stereo; (0, 2), (0, 4) - Quadro;
-(0, 1, 2), (0, 1, 4) - 5.1; (0, 1, 2, 4) - 7.1.
-.Pp
 The sequence number 15 has a special meaning for output associations.
 Output pins with this number and device type
 .Dq Ar Headphones
 will duplicate (with automatic mute if jack detection is supported) the
 first pin in that association.
+.Pp
+The sequence numbers 14 and 15 has a special meaning for input associations.
+Their presence in association defines it as multiplexed or mixed respectively.
+If none of them present and there are more then one pin in association,
+the association will provide multichannel input.
+.Pp
+For multichannel input/output assotiations sequence numbers encode
+channel pairs positions:
+0 - Front, 1 - Center/LFE, 2 - Back, 3 - Front Wide Center, 4 - Side.
+Standard combinations are: (0) - Stereo; (0, 2), (0, 4) - Quadro;
+(0, 1, 2), (0, 1, 4) - 5.1; (0, 1, 2, 4) - 7.1.
 .It Va device
 Device type.
 Can be specified as a number from 0 to 15 or as a name:
@@ -278,7 +319,11 @@
 variables are available in addition to those available to all
 .Xr sound 4
 devices:
-.Bl -tag -width ".Va dev.hdac.%d.polling" -offset indent
+.Bl -tag -width ".Va dev.hdaa.%d.nid%d_original" -offset indent
+.It Va dev.hdac.%d.pindump
+Setting this to a non-zero value dumps the current pin configuration, main
+capabilities and jack sense status of all audio functions on the controller
+to console and syslog.
 .It Va dev.hdac.%d.polling
 Enables polling mode.
 In this mode the driver operates by querying the device state on timer
@@ -288,11 +333,30 @@
 Polling is disabled by default.
 Do not enable it unless you are facing weird interrupt problems or if the
 device cannot generate interrupts at all.
-.It Va dev.hdac.%d.polling_interval
-Controller/Jack Sense polling interval (1-1000 ms)
-.It Va dev.hdac.%d.pindump
-Setting this to a non-zero value dumps the current pin configuration, main
-capabilities and jack sense status to console and syslog.
+.It Va dev.hdaa.%d.config
+Run-time equivalent of the
+.Va hint.hdaa.%d.config
+tunable.
+.It Va dev.hdaa.%d.gpi_state
+Current state of GPI lines.
+.It Va dev.hdaa.%d.gpio_state
+Current state of GPIO lines.
+.It Va dev.hdaa.%d.gpio_config
+Run-time equivalent of the
+.Va hint.hdaa.%d.gpio.config
+tunable.
+.It Va dev.hdaa.%d.gpo_state
+Current state of GPO lines.
+.It Va dev.hdaa.%d.nid%d_config
+Run-time equivalent of the
+.Va hint.hdaa.%d.nid%d.config
+tunable.
+.It Va dev.hdaa.%d.nid%d_original
+Original pin configuration written by BIOS.
+.It Va dev.hdaa.%d.reconfig
+Setting this to a non-zero value makes driver to destroy existing pcm devices
+and process new pins configuration set via
+.Va dev.hdaa.%d.nid%d_config.
 .El
 .Sh EXAMPLES
 Taking HP Compaq DX2300 with Realtek ALC888 HDA codec for example.
@@ -307,22 +371,23 @@
 different ways, depending on requested pins usage described by pins configuration.
 The driver reports such default pin configuration when verbose messages enabled:
 .Bd -literal
-hdac0: nid 20 0x01014020 as  2 seq  0   Line-out  Jack jack 1 loc  1 color   Green misc 0
-hdac0: nid 21 0x99130110 as  1 seq  0    Speaker Fixed jack 3 loc 25 color Unknown misc 1
-hdac0: nid 22 0x411111f0 as 15 seq  0    Speaker  None jack 1 loc  1 color   Black misc 1
-hdac0: nid 23 0x411111f0 as 15 seq  0    Speaker  None jack 1 loc  1 color   Black misc 1
-hdac0: nid 24 0x01a19830 as  3 seq  0        Mic  Jack jack 1 loc  1 color    Pink misc 8
-hdac0: nid 25 0x02a1983f as  3 seq 15        Mic  Jack jack 1 loc  2 color    Pink misc 8
-hdac0: nid 26 0x01813031 as  3 seq  1    Line-in  Jack jack 1 loc  1 color    Blue misc 0
-hdac0: nid 27 0x0221401f as  1 seq 15 Headphones  Jack jack 1 loc  2 color   Green misc 0
-hdac0: nid 28 0x411111f0 as 15 seq  0    Speaker  None jack 1 loc  1 color   Black misc 1
-hdac0: nid 30 0x411111f0 as 15 seq  0    Speaker  None jack 1 loc  1 color   Black misc 1
-hdac0: nid 31 0x411111f0 as 15 seq  0    Speaker  None jack 1 loc  1 color   Black misc 1
+hdaa0: nid   0x    as seq device       conn  jack    loc        color   misc
+hdaa0: 20 01014020 2  0  Line-out      Jack  1/8     Rear       Green   0
+hdaa0: 21 99130110 1  0  Speaker       Fixed ATAPI   Onboard    Unknown 1
+hdaa0: 22 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
+hdaa0: 23 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
+hdaa0: 24 01a19830 3  0  Mic           Jack  1/8     Rear       Pink    8
+hdaa0: 25 02a1983f 3  15 Mic           Jack  1/8     Front      Pink    8
+hdaa0: 26 01813031 3  1  Line-in       Jack  1/8     Rear       Blue    0
+hdaa0: 27 0221401f 1  15 Headphones    Jack  1/8     Front      Green   0
+hdaa0: 28 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
+hdaa0: 30 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
+hdaa0: 31 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
 .Ed
 .Pp
 Here we can see, that the nodes with ID (nid) 25 and 27 are front panel
-connectors (Jack, loc 2), nids 20, 24 and 26 are rear panel connectors
-(Jack, loc 1) and nid 21 is a built-in speaker (Fixed, loc 25).
+connectors (Jack, Front), nids 20, 24 and 26 are rear panel connectors
+(Jack, Rear) and nid 21 is a built-in speaker (Fixed, Onboard).
 Pins with nids 22, 23, 28, 30 and 31 will be disabled by driver due to "None"
 connectivity. So the pin count and description matches to connectors that
 we have.
@@ -330,15 +395,15 @@
 Using association (as) and sequence (seq) fields values pins are grouped into
 3 associations:
 .Bd -literal
-hdac0: Association 0 (1) out:
-hdac0:   Pin nid=21 seq=0
-hdac0:   Pin nid=27 seq=15
-hdac0: Association 1 (2) out:
-hdac0:   Pin nid=20 seq=0
-hdac0: Association 2 (3) in:
-hdac0:   Pin nid=24 seq=0
-hdac0:   Pin nid=26 seq=1
-hdac0:   Pin nid=25 seq=15
+hdaa0: Association 0 (1) out:
+hdaa0:   Pin nid=21 seq=0
+hdaa0:   Pin nid=27 seq=15
+hdaa0: Association 1 (2) out:
+hdaa0:   Pin nid=20 seq=0
+hdaa0: Association 2 (3) in:
+hdaa0:   Pin nid=24 seq=0
+hdaa0:   Pin nid=26 seq=1
+hdaa0:   Pin nid=25 seq=15
 .Ed
 .Pp
 Each
@@ -497,148 +562,14 @@
 .Sh HARDWARE
 The
 .Nm
-driver supports many Intel HDA compatible audio chipsets including the
-following:
+driver supports controllers having PCI class 4 (multimedia) and
+subclass 3 (HDA), compatible with Intel HDA specification.
 .Pp
-.Bl -bullet -compact
-.It
-ATI SB450
-.It
-ATI SB600
-.It
-Intel 631x/632xESB
-.It
-Intel 82801F (ICH6)
-.It
-Intel 82801G (ICH7)
-.It
-Intel 82801H (ICH8)
-.It
-Intel 82801I (ICH9)
-.It
-Intel 82801J (ICH10)
-.It
-Intel US15W (SCH)
-.It
-nVidia MCP51
-.It
-nVidia MCP55
-.It
-nVidia MCP61A
-.It
-nVidia MCP61B
-.It
-nVidia MCP63
-.It
-nVidia MCP65A
-.It
-nVidia MCP65B
-.It
-nVidia MCP67A
-.It
-nVidia MCP67B
-.It
-nVidia MCP68
-.It
-nVidia MCP69
-.It
-nVidia MCP73
-.It
-nVidia MCP78
-.It
-nVidia MCP79
-.It
-nVidia MCP89
-.It
-SiS 966
-.It
-VIA VT8251/8237A
-.El
-.Pp
-The following and many other codecs have been verified to work:
-.Pp
-.Bl -bullet -compact
-.It
-Analog Devices AD1981HD
-.It
-Analog Devices AD1983
-.It
-Analog Devices AD1984
-.It
-Analog Devices AD1986A
-.It
-Analog Devices AD1988
-.It
-Analog Devices AD1988B
-.It
-CMedia CMI9880
-.It
-Conexant CX20549 (Venice)
-.It
-Conexant CX20551 (Waikiki)
-.It
-Conexant CX20561 (Hermosa)
-.It
-Realtek ALC260
-.It
-Realtek ALC262
-.It
-Realtek ALC268
-.It
-Realtek ALC660
-.It
-Realtek ALC861
-.It
-Realtek ALC861VD
-.It
-Realtek ALC880
-.It
-Realtek ALC882
-.It
-Realtek ALC883
-.It
-Realtek ALC885
-.It
-Realtek ALC888
-.It
-Realtek ALC889
-.It
-Sigmatel STAC9205
-.It
-Sigmatel STAC9220
-.It
-Sigmatel STAC9220D / 9223D
-.It
-Sigmatel STAC9221
-.It
-Sigmatel STAC9221D
-.It
-Sigmatel STAC9227D
-.It
-Sigmatel STAC9227X
-.It
-Sigmatel STAC9228D
-.It
-Sigmatel STAC9228X
-.It
-Sigmatel STAC9229D
-.It
-Sigmatel STAC9229X
-.It
-Sigmatel STAC9230D
-.It
-Sigmatel STAC9230X
-.It
-Sigmatel STAC9271D
-.It
-Sigmatel STAC9872AK
-.It
-VIA VT1708
-.It
-VIA VT1708B
-.It
-VIA VT1709
-.El
+The
+.Nm
+driver supports more then two hundred different controllers and CODECs.
+There is no sense to list all of them here, as in most cases specific CODEC
+configuration and wiring are more important then type of the CODEC itself.
 .Sh SEE ALSO
 .Xr sound 4 ,
 .Xr snd_ich 4 ,
@@ -665,19 +596,17 @@
 and
 .An Giorgos Keramidas Aq keramida at FreeBSD.org .
 .Sh BUGS
-A few Hardware/OEM vendors tend to screw up BIOS settings, thus
-rendering the
-.Nm
-driver useless.
-This usually results in a state where the
+Some Hardware/OEM vendors tend to screw up BIOS settings or use custom
+unusual CODEC wiring that create problems to the driver.
+This may result in missing pcm devices, or a state where the
 .Nm
 driver seems to attach and work, but no sound is played.
 Some cases can be solved by tuning
 .Pa loader.conf
 variables.
-Before trying to fix problem that way, make sure that there really is a problem
-and that the PCM audio device in use really corresponds to the expected
-audio connector.
+But before trying to fix problem that way, make sure that there really is
+a problem and that the PCM audio device in use really corresponds to the
+expected audio connector.
 .Pp
 Some vendors use non-standardized General Purpose I/O (GPIO) pins of the codec
 to control external amplifiers.
diff -r b112b8e55492 -r 484dfe564ae6 head/share/man/man5/src.conf.5
--- a/head/share/man/man5/src.conf.5	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/share/man/man5/src.conf.5	Mon Jan 16 14:38:30 2012 +0200
@@ -1,7 +1,7 @@
 .\" DO NOT EDIT-- this file is automatically generated.
 .\" from FreeBSD: head/tools/build/options/makeman 221733 2011-05-10 13:01:11Z ru
-.\" $FreeBSD: head/share/man/man5/src.conf.5 229319 2012-01-02 21:57:58Z rwatson $
-.Dd December 30, 2011
+.\" $FreeBSD: head/share/man/man5/src.conf.5 230061 2012-01-13 15:43:01Z ed $
+.Dd January 13, 2012
 .Dt SRC.CONF 5
 .Os
 .Sh NAME
@@ -252,7 +252,7 @@
 Set to not build
 .Xr calendar 1 .
 .It Va WITHOUT_CAPSICUM
-.\" $FreeBSD: head/share/man/man5/src.conf.5 229319 2012-01-02 21:57:58Z rwatson $
+.\" from FreeBSD: head/tools/build/options/WITHOUT_CAPSICUM 229319 2012-01-02 21:57:58Z rwatson
 Set to not build Capsicum support into system programs.
 .It Va WITHOUT_CDDL
 .\" from FreeBSD: head/tools/build/options/WITHOUT_CDDL 163861 2006-11-01 09:02:11Z jb
@@ -930,12 +930,11 @@
 .\" from FreeBSD: head/tools/build/options/WITHOUT_USB 156932 2006-03-21 07:50:50Z ru
 Set to not build USB-related programs and libraries.
 .It Va WITHOUT_UTMPX
-.\" from FreeBSD: head/tools/build/options/WITHOUT_UTMPX 223209 2011-06-17 21:30:21Z ed
+.\" from FreeBSD: head/tools/build/options/WITHOUT_UTMPX 230060 2012-01-13 15:40:49Z ed
 Set to not build user accounting tools such as
 .Xr last 1 ,
 .Xr users 1 ,
 .Xr who 1 ,
-.Xr wtmpcvt 1 ,
 .Xr ac 8 ,
 .Xr lastlogin 8
 and
diff -r b112b8e55492 -r 484dfe564ae6 head/share/man/man7/release.7
--- a/head/share/man/man7/release.7	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/share/man/man7/release.7	Mon Jan 16 14:38:30 2012 +0200
@@ -22,9 +22,9 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/share/man/man7/release.7 227536 2011-11-15 18:49:27Z nwhitehorn $
+.\" $FreeBSD: head/share/man/man7/release.7 230110 2012-01-14 18:16:10Z glebius $
 .\"
-.Dd March 18, 2011
+.Dd January 14, 2012
 .Dt RELEASE 7
 .Os
 .Sh NAME
@@ -316,9 +316,7 @@
 .Dq "-CURRENT snapshot"
 in a clean environment, including ports and documentation:
 .Bd -literal -offset indent
-cd /usr/src
-make buildworld
-cd release
+cd /usr/src/release
 export CVSUP_HOST=cvsupN.freebsd.org
 sh generate-release.sh head /local3/release
 .Ed
diff -r b112b8e55492 -r 484dfe564ae6 head/share/man/man8/rc.8
--- a/head/share/man/man8/rc.8	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/share/man/man8/rc.8	Mon Jan 16 14:38:30 2012 +0200
@@ -33,9 +33,9 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)rc.8	8.2 (Berkeley) 12/11/93
-.\" $FreeBSD$
+.\" $FreeBSD: head/share/man/man8/rc.8 230116 2012-01-14 21:51:44Z dougb $
 .\"
-.Dd November 17, 2009
+.Dd January 14, 2012
 .Dt RC 8
 .Os
 .Sh NAME
@@ -485,7 +485,7 @@
 \&. /etc/rc.subr
 
 name="foo"
-rcvar=`set_rcvar`
+rcvar=foo_enable
 command="/usr/local/bin/foo"
 
 load_rc_config $name
@@ -506,7 +506,7 @@
 \&. /etc/rc.subr
 
 name="foo"
-rcvar=`set_rcvar`
+rcvar=foo_enable
 command="/usr/local/bin/foo"
 extra_commands="nop hello"
 hello_cmd="echo Hello World."
diff -r b112b8e55492 -r 484dfe564ae6 head/share/man/man8/rc.subr.8
--- a/head/share/man/man8/rc.subr.8	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/share/man/man8/rc.subr.8	Mon Jan 16 14:38:30 2012 +0200
@@ -27,9 +27,9 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/share/man/man8/rc.subr.8 230007 2012-01-12 06:48:11Z rea $
+.\" $FreeBSD: head/share/man/man8/rc.subr.8 230116 2012-01-14 21:51:44Z dougb $
 .\"
-.Dd May 18, 2007
+.Dd January 14, 2012
 .Dt RC.SUBR 8
 .Os
 .Sh NAME
@@ -73,8 +73,6 @@
 .It
 .Ic run_rc_script Ar file Ar argument
 .It
-.Ic set_rcvar Op Ar base
-.It
 .Ic wait_for_pids Op Ar pid ...
 .It
 .Ic warn Ar message
@@ -832,32 +830,6 @@
 process, which is assumed to be
 .Xr rc 8 .
 Otherwise, the shell exits with a non-zero status.
-.It Ic set_rcvar Op Ar base
-Set the variable name required to start a service.
-In
-.Fx
-a daemon is usually controlled by an
-.Xr rc.conf 5
-variable consisting of a daemon's name postfixed by the string
-.Dq Li "_enable" .
-This is not the case in
-.Nx .
-When the following line is included in a script:
-.Pp
-.Dl "rcvar=`set_rcvar`"
-.Pp
-this function will use the value of the
-.Va $name
-variable, which should be defined by the calling script,
-to construct the appropriate
-.Xr rc.conf 5
-knob.
-If the
-.Ar base
-argument is set it will use
-.Ar base
-instead of
-.Va $name .
 .It Ic wait_for_pids Op Ar pid ...
 Wait until all of the provided
 .Ar pids
diff -r b112b8e55492 -r 484dfe564ae6 head/share/misc/bsd-family-tree
--- a/head/share/misc/bsd-family-tree	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/share/misc/bsd-family-tree	Mon Jan 16 14:38:30 2012 +0200
@@ -247,11 +247,14 @@
  |  FreeBSD  FreeBSD  |      |                 |                       |
  |    8.2      7.4    |      |                 |               DragonFly 2.10.1
  |     v              |      |             OpenBSD 4.9                 |
+ |                 Mac OS X  |                 |                       |
+ |                   10.7    |                 |                       |
+ |                    |      |             OpenBSD 5.0                 |
+ +--FreeBSD           |      |                 |                       |
+ |    9.0             |      |                 |                       |
+ |     v              |      |                 |                       |
  |                    |      |                 |                       |
- |                    |      |                 |                       |
- |                    |      |             OpenBSD 5.0                 |
- |                    |      |                 |                       |
-FreeBSD 9 -current    |  NetBSD -current  OpenBSD -current             |
+FreeBSD 10 -current   |  NetBSD -current  OpenBSD -current             |
  |                    |      |                 |                       |
  v                    v      v                 v                       v
 
@@ -537,7 +540,9 @@
 FreeBSD 8.2		2011-02-24 [FBD]
 DragonFly 2.10.1	2011-04-26 [DFB]
 OpenBSD 4.9		2011-05-01 [OBD]
+Mac OS X 10.7		2011-07-20 [APL]
 OpenBSD 5.0		2011-11-01 [OBD]
+FreeBSD 9.0		2012-01-12 [FBD]
 
 Bibliography
 ------------------------
@@ -595,7 +600,7 @@
 Steven M. Schultz for providing 2.8BSD, 2.10BSD, 2.11BSD manual pages.
 
 --
-Copyright (c) 1997-2007 Wolfram Schneider <wosch at FreeBSD.ORG>
+Copyright (c) 1997-2012 Wolfram Schneider <wosch at FreeBSD.ORG>
 URL: http://cvsweb.freebsd.org/src/share/misc/bsd-family-tree
 
-$FreeBSD: head/share/misc/bsd-family-tree 227020 2011-11-02 14:28:36Z maxim $
+$FreeBSD: head/share/misc/bsd-family-tree 230043 2012-01-13 06:18:23Z maxim $
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/amd64/linux32/linux.h
--- a/head/sys/amd64/linux32/linux.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/amd64/linux32/linux.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,7 +1,7 @@
 /*-
  * Copyright (c) 2004 Tim J. Robbins
  * Copyright (c) 2001 Doug Rabson
- * Copyright (c) 1994-1996 Søren Schmidt
+ * Copyright (c) 1994-1996 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/amd64/linux32/linux.h 228957 2011-12-29 15:34:59Z jhb $
+ * $FreeBSD: head/sys/amd64/linux32/linux.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #ifndef _AMD64_LINUX_H_
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/amd64/linux32/linux32_dummy.c
--- a/head/sys/amd64/linux32/linux32_dummy.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/amd64/linux32/linux32_dummy.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1994-1995 Søren Schmidt
+ * Copyright (c) 1994-1995 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/amd64/linux32/linux32_dummy.c 228957 2011-12-29 15:34:59Z jhb $");
+__FBSDID("$FreeBSD: head/sys/amd64/linux32/linux32_dummy.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/amd64/linux32/linux32_sysvec.c
--- a/head/sys/amd64/linux32/linux32_sysvec.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/amd64/linux32/linux32_sysvec.c	Mon Jan 16 14:38:30 2012 +0200
@@ -3,7 +3,7 @@
  * Copyright (c) 2003 Peter Wemm
  * Copyright (c) 2002 Doug Rabson
  * Copyright (c) 1998-1999 Andrew Gallatin
- * Copyright (c) 1994-1996 Søren Schmidt
+ * Copyright (c) 1994-1996 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/amd64/linux32/linux32_sysvec.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/amd64/linux32/linux32_sysvec.c 230132 2012-01-15 13:23:18Z uqs $");
 #include "opt_compat.h"
 
 #ifndef COMPAT_FREEBSD32
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/arm/at91/at91_st.c
--- a/head/sys/arm/at91/at91_st.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/arm/at91/at91_st.c	Mon Jan 16 14:38:30 2012 +0200
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/arm/at91/at91_st.c 230133 2012-01-15 13:23:33Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -200,7 +200,7 @@
 		hz = 32768 / rel_value;
 		tick = 1000000 / hz;
 	}
-	/* Disable all interrupts. */
+	/* Disable all interrupts. */
 	WR4(ST_IDR, 0xffffffff);
 	/* The system timer shares the system irq (1) */
 	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 1, 1, 1,
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/arm/include/float.h
--- a/head/sys/arm/include/float.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/arm/include/float.h	Mon Jan 16 14:38:30 2012 +0200
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)float.h	7.1 (Berkeley) 5/8/90
- * $FreeBSD$
+ * $FreeBSD: head/sys/arm/include/float.h 230198 2012-01-16 05:23:13Z das $
  */
 
 #ifndef _MACHINE_FLOAT_H_
@@ -44,9 +44,15 @@
 __END_DECLS
 
 #define FLT_RADIX	2		/* b */
-#define FLT_ROUNDS	-1
-#define	FLT_EVAL_METHOD	(-1)		/* XXX */
+#ifndef	_ARM_HARD_FLOAT
+#define	FLT_ROUNDS	__flt_rounds()
+#else
+#define	FLT_ROUNDS	(-1)
+#endif
+#if __ISO_C_VISIBLE >= 1999
+#define	FLT_EVAL_METHOD	0
 #define	DECIMAL_DIG	17		/* max precision in decimal digits */
+#endif
 
 #define FLT_MANT_DIG	24		/* p */
 #define FLT_EPSILON	1.19209290E-07F	/* b**(1-p) */
@@ -69,12 +75,12 @@
 #define DBL_MAX_10_EXP	308
 
 #define LDBL_MANT_DIG	DBL_MANT_DIG
-#define LDBL_EPSILON	DBL_EPSILON
+#define LDBL_EPSILON	(long double)DBL_EPSILON
 #define LDBL_DIG	DBL_DIG
 #define LDBL_MIN_EXP	DBL_MIN_EXP
-#define LDBL_MIN	DBL_MIN
+#define LDBL_MIN	(long double)DBL_MIN
 #define LDBL_MIN_10_EXP	DBL_MIN_10_EXP
 #define LDBL_MAX_EXP	DBL_MAX_EXP
-#define LDBL_MAX	DBL_MAX
+#define LDBL_MAX	(long double)DBL_MAX
 #define LDBL_MAX_10_EXP	DBL_MAX_10_EXP
 #endif /* _MACHINE_FLOAT_H_ */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/arm/sa11x0/sa11x0_ost.c
--- a/head/sys/arm/sa11x0/sa11x0_ost.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/arm/sa11x0/sa11x0_ost.c	Mon Jan 16 14:38:30 2012 +0200
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/arm/sa11x0/sa11x0_ost.c 230133 2012-01-15 13:23:33Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -251,7 +251,7 @@
 	stathz = STATHZ;
 	profhz = stathz;
 #if 0
-	mtx_init(&clock_lock, "SA1110 Clock locké", NULL, MTX_SPIN);
+	mtx_init(&clock_lock, "SA1110 Clock locked", NULL, MTX_SPIN);
 #endif
 	saost_sc->sc_statclock_step = TIMER_FREQUENCY / stathz;
 	struct resource *irq1, *irq2;
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/boot/forth/loader.conf
--- a/head/sys/boot/forth/loader.conf	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/boot/forth/loader.conf	Mon Jan 16 14:38:30 2012 +0200
@@ -6,7 +6,7 @@
 #
 # All arguments must be in double quotes.
 #
-# $FreeBSD: head/sys/boot/forth/loader.conf 228576 2011-12-16 14:28:34Z glebius $
+# $FreeBSD: head/sys/boot/forth/loader.conf 230109 2012-01-14 17:34:32Z eadler $
 
 ##############################################################
 ###  Basic configuration options  ############################
@@ -31,9 +31,10 @@
 
 splash_bmp_load="NO"		# Set this to YES for bmp splash screen!
 splash_pcx_load="NO"		# Set this to YES for pcx splash screen!
+splash_txt_load="NO"		# Set this to YES for TheDraw splash screen!
 vesa_load="NO"			# Set this to YES to load the vesa module
 bitmap_load="NO"		# Set this to YES if you want splash screen!
-bitmap_name="splash.bmp"	# Set this to the name of the bmp or pcx file
+bitmap_name="splash.bmp"	# Set this to the name of the file
 bitmap_type="splash_image_data" # and place it on the module_path
 
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/boot/powerpc/ps3/ps3mmu.c
--- a/head/sys/boot/powerpc/ps3/ps3mmu.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/boot/powerpc/ps3/ps3mmu.c	Mon Jan 16 14:38:30 2012 +0200
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/boot/powerpc/ps3/ps3mmu.c 230140 2012-01-15 16:58:44Z nwhitehorn $");
 
 #include <stand.h>
 #include <stdint.h>
@@ -113,7 +113,7 @@
 	    "r"(1 << SLBV_VSID_SHIFT),
 	    "r"((1 << SLBE_ESID_SHIFT) | SLBE_VALID | 1));
 
-	mtmsr(mfmsr() | PSL_IR | PSL_DR | PSL_RI | PSL_ME);
+	mtmsr(PSL_IR | PSL_DR | PSL_RI | PSL_ME);
 
 	return (0);
 }
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/cam/ctl/scsi_ctl.c
--- a/head/sys/cam/ctl/scsi_ctl.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/cam/ctl/scsi_ctl.c	Mon Jan 16 14:38:30 2012 +0200
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/ctl/scsi_ctl.c 229997 2012-01-12 00:34:33Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/ctl/scsi_ctl.c 230033 2012-01-12 22:08:33Z ken $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -305,8 +305,10 @@
 
 		/* Don't attach if it doesn't support target mode */
 		if ((cpi->target_sprt & PIT_PROCESSOR) == 0) {
+#ifdef CTLFEDEBUG
 			printf("%s: SIM %s%d doesn't support target mode\n",
 			       __func__, cpi->dev_name, cpi->unit_number);
+#endif
 			break;
 		}
 
@@ -421,8 +423,10 @@
 		 * XXX KDM need to figure out whether we're the master or
 		 * slave.
 		 */
+#ifdef CTLFEDEBUG
 		printf("%s: calling ctl_frontend_register() for %s%d\n",
 		       __func__, cpi->dev_name, cpi->unit_number);
+#endif
 		retval = ctl_frontend_register(fe, /*master_SC*/ 1);
 		if (retval != 0) {
 			printf("%s: ctl_frontend_register() failed with "
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/cam/scsi/scsi_all.c
--- a/head/sys/cam/scsi/scsi_all.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/cam/scsi/scsi_all.c	Mon Jan 16 14:38:30 2012 +0200
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_all.c 229997 2012-01-12 00:34:33Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_all.c 230053 2012-01-13 10:21:17Z mav $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -364,6 +364,8 @@
 	{ 0x40,	D | T | L | P | W | R | O | M | S | C, "CHANGE DEFINITION" },
 	/* 41  O               WRITE SAME(10) */
 	{ 0x41,	D, "WRITE SAME(10)" },
+	/* 42       O          UNMAP */
+	{ 0x42,	D, "UNMAP" },
 	/* 42       O          READ SUB-CHANNEL */
 	{ 0x42,	R, "READ SUB-CHANNEL" },
 	/* 43       O          READ TOC/PMA/ATIP */
@@ -5570,6 +5572,104 @@
 }
 
 void
+scsi_write_same(struct ccb_scsiio *csio, u_int32_t retries,
+		void (*cbfcnp)(struct cam_periph *, union ccb *),
+		u_int8_t tag_action, u_int8_t byte2,
+		int minimum_cmd_size, u_int64_t lba, u_int32_t block_count,
+		u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
+		u_int32_t timeout)
+{
+	u_int8_t cdb_len;
+	if ((minimum_cmd_size < 16) &&
+	    ((block_count & 0xffff) == block_count) &&
+	    ((lba & 0xffffffff) == lba)) {
+		/*
+		 * Need a 10 byte cdb.
+		 */
+		struct scsi_write_same_10 *scsi_cmd;
+
+		scsi_cmd = (struct scsi_write_same_10 *)&csio->cdb_io.cdb_bytes;
+		scsi_cmd->opcode = WRITE_SAME_10;
+		scsi_cmd->byte2 = byte2;
+		scsi_ulto4b(lba, scsi_cmd->addr);
+		scsi_cmd->group = 0;
+		scsi_ulto2b(block_count, scsi_cmd->length);
+		scsi_cmd->control = 0;
+		cdb_len = sizeof(*scsi_cmd);
+
+		CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE,
+			  ("10byte: %x%x%x%x:%x%x: %d\n", scsi_cmd->addr[0],
+			   scsi_cmd->addr[1], scsi_cmd->addr[2],
+			   scsi_cmd->addr[3], scsi_cmd->length[0],
+			   scsi_cmd->length[1], dxfer_len));
+	} else {
+		/*
+		 * 16 byte CDB.  We'll only get here if the LBA is larger
+		 * than 2^32, or if the user asks for a 16 byte command.
+		 */
+		struct scsi_write_same_16 *scsi_cmd;
+
+		scsi_cmd = (struct scsi_write_same_16 *)&csio->cdb_io.cdb_bytes;
+		scsi_cmd->opcode = WRITE_SAME_16;
+		scsi_cmd->byte2 = byte2;
+		scsi_u64to8b(lba, scsi_cmd->addr);
+		scsi_ulto4b(block_count, scsi_cmd->length);
+		scsi_cmd->group = 0;
+		scsi_cmd->control = 0;
+		cdb_len = sizeof(*scsi_cmd);
+
+		CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE,
+			  ("16byte: %x%x%x%x%x%x%x%x:%x%x%x%x: %d\n",
+			   scsi_cmd->addr[0], scsi_cmd->addr[1],
+			   scsi_cmd->addr[2], scsi_cmd->addr[3],
+			   scsi_cmd->addr[4], scsi_cmd->addr[5],
+			   scsi_cmd->addr[6], scsi_cmd->addr[7],
+			   scsi_cmd->length[0], scsi_cmd->length[1],
+			   scsi_cmd->length[2], scsi_cmd->length[3],
+			   dxfer_len));
+	}
+	cam_fill_csio(csio,
+		      retries,
+		      cbfcnp,
+		      /*flags*/CAM_DIR_OUT,
+		      tag_action,
+		      data_ptr,
+		      dxfer_len,
+		      sense_len,
+		      cdb_len,
+		      timeout);
+}
+
+void
+scsi_unmap(struct ccb_scsiio *csio, u_int32_t retries,
+	   void (*cbfcnp)(struct cam_periph *, union ccb *),
+	   u_int8_t tag_action, u_int8_t byte2,
+	   u_int8_t *data_ptr, u_int16_t dxfer_len, u_int8_t sense_len,
+	   u_int32_t timeout)
+{
+	struct scsi_unmap *scsi_cmd;
+
+	scsi_cmd = (struct scsi_unmap *)&csio->cdb_io.cdb_bytes;
+	scsi_cmd->opcode = UNMAP;
+	scsi_cmd->byte2 = byte2;
+	scsi_ulto4b(0, scsi_cmd->reserved);
+	scsi_cmd->group = 0;
+	scsi_ulto2b(dxfer_len, scsi_cmd->length);
+	scsi_cmd->control = 0;
+
+	cam_fill_csio(csio,
+		      retries,
+		      cbfcnp,
+		      /*flags*/CAM_DIR_OUT,
+		      tag_action,
+		      data_ptr,
+		      dxfer_len,
+		      sense_len,
+		      sizeof(*scsi_cmd),
+		      timeout);
+}
+
+void
 scsi_receive_diagnostic_results(struct ccb_scsiio *csio, u_int32_t retries,
 				void (*cbfcnp)(struct cam_periph *, union ccb*),
 				uint8_t tag_action, int pcv, uint8_t page_code,
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/cam/scsi/scsi_all.h
--- a/head/sys/cam/scsi/scsi_all.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/cam/scsi/scsi_all.h	Mon Jan 16 14:38:30 2012 +0200
@@ -14,7 +14,7 @@
  *
  * Ported to run under 386BSD by Julian Elischer (julian at tfs.com) Sept 1992
  *
- * $FreeBSD: head/sys/cam/scsi/scsi_all.h 229997 2012-01-12 00:34:33Z ken $
+ * $FreeBSD: head/sys/cam/scsi/scsi_all.h 230053 2012-01-13 10:21:17Z mav $
  */
 
 /*
@@ -819,6 +819,41 @@
 	u_int8_t control;
 };
 
+struct scsi_write_same_10
+{
+	uint8_t	opcode;
+	uint8_t	byte2;
+#define	SWS_LBDATA	0x02
+#define	SWS_PBDATA	0x04
+#define	SWS_UNMAP	0x08
+#define	SWS_ANCHOR	0x10
+	uint8_t	addr[4];
+	uint8_t	group;
+	uint8_t	length[2];
+	uint8_t	control;
+};
+
+struct scsi_write_same_16
+{
+	uint8_t	opcode;
+	uint8_t	byte2;
+	uint8_t	addr[8];
+	uint8_t	length[4];
+	uint8_t	group;
+	uint8_t	control;
+};
+
+struct scsi_unmap
+{
+	uint8_t	opcode;
+	uint8_t	byte2;
+#define	SU_ANCHOR	0x01
+	uint8_t	reserved[4];
+	uint8_t	group;
+	uint8_t	length[2];
+	uint8_t	control;
+};
+
 struct scsi_write_verify_10
 {
 	uint8_t	opcode;
@@ -957,6 +992,8 @@
 #define	WRITE_BUFFER            0x3B
 #define	READ_BUFFER             0x3C
 #define	CHANGE_DEFINITION	0x40
+#define	WRITE_SAME_10		0x41
+#define	UNMAP			0x42
 #define	LOG_SELECT		0x4C
 #define	LOG_SENSE		0x4D
 #define	MODE_SELECT_10		0x55
@@ -970,6 +1007,7 @@
 #define	WRITE_16		0x8A
 #define	WRITE_VERIFY_16		0x8E
 #define	SYNCHRONIZE_CACHE_16	0x91
+#define	WRITE_SAME_16		0x93
 #define	SERVICE_ACTION_IN	0x9E
 #define	REPORT_LUNS		0xA0
 #define	ATA_PASS_12		0xA1
@@ -2312,6 +2350,20 @@
 		     u_int32_t dxfer_len, u_int8_t sense_len,
 		     u_int32_t timeout);
 
+void scsi_write_same(struct ccb_scsiio *csio, u_int32_t retries,
+		     void (*cbfcnp)(struct cam_periph *, union ccb *),
+		     u_int8_t tag_action, u_int8_t byte2, 
+		     int minimum_cmd_size, u_int64_t lba,
+		     u_int32_t block_count, u_int8_t *data_ptr,
+		     u_int32_t dxfer_len, u_int8_t sense_len,
+		     u_int32_t timeout);
+
+void scsi_unmap(struct ccb_scsiio *csio, u_int32_t retries,
+		void (*cbfcnp)(struct cam_periph *, union ccb *),
+		u_int8_t tag_action, u_int8_t byte2,
+		u_int8_t *data_ptr, u_int16_t dxfer_len,
+		u_int8_t sense_len, u_int32_t timeout);
+
 void scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
 		     void (*cbfcnp)(struct cam_periph *, union ccb *),
 		     u_int8_t tag_action, int start, int load_eject,
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/cam/scsi/scsi_da.c
--- a/head/sys/cam/scsi/scsi_da.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/cam/scsi/scsi_da.c	Mon Jan 16 14:38:30 2012 +0200
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_da.c 230000 2012-01-12 00:41:48Z ken $");
+__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_da.c 230157 2012-01-15 20:43:39Z avg $");
 
 #include <sys/param.h>
 
@@ -83,8 +83,7 @@
 	DA_FLAG_RETRY_UA	= 0x080,
 	DA_FLAG_OPEN		= 0x100,
 	DA_FLAG_SCTX_INIT	= 0x200,
-	DA_FLAG_CAN_RC16	= 0x400,
-	DA_FLAG_CAN_LBPME	= 0x800
+	DA_FLAG_CAN_RC16	= 0x400
 } da_flags;
 
 typedef enum {
@@ -101,10 +100,24 @@
 	DA_CCB_BUFFER_IO	= 0x03,
 	DA_CCB_WAITING		= 0x04,
 	DA_CCB_DUMP		= 0x05,
+	DA_CCB_DELETE		= 0x06,
 	DA_CCB_TYPE_MASK	= 0x0F,
 	DA_CCB_RETRY_UA		= 0x10
 } da_ccb_state;
 
+typedef enum {
+	DA_DELETE_NONE,
+	DA_DELETE_DISABLE,
+	DA_DELETE_ZERO,
+	DA_DELETE_WS10,
+	DA_DELETE_WS16,
+	DA_DELETE_UNMAP,
+	DA_DELETE_MAX = DA_DELETE_UNMAP
+} da_delete_methods;
+
+static const char *da_delete_method_names[] =
+    { "NONE", "DISABLE", "ZERO", "WS10", "WS16", "UNMAP" };
+
 /* Offsets into our private area for storing information */
 #define ccb_state	ppriv_field0
 #define ccb_bp		ppriv_ptr1
@@ -119,8 +132,12 @@
 	u_int     stripeoffset;
 };
 
+#define UNMAP_MAX_RANGES	512
+
 struct da_softc {
 	struct	 bio_queue_head bio_queue;
+	struct	 bio_queue_head delete_queue;
+	struct	 bio_queue_head delete_run_queue;
 	SLIST_ENTRY(da_softc) links;
 	LIST_HEAD(, ccb_hdr) pending_ccbs;
 	da_state state;
@@ -130,6 +147,10 @@
 	int	 error_inject;
 	int	 ordered_tag_count;
 	int	 outstanding_cmds;
+	int	 unmap_max_ranges;
+	int	 unmap_max_lba;
+	int	 delete_running;
+	da_delete_methods	 delete_method;
 	struct	 disk_params params;
 	struct	 disk *disk;
 	union	 ccb saved_ccb;
@@ -138,6 +159,7 @@
 	struct sysctl_oid	*sysctl_tree;
 	struct callout		sendordered_c;
 	uint64_t wwpn;
+	uint8_t	 unmap_buf[UNMAP_MAX_RANGES * 16 + 8];
 };
 
 struct da_quirk_entry {
@@ -796,6 +818,7 @@
 				struct cam_path *path, void *arg);
 static	void		dasysctlinit(void *context, int pending);
 static	int		dacmdsizesysctl(SYSCTL_HANDLER_ARGS);
+static	int		dadeletemethodsysctl(SYSCTL_HANDLER_ARGS);
 static	periph_ctor_t	daregister;
 static	periph_dtor_t	dacleanup;
 static	periph_start_t	dastart;
@@ -916,6 +939,10 @@
 		softc->disk->d_fwheads = softc->params.heads;
 		softc->disk->d_devstat->block_size = softc->params.secsize;
 		softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE;
+		if (softc->delete_method > DA_DELETE_DISABLE)
+			softc->disk->d_flags |= DISKFLAG_CANDELETE;
+		else
+			softc->disk->d_flags &= ~DISKFLAG_CANDELETE;
 
 		if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 &&
 		    (softc->quirks & DA_Q_NO_PREVENT) == 0)
@@ -1013,6 +1040,26 @@
 	return (0);	
 }
 
+static void
+daschedule(struct cam_periph *periph)
+{
+	struct da_softc *softc = (struct da_softc *)periph->softc;
+	uint32_t prio;
+
+	/* Check if cam_periph_getccb() was called. */
+	prio = periph->immediate_priority;
+
+	/* Check if we have more work to do. */
+	if (bioq_first(&softc->bio_queue) ||
+	    (!softc->delete_running && bioq_first(&softc->delete_queue))) {
+		prio = CAM_PRIORITY_NORMAL;
+	}
+
+	/* Schedule CCB if any of above is true. */
+	if (prio != CAM_PRIORITY_NONE)
+		xpt_schedule(periph, prio);
+}
+
 /*
  * Actually translate the requested transfer into one the physical driver
  * can understand.  The transfer is described by a buf and will include
@@ -1045,12 +1092,18 @@
 	/*
 	 * Place it in the queue of disk activities for this disk
 	 */
-	bioq_disksort(&softc->bio_queue, bp);
+	if (bp->bio_cmd == BIO_DELETE) {
+		if (bp->bio_bcount == 0)
+			biodone(bp);
+		else
+			bioq_disksort(&softc->delete_queue, bp);
+	} else
+		bioq_disksort(&softc->bio_queue, bp);
 
 	/*
 	 * Schedule ourselves for performing the work.
 	 */
-	xpt_schedule(periph, CAM_PRIORITY_NORMAL);
+	daschedule(periph);
 	cam_periph_unlock(periph);
 
 	return;
@@ -1095,6 +1148,7 @@
 				/*sense_len*/SSD_FULL_SIZE,
 				DA_DEFAULT_TIMEOUT * 1000);		
 		xpt_polled_action((union ccb *)&csio);
+		cam_periph_unlock(periph);
 
 		if ((csio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 			printf("Aborting dump due to I/O error.\n");
@@ -1106,7 +1160,6 @@
 				       csio.ccb_h.status, csio.scsi_status);
 			return(EIO);
 		}
-		cam_periph_unlock(periph);
 		return(0);
 	}
 		
@@ -1213,6 +1266,7 @@
 	 *     with XPT_ABORT_CCB.
 	 */
 	bioq_flush(&softc->bio_queue, NULL, ENXIO);
+	bioq_flush(&softc->delete_queue, NULL, ENXIO);
 
 	disk_gone(softc->disk);
 	xpt_print(periph->path, "lost device - %d outstanding, %d refs\n",
@@ -1358,6 +1412,10 @@
 	 * the fly.
 	 */
 	SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
+		OID_AUTO, "delete_method", CTLTYPE_STRING | CTLFLAG_RW,
+		&softc->delete_method, 0, dadeletemethodsysctl, "A",
+		"BIO_DELETE execution method");
+	SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 		OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW,
 		&softc->minimum_cmd_size, 0, dacmdsizesysctl, "I",
 		"Minimum CDB size");
@@ -1431,6 +1489,32 @@
 	return (0);
 }
 
+static int
+dadeletemethodsysctl(SYSCTL_HANDLER_ARGS)
+{
+	char buf[16];
+	int error;
+	const char *p;
+	int i, value;
+
+	value = *(int *)arg1;
+	if (value < 0 || value > DA_DELETE_MAX)
+		p = "UNKNOWN";
+	else
+		p = da_delete_method_names[value];
+	strncpy(buf, p, sizeof(buf));
+	error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+	for (i = 0; i <= DA_DELETE_MAX; i++) {
+		if (strcmp(buf, da_delete_method_names[i]) != 0)
+			continue;
+		*(int *)arg1 = i;
+		return (0);
+	}
+	return (EINVAL);
+}
+
 static cam_status
 daregister(struct cam_periph *periph, void *arg)
 {
@@ -1463,10 +1547,14 @@
 	LIST_INIT(&softc->pending_ccbs);
 	softc->state = DA_STATE_PROBE;
 	bioq_init(&softc->bio_queue);
+	bioq_init(&softc->delete_queue);
+	bioq_init(&softc->delete_run_queue);
 	if (SID_IS_REMOVABLE(&cgd->inq_data))
 		softc->flags |= DA_FLAG_PACK_REMOVABLE;
 	if ((cgd->inq_data.flags & SID_CmdQue) != 0)
 		softc->flags |= DA_FLAG_TAGGED_QUEUING;
+	softc->unmap_max_ranges = UNMAP_MAX_RANGES;
+	softc->unmap_max_lba = 1024*1024*2;
 
 	periph->softc = softc;
 
@@ -1621,13 +1709,10 @@
 	switch (softc->state) {
 	case DA_STATE_NORMAL:
 	{
-		/* Pull a buffer from the queue and get going on it */		
-		struct bio *bp;
+		struct bio *bp, *bp1;
+		uint8_t tag_code;
 
-		/*
-		 * See if there is a buf with work for us to do..
-		 */
-		bp = bioq_first(&softc->bio_queue);
+		/* Execute immediate CCB if waiting. */
 		if (periph->immediate_priority <= periph->pinfo.priority) {
 			CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
 					("queuing for immediate ccb\n"));
@@ -1636,84 +1721,186 @@
 					  periph_links.sle);
 			periph->immediate_priority = CAM_PRIORITY_NONE;
 			wakeup(&periph->ccb_list);
-		} else if (bp == NULL) {
+			/* May have more work to do, so ensure we stay scheduled */
+			daschedule(periph);
+			break;
+		}
+
+		/* Run BIO_DELETE if not running yet. */
+		if (!softc->delete_running &&
+		    (bp = bioq_first(&softc->delete_queue)) != NULL) {
+		    uint64_t lba;
+		    u_int count;
+
+		    if (softc->delete_method == DA_DELETE_UNMAP) {
+			uint8_t *buf = softc->unmap_buf;
+			uint64_t lastlba = (uint64_t)-1;
+			uint32_t lastcount = 0;
+			int blocks = 0, off, ranges = 0;
+
+			softc->delete_running = 1;
+			bzero(softc->unmap_buf, sizeof(softc->unmap_buf));
+			bp1 = bp;
+			do {
+				bioq_remove(&softc->delete_queue, bp1);
+				if (bp1 != bp)
+					bioq_insert_tail(&softc->delete_run_queue, bp1);
+				lba = bp1->bio_pblkno;
+				count = bp1->bio_bcount / softc->params.secsize;
+
+				/* Try to extend the previous range. */
+				if (lba == lastlba) {
+					lastcount += count;
+					off = (ranges - 1) * 16 + 8;
+					scsi_ulto4b(lastcount, &buf[off + 8]);
+				} else if (count > 0) {
+					off = ranges * 16 + 8;
+					scsi_u64to8b(lba, &buf[off + 0]);
+					scsi_ulto4b(count, &buf[off + 8]);
+					lastcount = count;
+					ranges++;
+				}
+				blocks += count;
+				lastlba = lba + count;
+				bp1 = bioq_first(&softc->delete_queue);
+				if (bp1 == NULL ||
+				    ranges >= softc->unmap_max_ranges ||
+				    blocks + bp1->bio_bcount /
+				     softc->params.secsize > softc->unmap_max_lba)
+					break;
+			} while (1);
+			scsi_ulto2b(count * 16 + 6, &buf[0]);
+			scsi_ulto2b(count * 16, &buf[2]);
+
+			scsi_unmap(&start_ccb->csio,
+					/*retries*/da_retry_count,
+					/*cbfcnp*/dadone,
+					/*tag_action*/MSG_SIMPLE_Q_TAG,
+					/*byte2*/0,
+					/*data_ptr*/ buf,
+					/*dxfer_len*/ count * 16 + 8,
+					/*sense_len*/SSD_FULL_SIZE,
+					da_default_timeout * 1000);
+			start_ccb->ccb_h.ccb_state = DA_CCB_DELETE;
+			goto out;
+		    } else if (softc->delete_method == DA_DELETE_ZERO ||
+			       softc->delete_method == DA_DELETE_WS10 ||
+			       softc->delete_method == DA_DELETE_WS16) {
+			softc->delete_running = 1;
+			lba = bp->bio_pblkno;
+			count = 0;
+			bp1 = bp;
+			do {
+				bioq_remove(&softc->delete_queue, bp1);
+				if (bp1 != bp)
+					bioq_insert_tail(&softc->delete_run_queue, bp1);
+				count += bp1->bio_bcount / softc->params.secsize;
+				bp1 = bioq_first(&softc->delete_queue);
+				if (bp1 == NULL ||
+				    lba + count != bp1->bio_pblkno ||
+				    count + bp1->bio_bcount /
+				     softc->params.secsize > 0xffff)
+					break;
+			} while (1);
+
+			scsi_write_same(&start_ccb->csio,
+					/*retries*/da_retry_count,
+					/*cbfcnp*/dadone,
+					/*tag_action*/MSG_SIMPLE_Q_TAG,
+					/*byte2*/softc->delete_method ==
+					    DA_DELETE_ZERO ? 0 : SWS_UNMAP,
+					softc->delete_method ==
+					    DA_DELETE_WS16 ? 16 : 10,
+					/*lba*/lba,
+					/*block_count*/count,
+					/*data_ptr*/ __DECONST(void *,
+					    zero_region),
+					/*dxfer_len*/ softc->params.secsize,
+					/*sense_len*/SSD_FULL_SIZE,
+					da_default_timeout * 1000);
+			start_ccb->ccb_h.ccb_state = DA_CCB_DELETE;
+			goto out;
+		    } else {
+			bioq_flush(&softc->delete_queue, NULL, 0);
+			/* FALLTHROUGH */
+		    }
+		}
+
+		/* Run regular command. */
+		bp = bioq_takefirst(&softc->bio_queue);
+		if (bp == NULL) {
 			xpt_release_ccb(start_ccb);
+			break;
+		}
+
+		if ((bp->bio_flags & BIO_ORDERED) != 0 ||
+		    (softc->flags & DA_FLAG_NEED_OTAG) != 0) {
+			softc->flags &= ~DA_FLAG_NEED_OTAG;
+			softc->ordered_tag_count++;
+			tag_code = MSG_ORDERED_Q_TAG;
 		} else {
-			u_int8_t tag_code;
+			tag_code = MSG_SIMPLE_Q_TAG;
+		}
 
-			bioq_remove(&softc->bio_queue, bp);
+		switch (bp->bio_cmd) {
+		case BIO_READ:
+		case BIO_WRITE:
+			scsi_read_write(&start_ccb->csio,
+					/*retries*/da_retry_count,
+					/*cbfcnp*/dadone,
+					/*tag_action*/tag_code,
+					/*read_op*/bp->bio_cmd
+						== BIO_READ,
+					/*byte2*/0,
+					softc->minimum_cmd_size,
+					/*lba*/bp->bio_pblkno,
+					/*block_count*/bp->bio_bcount /
+					softc->params.secsize,
+					/*data_ptr*/ bp->bio_data,
+					/*dxfer_len*/ bp->bio_bcount,
+					/*sense_len*/SSD_FULL_SIZE,
+					da_default_timeout * 1000);
+			break;
+		case BIO_FLUSH:
+			/*
+			 * BIO_FLUSH doesn't currently communicate
+			 * range data, so we synchronize the cache
+			 * over the whole disk.  We also force
+			 * ordered tag semantics the flush applies
+			 * to all previously queued I/O.
+			 */
+			scsi_synchronize_cache(&start_ccb->csio,
+					       /*retries*/1,
+					       /*cbfcnp*/dadone,
+					       MSG_ORDERED_Q_TAG,
+					       /*begin_lba*/0,
+					       /*lb_count*/0,
+					       SSD_FULL_SIZE,
+					       da_default_timeout*1000);
+			break;
+		}
+		start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
 
-			if ((bp->bio_flags & BIO_ORDERED) != 0
-			 || (softc->flags & DA_FLAG_NEED_OTAG) != 0) {
-				softc->flags &= ~DA_FLAG_NEED_OTAG;
-				softc->ordered_tag_count++;
-				tag_code = MSG_ORDERED_Q_TAG;
-			} else {
-				tag_code = MSG_SIMPLE_Q_TAG;
-			}
-			switch (bp->bio_cmd) {
-			case BIO_READ:
-			case BIO_WRITE:
-				scsi_read_write(&start_ccb->csio,
-						/*retries*/da_retry_count,
-						/*cbfcnp*/dadone,
-						/*tag_action*/tag_code,
-						/*read_op*/bp->bio_cmd
-							== BIO_READ,
-						/*byte2*/0,
-						softc->minimum_cmd_size,
-						/*lba*/bp->bio_pblkno,
-						/*block_count*/bp->bio_bcount /
-						softc->params.secsize,
-						/*data_ptr*/ bp->bio_data,
-						/*dxfer_len*/ bp->bio_bcount,
-						/*sense_len*/SSD_FULL_SIZE,
-						da_default_timeout * 1000);
-				break;
-			case BIO_FLUSH:
-				/*
-				 * BIO_FLUSH doesn't currently communicate
-				 * range data, so we synchronize the cache
-				 * over the whole disk.  We also force
-				 * ordered tag semantics the flush applies
-				 * to all previously queued I/O.
-				 */
-				scsi_synchronize_cache(&start_ccb->csio,
-						       /*retries*/1,
-						       /*cbfcnp*/dadone,
-						       MSG_ORDERED_Q_TAG,
-						       /*begin_lba*/0,
-						       /*lb_count*/0,
-						       SSD_FULL_SIZE,
-						       da_default_timeout*1000);
-				break;
-			}
-			start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
+out:
+		/*
+		 * Block out any asyncronous callbacks
+		 * while we touch the pending ccb list.
+		 */
+		LIST_INSERT_HEAD(&softc->pending_ccbs,
+				 &start_ccb->ccb_h, periph_links.le);
+		softc->outstanding_cmds++;
 
-			/*
-			 * Block out any asyncronous callbacks
-			 * while we touch the pending ccb list.
-			 */
-			LIST_INSERT_HEAD(&softc->pending_ccbs,
-					 &start_ccb->ccb_h, periph_links.le);
-			softc->outstanding_cmds++;
+		/* We expect a unit attention from this device */
+		if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
+			start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA;
+			softc->flags &= ~DA_FLAG_RETRY_UA;
+		}
 
-			/* We expect a unit attention from this device */
-			if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
-				start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA;
-				softc->flags &= ~DA_FLAG_RETRY_UA;
-			}
+		start_ccb->ccb_h.ccb_bp = bp;
+		xpt_action(start_ccb);
 
-			start_ccb->ccb_h.ccb_bp = bp;
-			bp = bioq_first(&softc->bio_queue);
-
-			xpt_action(start_ccb);
-		}
-		
-		if (bp != NULL) {
-			/* Have more work to do, so ensure we stay scheduled */
-			xpt_schedule(periph, CAM_PRIORITY_NORMAL);
-		}
+		/* May have more work to do, so ensure we stay scheduled */
+		daschedule(periph);
 		break;
 	}
 	case DA_STATE_PROBE:
@@ -1779,9 +1966,42 @@
 	struct scsi_rw_10 *cmd10;
 	struct da_softc *softc;
 	u_int8_t *cdb;
+	struct bio *bp;
 	int frozen;
 
 	cdb = ccb->csio.cdb_io.cdb_bytes;
+	softc = (struct da_softc *)xpt_path_periph(ccb->ccb_h.path)->softc;
+
+	if (ccb->ccb_h.ccb_state == DA_CCB_DELETE) {
+		if (softc->delete_method == DA_DELETE_UNMAP) {
+			xpt_print(ccb->ccb_h.path, "UNMAP is not supported, "
+			    "switching to WRITE SAME(16) with UNMAP.\n");
+			softc->delete_method = DA_DELETE_WS16;
+		} else if (softc->delete_method == DA_DELETE_WS16) {
+			xpt_print(ccb->ccb_h.path,
+			    "WRITE SAME(16) with UNMAP is not supported, "
+			    "disabling BIO_DELETE.\n");
+			softc->delete_method = DA_DELETE_DISABLE;
+		} else if (softc->delete_method == DA_DELETE_WS10) {
+			xpt_print(ccb->ccb_h.path,
+			    "WRITE SAME(10) with UNMAP is not supported, "
+			    "disabling BIO_DELETE.\n");
+			softc->delete_method = DA_DELETE_DISABLE;
+		} else if (softc->delete_method == DA_DELETE_ZERO) {
+			xpt_print(ccb->ccb_h.path,
+			    "WRITE SAME(10) is not supported, "
+			    "disabling BIO_DELETE.\n");
+			softc->delete_method = DA_DELETE_DISABLE;
+		} else
+			softc->delete_method = DA_DELETE_DISABLE;
+		while ((bp = bioq_takefirst(&softc->delete_run_queue))
+		    != NULL)
+			bioq_disksort(&softc->delete_queue, bp);
+		bioq_insert_tail(&softc->delete_queue,
+		    (struct bio *)ccb->ccb_h.ccb_bp);
+		ccb->ccb_h.ccb_bp = NULL;
+		return (0);
+	}
 
 	/* Translation only possible if CDB is an array and cmd is R/W6 */
 	if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0 ||
@@ -1790,8 +2010,7 @@
 
 	xpt_print(ccb->ccb_h.path, "READ(6)/WRITE(6) not supported, "
 	    "increasing minimum_cmd_size to 10.\n");
- 	softc = (struct da_softc *)xpt_path_periph(ccb->ccb_h.path)->softc;
-	softc->minimum_cmd_size = 10;
+ 	softc->minimum_cmd_size = 10;
 
 	bcopy(cdb, &cmd6, sizeof(struct scsi_rw_6));
 	cmd10 = (struct scsi_rw_10 *)cdb;
@@ -1829,8 +2048,9 @@
 	csio = &done_ccb->csio;
 	switch (csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) {
 	case DA_CCB_BUFFER_IO:
+	case DA_CCB_DELETE:
 	{
-		struct bio *bp;
+		struct bio *bp, *bp1;
 
 		bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
@@ -1850,6 +2070,7 @@
 				 */
 				return;
 			}
+			bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
 			if (error != 0) {
 				int queued_error;
 
@@ -1877,10 +2098,12 @@
 				}
 				bioq_flush(&softc->bio_queue, NULL,
 					   queued_error);
-				bp->bio_error = error;
-				bp->bio_resid = bp->bio_bcount;
-				bp->bio_flags |= BIO_ERROR;
-			} else {
+				if (bp != NULL) {
+					bp->bio_error = error;
+					bp->bio_resid = bp->bio_bcount;
+					bp->bio_flags |= BIO_ERROR;
+				}
+			} else if (bp != NULL) {
 				bp->bio_resid = csio->resid;
 				bp->bio_error = 0;
 				if (bp->bio_resid != 0)
@@ -1892,7 +2115,7 @@
 						 /*reduction*/0,
 						 /*timeout*/0,
 						 /*getcount_only*/0);
-		} else {
+		} else if (bp != NULL) {
 			if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
 				panic("REQ_CMP with QFRZN");
 			bp->bio_resid = csio->resid;
@@ -1921,7 +2144,22 @@
 				  softc->outstanding_cmds);
 		}
 
-		biodone(bp);
+		if ((csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) ==
+		    DA_CCB_DELETE) {
+			while ((bp1 = bioq_takefirst(&softc->delete_run_queue))
+			    != NULL) {
+				bp1->bio_resid = bp->bio_resid;
+				bp1->bio_error = bp->bio_error;
+				if (bp->bio_flags & BIO_ERROR)
+					bp1->bio_flags |= BIO_ERROR;
+				biodone(bp1);
+			}
+			softc->delete_running = 0;
+			if (bp != NULL)
+				biodone(bp);
+			daschedule(periph);
+		} else if (bp != NULL)
+			biodone(bp);
 		break;
 	}
 	case DA_CCB_PROBE:
@@ -1991,10 +2229,9 @@
 			} else {
 				dasetgeom(periph, block_size, maxsector,
 				    lbppbe, lalba & SRC16_LALBA);
-				if (lalba & SRC16_LBPME)
-					softc->flags |= DA_FLAG_CAN_LBPME;
-				else
-					softc->flags &= ~DA_FLAG_CAN_LBPME;
+				if ((lalba & SRC16_LBPME) &&
+				    softc->delete_method == DA_DELETE_NONE)
+					softc->delete_method = DA_DELETE_UNMAP;
 				dp = &softc->params;
 				snprintf(announce_buf, sizeof(announce_buf),
 				        "%juMB (%ju %u byte sectors: %dH %dS/T "
@@ -2381,10 +2618,9 @@
 		} else {
 			dasetgeom(periph, block_len, maxsector,
 			    lbppbe, lalba & SRC16_LALBA);
-			if (lalba & SRC16_LBPME)
-				softc->flags |= DA_FLAG_CAN_LBPME;
-			else
-				softc->flags &= ~DA_FLAG_CAN_LBPME;
+			if ((lalba & SRC16_LBPME) &&
+			    softc->delete_method == DA_DELETE_NONE)
+				softc->delete_method = DA_DELETE_UNMAP;
 		}
 	}
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/compat/linprocfs/linprocfs.c
--- a/head/sys/compat/linprocfs/linprocfs.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/compat/linprocfs/linprocfs.c	Mon Jan 16 14:38:30 2012 +0200
@@ -42,7 +42,7 @@
 #include "opt_compat.h"
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linprocfs/linprocfs.c 228268 2011-12-04 21:43:13Z trociny $");
+__FBSDID("$FreeBSD: head/sys/compat/linprocfs/linprocfs.c 230145 2012-01-15 18:47:24Z trociny $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -954,7 +954,7 @@
 
 	PROC_UNLOCK(p);
 
-	ret = proc_getargv(td, p, sb, ARG_MAX);
+	ret = proc_getargv(td, p, sb);
 	return (ret);
 }
 
@@ -988,7 +988,7 @@
 
 	PROC_UNLOCK(p);
 
-	ret = proc_getenvv(td, p, sb, ARG_MAX);
+	ret = proc_getenvv(td, p, sb);
 	return (ret);
 }
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/compat/linux/linux_file.c
--- a/head/sys/compat/linux/linux_file.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/compat/linux/linux_file.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1994-1995 Søren Schmidt
+ * Copyright (c) 1994-1995 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_file.c 228957 2011-12-29 15:34:59Z jhb $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_file.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_compat.h"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/compat/linux/linux_ioctl.c
--- a/head/sys/compat/linux/linux_ioctl.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/compat/linux/linux_ioctl.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1994-1995 Søren Schmidt
+ * Copyright (c) 1994-1995 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -29,7 +29,7 @@
 #include "opt_compat.h"
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_ioctl.c 229402 2012-01-03 18:49:39Z dim $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_ioctl.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/compat/linux/linux_ipc.c
--- a/head/sys/compat/linux/linux_ipc.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/compat/linux/linux_ipc.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1994-1995 Søren Schmidt
+ * Copyright (c) 1994-1995 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_ipc.c 225617 2011-09-16 13:58:51Z kmacy $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_ipc.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/compat/linux/linux_misc.c
--- a/head/sys/compat/linux/linux_misc.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/compat/linux/linux_misc.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2002 Doug Rabson
- * Copyright (c) 1994-1995 Søren Schmidt
+ * Copyright (c) 1994-1995 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_misc.c 225617 2011-09-16 13:58:51Z kmacy $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_misc.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_compat.h"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/compat/linux/linux_signal.c
--- a/head/sys/compat/linux/linux_signal.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/compat/linux/linux_signal.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1994-1995 Søren Schmidt
+ * Copyright (c) 1994-1995 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_signal.c 225617 2011-09-16 13:58:51Z kmacy $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_signal.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/compat/linux/linux_socket.c
--- a/head/sys/compat/linux/linux_socket.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/compat/linux/linux_socket.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1995 Søren Schmidt
+ * Copyright (c) 1995 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_socket.c 226079 2011-10-06 21:55:05Z jkim $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_socket.c 230132 2012-01-15 13:23:18Z uqs $");
 
 /* XXX we use functions that might not exist. */
 #include "opt_compat.h"
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/compat/linux/linux_stats.c
--- a/head/sys/compat/linux/linux_stats.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/compat/linux/linux_stats.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1994-1995 Søren Schmidt
+ * Copyright (c) 1994-1995 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/linux/linux_stats.c 224778 2011-08-11 12:30:23Z rwatson $");
+__FBSDID("$FreeBSD: head/sys/compat/linux/linux_stats.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_compat.h"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/compat/svr4/imgact_svr4.c
--- a/head/sys/compat/svr4/imgact_svr4.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/compat/svr4/imgact_svr4.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 1998 Mark Newton
- * Copyright (c) 1994-1996 Søren Schmidt
+ * Copyright (c) 1994-1996 Søren Schmidt
  * All rights reserved.
  *
  * Based heavily on /sys/kern/imgact_aout.c which is:
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/compat/svr4/imgact_svr4.c 220515 2011-04-10 10:15:49Z trasz $");
+__FBSDID("$FreeBSD: head/sys/compat/svr4/imgact_svr4.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/conf/files
--- a/head/sys/conf/files	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/conf/files	Mon Jan 16 14:38:30 2012 +0200
@@ -1,4 +1,4 @@
-# $FreeBSD: head/sys/conf/files 229997 2012-01-12 00:34:33Z ken $
+# $FreeBSD: head/sys/conf/files 230130 2012-01-15 13:21:36Z mav $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -1761,7 +1761,11 @@
 dev/sound/pci/via8233.c		optional snd_via8233 pci
 dev/sound/pci/via82c686.c	optional snd_via82c686 pci
 dev/sound/pci/vibes.c		optional snd_vibes pci
+dev/sound/pci/hda/hdaa.c	optional snd_hda pci
+dev/sound/pci/hda/hdaa_patches.c	optional snd_hda pci
 dev/sound/pci/hda/hdac.c	optional snd_hda pci
+dev/sound/pci/hda/hdac_if.m	optional snd_hda pci
+dev/sound/pci/hda/hdacc.c	optional snd_hda pci
 dev/sound/pcm/ac97.c		optional sound
 dev/sound/pcm/ac97_if.m		optional sound
 dev/sound/pcm/ac97_patch.c	optional sound
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/conf/kmod.mk
--- a/head/sys/conf/kmod.mk	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/conf/kmod.mk	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 #	From: @(#)bsd.prog.mk	5.26 (Berkeley) 6/25/91
-# $FreeBSD: head/sys/conf/kmod.mk 228311 2011-12-06 18:01:09Z fjoe $
+# $FreeBSD: head/sys/conf/kmod.mk 230130 2012-01-15 13:21:36Z mav $
 #
 # The include file <bsd.kmod.mk> handles building and installing loadable
 # kernel modules.
@@ -345,6 +345,7 @@
 	dev/mii/miibus_if.m dev/mvs/mvs_if.m dev/ofw/ofw_bus_if.m \
 	dev/pccard/card_if.m dev/pccard/power_if.m dev/pci/pci_if.m \
 	dev/pci/pcib_if.m dev/ppbus/ppbus_if.m dev/smbus/smbus_if.m \
+	dev/sound/pci/hda/hdac_if.m \
 	dev/sound/pcm/ac97_if.m dev/sound/pcm/channel_if.m \
 	dev/sound/pcm/feeder_if.m dev/sound/pcm/mixer_if.m \
 	dev/sound/midi/mpu_if.m dev/sound/midi/mpufoi_if.m \
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/conf/options
--- a/head/sys/conf/options	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/conf/options	Mon Jan 16 14:38:30 2012 +0200
@@ -1,4 +1,4 @@
-# $FreeBSD: head/sys/conf/options 229537 2012-01-04 23:39:11Z ray $
+# $FreeBSD: head/sys/conf/options 230195 2012-01-16 05:07:32Z adrian $
 #
 #        On the handling of kernel options
 #
@@ -900,6 +900,7 @@
 # At least one of the AR71XX ubiquiti boards has a Redboot configuration
 # that "lies" about the amount of RAM it has. Until a cleaner method is
 # defined, this option will suffice in overriding what Redboot says.
-AR71XX_REALMEM    opt_global.h
-AR71XX_ENV_UBOOT	opt_global.h
-AR71XX_ENV_REDBOOT	opt_global.h
+AR71XX_REALMEM		opt_ar71xx.h
+AR71XX_ENV_UBOOT	opt_ar71xx.h
+AR71XX_ENV_REDBOOT	opt_ar71xx.h
+AR71XX_ATH_EEPROM	opt_ar71xx.h
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/contrib/dev/npe/LICENSE
--- a/head/sys/contrib/dev/npe/LICENSE	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/contrib/dev/npe/LICENSE	Mon Jan 16 14:38:30 2012 +0200
@@ -1,4 +1,4 @@
-$FreeBSD$
+$FreeBSD: head/sys/contrib/dev/npe/LICENSE 230135 2012-01-15 13:23:54Z uqs $
 
 Copyright (c) 2007, Intel Corporation.
 All rights reserved.
@@ -8,5 +8,5 @@
 - Neither the name of Intel Corporation nor the names of its suppliers may be used to endorse or promote products derived from this software without specific prior written permission.
 - No reverse engineering, decompilation, or disassembly of this software is permitted.
 
-Limited patent license. Intel Corporation grants a world-wide, royalty-free, non-exclusive license under patents it now or hereafter owns or controls to make, have made, use, import, offer to sell and sell (¿Utilize¿) this software, but solely to the extent that any such patent is necessary to Utilize the software alone. The patent license shall not apply to any combinations which include this software. No hardware per se is licensed hereunder.
+Limited patent license. Intel Corporation grants a world-wide, royalty-free, non-exclusive license under patents it now or hereafter owns or controls to make, have made, use, import, offer to sell and sell ("Utilize") this software, but solely to the extent that any such patent is necessary to Utilize the software alone. The patent license shall not apply to any combinations which include this software. No hardware per se is licensed hereunder.
 DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/contrib/dev/nve/amd64/nvenetlib.README
--- a/head/sys/contrib/dev/nve/amd64/nvenetlib.README	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/contrib/dev/nve/amd64/nvenetlib.README	Mon Jan 16 14:38:30 2012 +0200
@@ -1,10 +1,10 @@
-$FreeBSD$
+$FreeBSD: head/sys/contrib/dev/nve/amd64/nvenetlib.README 230135 2012-01-15 13:23:54Z uqs $
 
 The installation and use of this software is subject to the following license terms and conditions:
 
 License For Customer Use of NVIDIA Software 
 
-IMPORTANT NOTICE -- READ CAREFULLY: This License For Customer Use of NVIDIA Software ("LICENSE") is the agreement which governs use of the software of NVIDIA Corporation and its subsidiaries (“NVIDIA”) enclosed herewith, including computer software and associated printed materials ("SOFTWARE"). By downloading, installing, copying, or otherwise using the SOFTWARE, you agree to be bound by the terms of this LICENSE. If you do not agree to the terms of this LICENSE, do not download, install or use the SOFTWARE.
+IMPORTANT NOTICE -- READ CAREFULLY: This License For Customer Use of NVIDIA Software ("LICENSE") is the agreement which governs use of the software of NVIDIA Corporation and its subsidiaries ("NVIDIA") enclosed herewith, including computer software and associated printed materials ("SOFTWARE"). By downloading, installing, copying, or otherwise using the SOFTWARE, you agree to be bound by the terms of this LICENSE. If you do not agree to the terms of this LICENSE, do not download, install or use the SOFTWARE.
 
 RECITALS
 Use of NVIDIA's products requires three elements: the SOFTWARE, the hardware on a computer motherboard, and a personal computer. The SOFTWARE is protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties. The SOFTWARE is not sold, and instead is only licensed for use, strictly in accordance with this document. The hardware is protected by various patents, and is sold, but this agreement does not cover that sale, since it may not necessarily be sold as a package with the SOFTWARE. This agreement sets forth the terms and conditions of the SOFTWARE LICENSE only.
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/contrib/dev/nve/i386/nvenetlib.README
--- a/head/sys/contrib/dev/nve/i386/nvenetlib.README	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/contrib/dev/nve/i386/nvenetlib.README	Mon Jan 16 14:38:30 2012 +0200
@@ -1,10 +1,10 @@
-$FreeBSD$
+$FreeBSD: head/sys/contrib/dev/nve/i386/nvenetlib.README 230135 2012-01-15 13:23:54Z uqs $
 
 The installation and use of this software is subject to the following license terms and conditions:
 
 License For Customer Use of NVIDIA Software 
 
-IMPORTANT NOTICE -- READ CAREFULLY: This License For Customer Use of NVIDIA Software ("LICENSE") is the agreement which governs use of the software of NVIDIA Corporation and its subsidiaries (“NVIDIA”) enclosed herewith, including computer software and associated printed materials ("SOFTWARE"). By downloading, installing, copying, or otherwise using the SOFTWARE, you agree to be bound by the terms of this LICENSE. If you do not agree to the terms of this LICENSE, do not download, install or use the SOFTWARE.
+IMPORTANT NOTICE -- READ CAREFULLY: This License For Customer Use of NVIDIA Software ("LICENSE") is the agreement which governs use of the software of NVIDIA Corporation and its subsidiaries ("NVIDIA") enclosed herewith, including computer software and associated printed materials ("SOFTWARE"). By downloading, installing, copying, or otherwise using the SOFTWARE, you agree to be bound by the terms of this LICENSE. If you do not agree to the terms of this LICENSE, do not download, install or use the SOFTWARE.
 
 RECITALS
 Use of NVIDIA's products requires three elements: the SOFTWARE, the hardware on a computer motherboard, and a personal computer. The SOFTWARE is protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties. The SOFTWARE is not sold, and instead is only licensed for use, strictly in accordance with this document. The hardware is protected by various patents, and is sold, but this agreement does not cover that sale, since it may not necessarily be sold as a package with the SOFTWARE. This agreement sets forth the terms and conditions of the SOFTWARE LICENSE only.
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/contrib/octeon-sdk/cvmx-pcie.c
--- a/head/sys/contrib/octeon-sdk/cvmx-pcie.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/contrib/octeon-sdk/cvmx-pcie.c	Mon Jan 16 14:38:30 2012 +0200
@@ -501,6 +501,12 @@
         }
     }
 
+    /* Make sure a CN56XX pass 1 isn't trying to do anything; errata for PASS 1 */
+    if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)) {
+        cvmx_dprintf ("PCIe port %d: CN56XX_PASS_1, skipping\n", pcie_port);
+        return -1;
+    }
+
     /* PCIe switch arbitration mode. '0' == fixed priority NPEI, PCIe0, then PCIe1. '1' == round robin. */
     npei_ctl_status.s.arb = 1;
     /* Allow up to 0x20 config retries */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/contrib/pf/net/pf_table.c
--- a/head/sys/contrib/pf/net/pf_table.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/contrib/pf/net/pf_table.c	Mon Jan 16 14:38:30 2012 +0200
@@ -35,7 +35,7 @@
 #include "opt_inet6.h"
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf_table.c 226535 2011-10-19 10:16:42Z bz $");
+__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf_table.c 230119 2012-01-14 22:51:34Z csjp $");
 #endif
 
 #include <sys/param.h>
@@ -927,16 +927,12 @@
 {
 	struct pfr_kentry	*ke;
 
+#ifdef __FreeBSD__
+	ke =  pool_get(&V_pfr_kentry_pl, PR_NOWAIT | PR_ZERO);
+#else
 	if (intr)
-#ifdef __FreeBSD__
-		ke = pool_get(&V_pfr_kentry_pl, PR_NOWAIT | PR_ZERO);
-#else
 		ke = pool_get(&pfr_kentry_pl, PR_NOWAIT | PR_ZERO);
-#endif
 	else
-#ifdef __FreeBSD__
-		ke = pool_get(&V_pfr_kentry_pl, PR_WAITOK|PR_ZERO);
-#else
 		ke = pool_get(&pfr_kentry_pl, PR_WAITOK|PR_ZERO|PR_LIMITFAIL);
 #endif
 	if (ke == NULL)
@@ -2081,16 +2077,12 @@
 	struct pfr_ktable	*kt;
 	struct pf_ruleset	*rs;
 
+#ifdef __FreeBSD__
+	kt = pool_get(&V_pfr_ktable_pl, PR_NOWAIT|PR_ZERO);
+#else
 	if (intr)
-#ifdef __FreeBSD__
-		kt = pool_get(&V_pfr_ktable_pl, PR_NOWAIT|PR_ZERO);
-#else
 		kt = pool_get(&pfr_ktable_pl, PR_NOWAIT|PR_ZERO|PR_LIMITFAIL);
-#endif
 	else
-#ifdef __FreeBSD__
-		kt = pool_get(&V_pfr_ktable_pl, PR_WAITOK|PR_ZERO);
-#else
 		kt = pool_get(&pfr_ktable_pl, PR_WAITOK|PR_ZERO|PR_LIMITFAIL);
 #endif
 	if (kt == NULL)
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ahci/ahci.h
--- a/head/sys/dev/ahci/ahci.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ahci/ahci.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * Copyright (c) 2009 Alexander Motin <mav at FreeBSD.org>
  * All rights reserved.
  *
@@ -24,7 +24,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/dev/ahci/ahci.h 224498 2011-07-29 20:35:23Z mav $
+ * $FreeBSD: head/sys/dev/ahci/ahci.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 /* ATA register defines */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-all.c
--- a/head/sys/dev/ata/ata-all.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-all.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/ata-all.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/ata-all.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-all.h
--- a/head/sys/dev/ata/ata-all.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-all.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/dev/ata/ata-all.h 220563 2011-04-12 09:55:24Z mav $
+ * $FreeBSD: head/sys/dev/ata/ata-all.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include "opt_ata.h"
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-card.c
--- a/head/sys/dev/ata/ata-card.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-card.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/ata-card.c 209682 2010-07-04 05:58:17Z imp $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/ata-card.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-cbus.c
--- a/head/sys/dev/ata/ata-cbus.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-cbus.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2002 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 2002 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/ata-cbus.c 189600 2009-03-09 20:48:57Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/ata-cbus.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-disk.c
--- a/head/sys/dev/ata/ata-disk.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-disk.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/ata-disk.c 229272 2012-01-02 12:12:10Z ed $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/ata-disk.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-disk.h
--- a/head/sys/dev/ata/ata-disk.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-disk.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/dev/ata/ata-disk.h 178067 2008-04-10 13:05:05Z sos $
+ * $FreeBSD: head/sys/dev/ata/ata-disk.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 /* structure describing an ATA disk */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-dma.c
--- a/head/sys/dev/ata/ata-dma.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-dma.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/ata-dma.c 219336 2011-03-06 12:54:00Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/ata-dma.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-isa.c
--- a/head/sys/dev/ata/ata-isa.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-isa.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/ata-isa.c 226680 2011-10-24 08:47:23Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/ata-isa.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-lowlevel.c
--- a/head/sys/dev/ata/ata-lowlevel.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-lowlevel.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/ata-lowlevel.c 220911 2011-04-21 07:26:14Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/ata-lowlevel.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-pci.c
--- a/head/sys/dev/ata/ata-pci.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-pci.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/ata-pci.c 227849 2011-11-22 21:56:55Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/ata-pci.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-pci.h
--- a/head/sys/dev/ata/ata-pci.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-pci.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2003 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 2003 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/dev/ata/ata-pci.h 229671 2012-01-06 00:22:55Z jimharris $
+ * $FreeBSD: head/sys/dev/ata/ata-pci.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 /* structure holding chipset config info */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-queue.c
--- a/head/sys/dev/ata/ata-queue.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-queue.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/ata-queue.c 207221 2010-04-26 11:58:15Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/ata-queue.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-raid.c
--- a/head/sys/dev/ata/ata-raid.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-raid.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2000 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 2000 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/ata-raid.c 205680 2010-03-26 10:18:19Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/ata-raid.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
@@ -595,11 +595,11 @@
 		}
 		if (bp->bio_cmd == BIO_WRITE) { 
 		    ata_raid_send_request(request);
-		    // sikre at læs-modify-skriv til hver disk er atomarisk.
+		    // sikre at læs-modify-skriv til hver disk er atomarisk.
 		    // par kopi af request
-		    // læse orgdata fra drv
+		    // læse orgdata fra drv
 		    // skriv nydata til drv
-		    // læse parorgdata fra par
+		    // læse parorgdata fra par
 		    // skriv orgdata xor parorgdata xor nydata til par
 		}
 	    }
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-raid.h
--- a/head/sys/dev/ata/ata-raid.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-raid.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2000 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 2000 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/dev/ata/ata-raid.h 188840 2009-02-20 06:10:12Z scottl $
+ * $FreeBSD: head/sys/dev/ata/ata-raid.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 /* misc defines */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata-sata.c
--- a/head/sys/dev/ata/ata-sata.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata-sata.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/ata-sata.c 222897 2011-06-09 16:30:13Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/ata-sata.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/ata_if.m
--- a/head/sys/dev/ata/ata_if.m	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/ata_if.m	Mon Jan 16 14:38:30 2012 +0200
@@ -1,4 +1,4 @@
-# Copyright (c) 2004 - 2008 Søren Schmidt <sos at FreeBSD.org>
+# Copyright (c) 2004 - 2008 Søren Schmidt <sos at FreeBSD.org>
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -22,7 +22,7 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #
-# $FreeBSD: head/sys/dev/ata/ata_if.m 202699 2010-01-20 14:29:55Z rpaulo $
+# $FreeBSD: head/sys/dev/ata/ata_if.m 230132 2012-01-15 13:23:18Z uqs $
 
 #include <sys/bus.h>
 #include <sys/kernel.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/atapi-cd.c
--- a/head/sys/dev/ata/atapi-cd.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/atapi-cd.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/atapi-cd.c 200481 2009-12-13 18:26:19Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/atapi-cd.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/atapi-cd.h
--- a/head/sys/dev/ata/atapi-cd.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/atapi-cd.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/dev/ata/atapi-cd.h 200481 2009-12-13 18:26:19Z marius $
+ * $FreeBSD: head/sys/dev/ata/atapi-cd.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 /* CDROM Table Of Contents */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/atapi-fd.c
--- a/head/sys/dev/ata/atapi-fd.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/atapi-fd.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/atapi-fd.c 200171 2009-12-06 00:10:13Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/atapi-fd.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/atapi-fd.h
--- a/head/sys/dev/ata/atapi-fd.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/atapi-fd.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/dev/ata/atapi-fd.h 178067 2008-04-10 13:05:05Z sos $
+ * $FreeBSD: head/sys/dev/ata/atapi-fd.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 /* ATAPI Rewriteable drive Capabilities and Mechanical Status Page */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/atapi-tape.c
--- a/head/sys/dev/ata/atapi-tape.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/atapi-tape.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/atapi-tape.c 200171 2009-12-06 00:10:13Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/atapi-tape.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/atapi-tape.h
--- a/head/sys/dev/ata/atapi-tape.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/atapi-tape.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/dev/ata/atapi-tape.h 178067 2008-04-10 13:05:05Z sos $
+ * $FreeBSD: head/sys/dev/ata/atapi-tape.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 /* ATAPI tape drive Capabilities and Mechanical Status Page */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-acard.c
--- a/head/sys/dev/ata/chipsets/ata-acard.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-acard.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-acard.c 224270 2011-07-22 16:37:04Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-acard.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-acerlabs.c
--- a/head/sys/dev/ata/chipsets/ata-acerlabs.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-acerlabs.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-acerlabs.c 224270 2011-07-22 16:37:04Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-acerlabs.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-adaptec.c
--- a/head/sys/dev/ata/chipsets/ata-adaptec.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-adaptec.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-adaptec.c 198700 2009-10-30 20:28:49Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-adaptec.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-ahci.c
--- a/head/sys/dev/ata/chipsets/ata-ahci.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-ahci.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-ahci.c 219337 2011-03-06 13:06:41Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-ahci.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-amd.c
--- a/head/sys/dev/ata/chipsets/ata-amd.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-amd.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-amd.c 209872 2010-07-10 13:46:14Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-amd.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-ati.c
--- a/head/sys/dev/ata/chipsets/ata-ati.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-ati.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-ati.c 228200 2011-12-02 12:52:33Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-ati.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-cenatek.c
--- a/head/sys/dev/ata/chipsets/ata-cenatek.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-cenatek.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-cenatek.c 200171 2009-12-06 00:10:13Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-cenatek.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-cypress.c
--- a/head/sys/dev/ata/chipsets/ata-cypress.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-cypress.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-cypress.c 200171 2009-12-06 00:10:13Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-cypress.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-cyrix.c
--- a/head/sys/dev/ata/chipsets/ata-cyrix.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-cyrix.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-cyrix.c 216013 2010-11-28 18:53:29Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-cyrix.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-highpoint.c
--- a/head/sys/dev/ata/chipsets/ata-highpoint.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-highpoint.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-highpoint.c 209872 2010-07-10 13:46:14Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-highpoint.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-intel.c
--- a/head/sys/dev/ata/chipsets/ata-intel.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-intel.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-intel.c 229671 2012-01-06 00:22:55Z jimharris $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-intel.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-ite.c
--- a/head/sys/dev/ata/chipsets/ata-ite.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-ite.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-ite.c 209872 2010-07-10 13:46:14Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-ite.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-jmicron.c
--- a/head/sys/dev/ata/chipsets/ata-jmicron.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-jmicron.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-jmicron.c 209872 2010-07-10 13:46:14Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-jmicron.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-marvell.c
--- a/head/sys/dev/ata/chipsets/ata-marvell.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-marvell.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-marvell.c 216013 2010-11-28 18:53:29Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-marvell.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-micron.c
--- a/head/sys/dev/ata/chipsets/ata-micron.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-micron.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-micron.c 200171 2009-12-06 00:10:13Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-micron.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-national.c
--- a/head/sys/dev/ata/chipsets/ata-national.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-national.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-national.c 216013 2010-11-28 18:53:29Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-national.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-netcell.c
--- a/head/sys/dev/ata/chipsets/ata-netcell.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-netcell.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-netcell.c 203347 2010-02-01 15:22:22Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-netcell.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-nvidia.c
--- a/head/sys/dev/ata/chipsets/ata-nvidia.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-nvidia.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-nvidia.c 228200 2011-12-02 12:52:33Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-nvidia.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-promise.c
--- a/head/sys/dev/ata/chipsets/ata-promise.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-promise.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-promise.c 227000 2011-11-01 17:57:21Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-promise.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-serverworks.c
--- a/head/sys/dev/ata/chipsets/ata-serverworks.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-serverworks.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-serverworks.c 216013 2010-11-28 18:53:29Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-serverworks.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-siliconimage.c
--- a/head/sys/dev/ata/chipsets/ata-siliconimage.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-siliconimage.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-siliconimage.c 227000 2011-11-01 17:57:21Z marius $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-siliconimage.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-sis.c
--- a/head/sys/dev/ata/chipsets/ata-sis.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-sis.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-sis.c 209884 2010-07-10 15:36:27Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-sis.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ata/chipsets/ata-via.c
--- a/head/sys/dev/ata/chipsets/ata-via.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ata/chipsets/ata-via.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 1998 - 2008 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-via.c 215451 2010-11-18 10:34:18Z mav $");
+__FBSDID("$FreeBSD: head/sys/dev/ata/chipsets/ata-via.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_ata.h"
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ath/ath_hal/ah.c
--- a/head/sys/dev/ath/ath_hal/ah.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ath/ath_hal/ah.c	Mon Jan 16 14:38:30 2012 +0200
@@ -14,7 +14,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $FreeBSD: head/sys/dev/ath/ath_hal/ah.c 227410 2011-11-09 22:39:44Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_hal/ah.c 230147 2012-01-15 19:22:34Z adrian $
  */
 #include "opt_ah.h"
 
@@ -1266,3 +1266,27 @@
 		return 1;
 	return ((diag & 0x500000) == 0);
 }
+
+/*
+ * This routine is only needed when supporting EEPROM-in-RAM setups
+ * (eg embedded SoCs and on-board PCI/PCIe devices.)
+ */
+/* NB: This is in 16 bit words; not bytes */
+/* XXX This doesn't belong here!  */
+#define ATH_DATA_EEPROM_SIZE    2048
+
+HAL_BOOL
+ath_hal_EepromDataRead(struct ath_hal *ah, u_int off, uint16_t *data)
+{
+	if (ah->ah_eepromdata == AH_NULL) {
+		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: no eeprom data!\n", __func__);
+		return AH_FALSE;
+	}
+	if (off > ATH_DATA_EEPROM_SIZE) {
+		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: offset %x > %x\n",
+		    __func__, off, ATH_DATA_EEPROM_SIZE);
+		return AH_FALSE;
+	}
+	(*data) = ah->ah_eepromdata[off];
+	return AH_TRUE;
+}
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ath/ath_hal/ah.h
--- a/head/sys/dev/ath/ath_hal/ah.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ath/ath_hal/ah.h	Mon Jan 16 14:38:30 2012 +0200
@@ -14,7 +14,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $FreeBSD: head/sys/dev/ath/ath_hal/ah.h 227410 2011-11-09 22:39:44Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_hal/ah.h 230147 2012-01-15 19:22:34Z adrian $
  */
 
 #ifndef _ATH_AH_H_
@@ -1169,4 +1169,10 @@
  */
 int __ahdecl ath_hal_getcca(struct ath_hal *ah);
 
+/*
+ * Read EEPROM data from ah_eepromdata
+ */
+HAL_BOOL __ahdecl ath_hal_EepromDataRead(struct ath_hal *ah,
+		u_int off, uint16_t *data);
+
 #endif /* _ATH_AH_H_ */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c
--- a/head/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c	Mon Jan 16 14:38:30 2012 +0200
@@ -15,7 +15,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $FreeBSD: head/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c 226488 2011-10-18 03:01:41Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c 230147 2012-01-15 19:22:34Z adrian $
  */
 #include "opt_ah.h"
 
@@ -119,11 +119,11 @@
 
 	/*
 	 * Use the "local" EEPROM data given to us by the higher layers.
-	 * This is a private copy out of system flash. The Linux ath9k
-	 * commit for the initial AR9130 support mentions MMIO flash
-	 * access is "unreliable." -adrian
+	 * This is a private copy out of system flash.
+	 * By this stage the SoC SPI flash may have disabled the memory-
+	 * mapping and rely purely on port-based SPI IO.
 	 */
-	AH_PRIVATE((ah))->ah_eepromRead = ar9130EepromRead;
+	AH_PRIVATE((ah))->ah_eepromRead = ath_hal_EepromDataRead;
 	AH_PRIVATE((ah))->ah_eepromWrite = NULL;
 	ah->ah_eepromdata = eepromdata;
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ath/ath_hal/ar9001/ar9130_eeprom.c
--- a/head/sys/dev/ath/ath_hal/ar9001/ar9130_eeprom.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ath/ath_hal/ar9001/ar9130_eeprom.c	Mon Jan 16 14:38:30 2012 +0200
@@ -14,30 +14,5 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $FreeBSD: head/sys/dev/ath/ath_hal/ar9001/ar9130_eeprom.c 221163 2011-04-28 12:47:40Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_hal/ar9001/ar9130_eeprom.c 230147 2012-01-15 19:22:34Z adrian $
  */
-#include "opt_ah.h"
-
-#include "ah.h"
-#include "ah_internal.h"
-
-#include "ar9001/ar9130_eeprom.h"
-
-/* XXX this shouldn't be done here */
-/* This is in 16 bit words; not bytes -adrian */
-#define ATH_DATA_EEPROM_SIZE    2048
-
-HAL_BOOL
-ar9130EepromRead(struct ath_hal *ah, u_int off, uint16_t *data)
-{
-	if (ah->ah_eepromdata == AH_NULL) {
-		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: no eeprom data!\n", __func__);
-		return AH_FALSE;
-	}
-	if (off > ATH_DATA_EEPROM_SIZE) {
-		HALDEBUG(ah, HAL_DEBUG_ANY, "ar9130EepromRead: offset %x > %x\n", off, ATH_DATA_EEPROM_SIZE);
-		return AH_FALSE;
-	}
-	(*data) = ah->ah_eepromdata[off];
-	return AH_TRUE;
-}
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ath/ath_hal/ar9001/ar9130_eeprom.h
--- a/head/sys/dev/ath/ath_hal/ar9001/ar9130_eeprom.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ath/ath_hal/ar9001/ar9130_eeprom.h	Mon Jan 16 14:38:30 2012 +0200
@@ -14,11 +14,9 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $FreeBSD: head/sys/dev/ath/ath_hal/ar9001/ar9130_eeprom.h 221163 2011-04-28 12:47:40Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_hal/ar9001/ar9130_eeprom.h 230147 2012-01-15 19:22:34Z adrian $
  */
 #ifndef	__AR9130_EEPROM_H__
 #define	__AR9130_EEPROM_H__
 
-extern	HAL_BOOL ar9130EepromRead(struct ath_hal *ah, u_int off, uint16_t *data);
-
 #endif
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
--- a/head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c	Mon Jan 16 14:38:30 2012 +0200
@@ -14,7 +14,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $FreeBSD: head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c 227373 2011-11-09 04:38:27Z adrian $
+ * $FreeBSD: head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c 230147 2012-01-15 19:22:34Z adrian $
  */
 #include "opt_ah.h"
 
@@ -169,6 +169,19 @@
 
 	ar5416InitState(AH5416(ah), devid, sc, st, sh, status);
 
+
+	/*
+	 * Use the "local" EEPROM data given to us by the higher layers.
+	 * This is a private copy out of system flash. The Linux ath9k
+	 * commit for the initial AR9130 support mentions MMIO flash
+	 * access is "unreliable." -adrian
+	 */
+	if (eepromdata != AH_NULL) {
+		AH_PRIVATE((ah))->ah_eepromRead = ath_hal_EepromDataRead;
+		AH_PRIVATE((ah))->ah_eepromWrite = NULL;
+		ah->ah_eepromdata = eepromdata;
+	}
+
 	/* XXX override with 9280 specific state */
 	/* override 5416 methods for our needs */
 	AH5416(ah)->ah_initPLL = ar9280InitPLL;
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/bxe/bxe_hsi.h
--- a/head/sys/dev/bxe/bxe_hsi.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/bxe/bxe_hsi.h	Mon Jan 16 14:38:30 2012 +0200
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
- /*$FreeBSD$*/
+ /*$FreeBSD: head/sys/dev/bxe/bxe_hsi.h 230133 2012-01-15 13:23:33Z uqs $*/
 
 struct license_key {
 	uint32_t reserved[6];
@@ -282,7 +282,7 @@
 	 * 4 times 16 bits for all 4 lanes. In case external PHY is present
 	 * (not direct mode), those values will not take effect on the 4 XGXS
 	 * lanes. For some external PHYs (such as 8706 and 8726) the values
-	 * will be used to configure the external PHY – in those cases, not
+	 * will be used to configure the external PHY -- in those cases, not
 	 * all 4 values are needed.
 	 */
 	uint16_t xgxs_config_rx[4];			/* 0x198 */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/e1000/if_em.c
--- a/head/sys/dev/e1000/if_em.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/e1000/if_em.c	Mon Jan 16 14:38:30 2012 +0200
@@ -30,7 +30,7 @@
   POSSIBILITY OF SUCH DAMAGE.
 
 ******************************************************************************/
-/*$FreeBSD: head/sys/dev/e1000/if_em.c 229939 2012-01-10 19:57:23Z luigi $*/
+/*$FreeBSD: head/sys/dev/e1000/if_em.c 230024 2012-01-12 17:30:44Z luigi $*/
 
 #ifdef HAVE_KERNEL_OPTION_HEADERS
 #include "opt_device_polling.h"
@@ -4019,6 +4019,10 @@
 	struct em_buffer	*rxbuf;
 	bus_dma_segment_t	seg[1];
 	int			rsize, nsegs, error;
+#ifdef DEV_NETMAP
+	struct netmap_adapter *na = NA(adapter->ifp);
+	struct netmap_slot *slot;
+#endif
 
 
 	/* Clear the ring contents */
@@ -4026,6 +4030,9 @@
 	rsize = roundup2(adapter->num_rx_desc *
 	    sizeof(struct e1000_rx_desc), EM_DBA_ALIGN);
 	bzero((void *)rxr->rx_base, rsize);
+#ifdef DEV_NETMAP
+	slot = netmap_reset(na, NR_RX, 0, 0);
+#endif
 
 	/*
 	** Free current RX buffer structs and their mbufs
@@ -4037,12 +4044,29 @@
 			    BUS_DMASYNC_POSTREAD);
 			bus_dmamap_unload(rxr->rxtag, rxbuf->map);
 			m_freem(rxbuf->m_head);
+			rxbuf->m_head = NULL; /* mark as freed */
 		}
 	}
 
 	/* Now replenish the mbufs */
         for (int j = 0; j != adapter->num_rx_desc; ++j) {
 		rxbuf = &rxr->rx_buffers[j];
+#ifdef DEV_NETMAP
+		if (slot) {
+			/* slot si is mapped to the j-th NIC-ring entry */
+			int si = j + na->rx_rings[0].nkr_hwofs;
+			uint64_t paddr;
+			void *addr;
+
+			if (si > na->num_rx_desc)
+				si -= na->num_rx_desc;
+			addr = PNMB(slot + si, &paddr);
+			netmap_load_map(rxr->rxtag, rxbuf->map, addr);
+			/* Update descriptor */
+			rxr->rx_base[j].buffer_addr = htole64(paddr);
+			continue;
+		}
+#endif /* DEV_NETMAP */
 		rxbuf->m_head = m_getjcl(M_DONTWAIT, MT_DATA,
 		    M_PKTHDR, adapter->rx_mbuf_sz);
 		if (rxbuf->m_head == NULL) {
@@ -4073,63 +4097,6 @@
 	bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
-#ifdef DEV_NETMAP
-    {
-	/*
-	 * This driver is slightly different from the standard:
-	 * it refills the rings in blocks of 8, so the while()
-	 * above completes any leftover work. Also, after if_init()
-	 * the ring starts at rxr->next_to_check instead of 0.
-	 *
-	 * Currently: we leave the mbufs allocated even in netmap
-	 * mode, and simply make the NIC ring point to the
-	 * correct buffer (netmap_buf or mbuf) depending on
-	 * the mode. To avoid mbuf leaks, when in netmap mode we
-	 * must make sure that next_to_refresh == next_to_check - 1
-	 * so that the above while() loop is never run on init.
-	 *
-	 * A better way would be to free the mbufs when entering
-	 * netmap mode, and set next_to_refresh/check in
-	 * a way that the mbufs are completely reallocated
-	 * when going back to standard mode.
-	 */
-	struct netmap_adapter *na = NA(adapter->ifp);
-	struct netmap_slot *slot = netmap_reset(na,
-		NR_RX, rxr->me, rxr->next_to_check);
-	int sj = slot ? na->rx_rings[rxr->me].nkr_hwofs : 0;
-
-	/* slot sj corresponds to entry j in the NIC ring */
-	if (sj < 0)
-		sj += adapter->num_rx_desc;
-
-	for (int j = 0; j != adapter->num_rx_desc; j++, sj++) {
-		rxbuf = &rxr->rx_buffers[j];
-		/* no mbuf and regular mode -> skip this entry */
-		if (rxbuf->m_head == NULL && !slot)
-			continue;
-		/* Handle wrap. Cannot use "na" here, could be NULL */
-		if (sj >= adapter->num_rx_desc)
-			sj -= adapter->num_rx_desc;
-		/* see comment, set slot addr and map */
-		if (slot) {
-			uint64_t paddr;
-			void *addr = PNMB(slot + sj, &paddr);
-			netmap_load_map(rxr->rxtag, rxbuf->map, addr);
-			/* Update descriptor */
-			rxr->rx_base[j].buffer_addr = htole64(paddr);
-		} else {
-			/* Get the memory mapping */
-			bus_dmamap_load_mbuf_sg(rxr->rxtag,
-			    rxbuf->map, rxbuf->m_head, seg,
-			    &nsegs, BUS_DMA_NOWAIT);
-			/* Update descriptor */
-			rxr->rx_base[j].buffer_addr = htole64(seg[0].ds_addr);
-		}
-		bus_dmamap_sync(rxr->rxtag, rxbuf->map, BUS_DMASYNC_PREREAD);
-	}
-    }
-#endif /* DEV_NETMAP */
-
 fail:
 	EM_RX_UNLOCK(rxr);
 	return (error);
@@ -4313,21 +4280,18 @@
 		E1000_WRITE_REG(hw, E1000_RDBAL(i), (u32)bus_addr);
 		/* Setup the Head and Tail Descriptor Pointers */
 		E1000_WRITE_REG(hw, E1000_RDH(i), 0);
-		E1000_WRITE_REG(hw, E1000_RDT(i), adapter->num_rx_desc - 1);
 #ifdef DEV_NETMAP
 		/*
 		 * an init() while a netmap client is active must
 		 * preserve the rx buffers passed to userspace.
 		 * In this driver it means we adjust RDT to
-		 * something different from next_to_refresh.
+		 * something different from na->num_rx_desc - 1.
 		 */
 		if (ifp->if_capenable & IFCAP_NETMAP) {
 			struct netmap_adapter *na = NA(adapter->ifp);
 			struct netmap_kring *kring = &na->rx_rings[i];
-			int t = rxr->next_to_refresh - kring->nr_hwavail;
-
-			if (t < 0)
-				t += na->num_rx_desc;
+			int t = na->num_rx_desc - 1 - kring->nr_hwavail;
+
 			E1000_WRITE_REG(hw, E1000_RDT(i), t);
 		} else
 #endif /* DEV_NETMAP */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ex/if_ex.c
--- a/head/sys/dev/ex/if_ex.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ex/if_ex.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1996, Javier Martín Rueda (jmrueda at diatel.upm.es)
+ * Copyright (c) 1996, Javier Martín Rueda (jmrueda at diatel.upm.es)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/ex/if_ex.c 229767 2012-01-07 09:41:57Z kevlo $");
+__FBSDID("$FreeBSD: head/sys/dev/ex/if_ex.c 230132 2012-01-15 13:23:18Z uqs $");
 
 /*
  * Intel EtherExpress Pro/10, Pro/10+ Ethernet driver
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ex/if_exreg.h
--- a/head/sys/dev/ex/if_exreg.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ex/if_exreg.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1996, Javier Martín Rueda (jmrueda at diatel.upm.es)
+ * Copyright (c) 1996, Javier Martín Rueda (jmrueda at diatel.upm.es)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/ex/if_exreg.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 /*
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/fb/boot_font.c
--- a/head/sys/dev/fb/boot_font.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/fb/boot_font.c	Mon Jan 16 14:38:30 2012 +0200
@@ -34,14 +34,14 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 /*-
- * This font lives in the public domain. It is a PC font, IBM encoding,
- * which was designed for use with syscons.
+ * This font lives in the public domain. It is a PC font, IBM encoding
+ * (CP437), which was designed for use with syscons.
  *
  * Copyright (c) 2000 Andrew Miklic
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/fb/boot_font.c 230134 2012-01-15 13:23:43Z uqs $");
 
 #include <sys/param.h>
 
@@ -2931,7 +2931,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/*   */
+	/* á */
 	0x00, 	/* ........ */
 	0x06, 	/* .....**. */
 	0x0c, 	/* ....**.. */
@@ -2949,7 +2949,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ¡ */
+	/* í */
 	0x00, 	/* ........ */
 	0x06, 	/* .....**. */
 	0x0c, 	/* ....**.. */
@@ -2967,7 +2967,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ¢ */
+	/* ó */
 	0x00, 	/* ........ */
 	0x06, 	/* .....**. */
 	0x0c, 	/* ....**.. */
@@ -2985,7 +2985,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* £ */
+	/* ú */
 	0x00, 	/* ........ */
 	0x0c, 	/* ....**.. */
 	0x18, 	/* ...**... */
@@ -3003,7 +3003,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ¤ */
+	/* ñ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x76, 	/* .***.**. */
@@ -3021,7 +3021,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ¥ */
+	/* Ñ */
 	0x76, 	/* .***.**. */
 	0xdc, 	/* **.***.. */
 	0x00, 	/* ........ */
@@ -3039,7 +3039,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ¦ */
+	/* ª */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x7c, 	/* .*****.. */
@@ -3057,7 +3057,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* § */
+	/* º */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x7c, 	/* .*****.. */
@@ -3075,7 +3075,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ¨ */
+	/* ¿ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x18, 	/* ...**... */
@@ -3093,7 +3093,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* © */
+	/* ⌐ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3111,7 +3111,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ª */
+	/* ¬ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3129,7 +3129,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* « */
+	/* ½ */
 	0x00, 	/* ........ */
 	0x18, 	/* ...**... */
 	0x38, 	/* ..***... */
@@ -3147,7 +3147,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ¬ */
+	/* ¼ */
 	0x00, 	/* ........ */
 	0x18, 	/* ...**... */
 	0x38, 	/* ..***... */
@@ -3165,25 +3165,25 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ­ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x18, 	/* ...**... */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-
-	/* ® */
+	/* ¡ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x18, 	/* ...**... */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+
+	/* « */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3201,7 +3201,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ¯ */
+	/* » */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3219,7 +3219,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ° */
+	/* â–‘ */
 	0x82, 	/* *.....*. */
 	0x10, 	/* ...*.... */
 	0x82, 	/* *.....*. */
@@ -3237,7 +3237,7 @@
 	0x82, 	/* *.....*. */
 	0x10, 	/* ...*.... */
 
-	/* ± */
+	/* â–’ */
 	0x00, 	/* ........ */
 	0x95, 	/* *..*.*.* */
 	0x00, 	/* ........ */
@@ -3255,7 +3255,7 @@
 	0x00, 	/* ........ */
 	0xa9, 	/* *.*.*..* */
 
-	/* ² */
+	/* â–“ */
 	0x92, 	/* *..*..*. */
 	0x49, 	/* .*..*..* */
 	0x92, 	/* *..*..*. */
@@ -3273,25 +3273,25 @@
 	0x92, 	/* *..*..*. */
 	0x49, 	/* .*..*..* */
 
-	/* ³ */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-
-	/* ´ */
+	/* │ */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+
+	/* ┤ */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
@@ -3309,7 +3309,7 @@
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 
-	/* µ */
+	/* â•¡ */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
@@ -3327,7 +3327,7 @@
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 
-	/* ¶ */
+	/* â•¢ */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
@@ -3345,7 +3345,7 @@
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 
-	/* · */
+	/* â•– */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3363,7 +3363,7 @@
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 
-	/* ¸ */
+	/* â•• */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3381,7 +3381,7 @@
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 
-	/* ¹ */
+	/* â•£ */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
@@ -3399,25 +3399,25 @@
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 
-	/* º */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-	0x3c, 	/* ..****.. */
-
-	/* » */
+	/* â•‘ */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+	0x3c, 	/* ..****.. */
+
+	/* â•— */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3435,7 +3435,7 @@
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 
-	/* ¼ */
+	/* ╝ */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
@@ -3453,7 +3453,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ½ */
+	/* ╜ */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
@@ -3471,7 +3471,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ¾ */
+	/* â•› */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
@@ -3489,7 +3489,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ¿ */
+	/* ┐ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3507,7 +3507,7 @@
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 
-	/* À */
+	/* â”” */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
@@ -3525,7 +3525,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* Á */
+	/* â”´ */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
@@ -3543,7 +3543,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* Â */
+	/* ┬ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3561,7 +3561,7 @@
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 
-	/* Ã */
+	/* ├ */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
@@ -3579,7 +3579,7 @@
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 
-	/* Ä */
+	/* ─ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3597,7 +3597,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* Å */
+	/* ┼ */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
@@ -3615,7 +3615,7 @@
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 
-	/* Æ */
+	/* â•ž */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
@@ -3633,7 +3633,7 @@
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 
-	/* Ç */
+	/* â•Ÿ */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
@@ -3651,7 +3651,7 @@
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 
-	/* È */
+	/* â•š */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
@@ -3669,7 +3669,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* É */
+	/* â•” */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3687,7 +3687,7 @@
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 
-	/* Ê */
+	/* â•© */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
@@ -3705,7 +3705,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* Ë */
+	/* ╦ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3723,7 +3723,7 @@
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 
-	/* Ì */
+	/* â•  */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
@@ -3741,7 +3741,7 @@
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 
-	/* Í */
+	/* ═ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3759,7 +3759,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* Î */
+	/* ╬ */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
@@ -3777,7 +3777,7 @@
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 
-	/* Ï */
+	/* ╧ */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
@@ -3795,7 +3795,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* Ð */
+	/* ╨ */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
@@ -3813,7 +3813,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* Ñ */
+	/* ╤ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3831,7 +3831,7 @@
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 
-	/* Ò */
+	/* â•¥ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3849,7 +3849,7 @@
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 
-	/* Ó */
+	/* â•™ */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
@@ -3867,7 +3867,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* Ô */
+	/* ╘ */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
@@ -3885,7 +3885,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* Õ */
+	/* â•’ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3903,7 +3903,7 @@
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 
-	/* Ö */
+	/* â•“ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3921,7 +3921,7 @@
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 
-	/* × */
+	/* â•« */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
@@ -3939,7 +3939,7 @@
 	0x3c, 	/* ..****.. */
 	0x3c, 	/* ..****.. */
 
-	/* Ø */
+	/* ╪ */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
@@ -3957,7 +3957,7 @@
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 
-	/* Ù */
+	/* ┘ */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
@@ -3975,7 +3975,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* Ú */
+	/* ┌ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -3993,7 +3993,7 @@
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 
-	/* Û */
+	/* â–ˆ */
 	0xff, 	/* ******** */
 	0xff, 	/* ******** */
 	0xff, 	/* ******** */
@@ -4011,7 +4011,7 @@
 	0xff, 	/* ******** */
 	0xff, 	/* ******** */
 
-	/* Ü */
+	/* â–„ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4029,7 +4029,7 @@
 	0xff, 	/* ******** */
 	0xff, 	/* ******** */
 
-	/* Ý */
+	/* ▌ */
 	0xf0, 	/* ****.... */
 	0xf0, 	/* ****.... */
 	0xf0, 	/* ****.... */
@@ -4047,7 +4047,7 @@
 	0xf0, 	/* ****.... */
 	0xf0, 	/* ****.... */
 
-	/* Þ */
+	/* ▐ */
 	0x0f, 	/* ....**** */
 	0x0f, 	/* ....**** */
 	0x0f, 	/* ....**** */
@@ -4065,7 +4065,7 @@
 	0x0f, 	/* ....**** */
 	0x0f, 	/* ....**** */
 
-	/* ß */
+	/* â–€ */
 	0xff, 	/* ******** */
 	0xff, 	/* ******** */
 	0xff, 	/* ******** */
@@ -4083,7 +4083,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* à */
+	/* α */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4101,7 +4101,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* á */
+	/* ß */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x7c, 	/* .*****.. */
@@ -4119,7 +4119,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* â */
+	/* Γ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0xfe, 	/* *******. */
@@ -4137,7 +4137,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ã */
+	/* π */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4155,7 +4155,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ä */
+	/* Σ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0xfe, 	/* *******. */
@@ -4173,7 +4173,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* å */
+	/* σ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4191,7 +4191,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* æ */
+	/* µ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4209,7 +4209,7 @@
 	0xc0, 	/* **...... */
 	0x00, 	/* ........ */
 
-	/* ç */
+	/* Ï„ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4227,7 +4227,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* è */
+	/* Φ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x18, 	/* ...**... */
@@ -4245,7 +4245,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* é */
+	/* Θ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x38, 	/* ..***... */
@@ -4263,7 +4263,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ê */
+	/* Ω */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x3c, 	/* ..****.. */
@@ -4281,7 +4281,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ë */
+	/* δ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x1e, 	/* ...****. */
@@ -4299,7 +4299,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ì */
+	/* ∞ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4317,7 +4317,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* í */
+	/* φ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4335,7 +4335,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* î */
+	/* ε */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x1c, 	/* ...***.. */
@@ -4353,7 +4353,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ï */
+	/* ∩ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4371,7 +4371,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ð */
+	/* ≡ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4389,7 +4389,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ñ */
+	/* ± */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4407,7 +4407,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ò */
+	/* ≥ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4425,7 +4425,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ó */
+	/* ≤ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4443,7 +4443,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ô */
+	/* ⌠ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4461,7 +4461,7 @@
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 
-	/* õ */
+	/* ⌡ */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
 	0x18, 	/* ...**... */
@@ -4479,7 +4479,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ö */
+	/* ÷ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4497,7 +4497,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ÷ */
+	/* ≈ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
@@ -4515,7 +4515,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ø */
+	/* ° */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x38, 	/* ..***... */
@@ -4533,43 +4533,43 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ù */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x18, 	/* ...**... */
-	0x18, 	/* ...**... */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-
-	/* ú */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x18, 	/* ...**... */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-	0x00, 	/* ........ */
-
-	/* û */
+	/* ∙ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x18, 	/* ...**... */
+	0x18, 	/* ...**... */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+
+	/* · */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x18, 	/* ...**... */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+	0x00, 	/* ........ */
+
+	/* √ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x03, 	/* ......** */
@@ -4587,7 +4587,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ü */
+	/* ⁿ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0xd8, 	/* **.**... */
@@ -4605,7 +4605,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* ý */
+	/* ² */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x78, 	/* .****... */
@@ -4623,7 +4623,7 @@
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 
-	/* þ */
+	/* â–  */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
 	0x00, 	/* ........ */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/fb/splash_pcx.c
--- a/head/sys/dev/fb/splash_pcx.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/fb/splash_pcx.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,7 +1,7 @@
 /*-
  * Copyright (c) 1999 Michael Smith <msmith at freebsd.org>
  * Copyright (c) 1999 Kazutaka YOKOTA <yokota at freebsd.org>
- * Copyright (c) 1999 Dag-Erling Coïdan Smørgrav
+ * Copyright (c) 1999 Dag-Erling Coïdan Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/fb/splash_pcx.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/fb/vga.c
--- a/head/sys/dev/fb/vga.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/fb/vga.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 1999 Kazutaka YOKOTA <yokota at zodiac.mech.utsunomiya-u.ac.jp>
- * Copyright (c) 1992-1998 Søren Schmidt
+ * Copyright (c) 1992-1998 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/fb/vga.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_vga.h"
 #include "opt_fb.h"
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/hpt27xx/README
--- a/head/sys/dev/hpt27xx/README	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/hpt27xx/README	Mon Jan 16 14:38:30 2012 +0200
@@ -154,7 +154,7 @@
         /kernel text=0x24f1db data=0x3007ec+0x2062c -
         
         Hit [Enter] to boot immediagely, or any other key for command prompt.
-        Booting [kernel] in 9 seconds¡­
+        Booting [kernel] in 9 seconds
         
          <-- press SPACE key here 
         Type '?' for a list of commands, 'help' for more detailed help.
@@ -193,4 +193,4 @@
         (http://www.highpoint-tech.com) to check if there is a new or 
         updated device driver for your system.
 
-$FreeBSD: head/sys/dev/hpt27xx/README 228940 2011-12-28 23:26:58Z delphij $
+$FreeBSD: head/sys/dev/hpt27xx/README 230133 2012-01-15 13:23:33Z uqs $
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/hptmv/readme.txt
--- a/head/sys/dev/hptmv/readme.txt	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/hptmv/readme.txt	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 RocketRAID 18xx Driver for FreeBSD
 Copyright (C) 2007-2008 HighPoint Technologies, Inc. All rights reserved.
-$FreeBSD$
+$FreeBSD: head/sys/dev/hptmv/readme.txt 230133 2012-01-15 13:23:33Z uqs $
 
 #############################################################################
 Revision History:
@@ -184,7 +184,7 @@
         /kernel text=0x24f1db data=0x3007ec+0x2062c -
         
         Hit [Enter] to boot immediagely, or any other key for command prompt.
-        Booting [kernel] in 9 seconds¡­
+        Booting [kernel] in 9 seconds
         
          <-- press SPACE key here 
         Type '?' for a list of commands, 'help' for more detailed help.
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/hwpmc/hwpmc_uncore.c
--- a/head/sys/dev/hwpmc/hwpmc_uncore.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/hwpmc/hwpmc_uncore.c	Mon Jan 16 14:38:30 2012 +0200
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_uncore.c 229469 2012-01-04 07:33:06Z fabient $");
+__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_uncore.c 230063 2012-01-13 17:13:46Z gnn $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -974,26 +974,18 @@
 	/* Event specific configuration. */
 	switch (pm->pm_event) {
 	case PMC_EV_UCP_EVENT_0CH_04H_E:
+	case PMC_EV_UCP_EVENT_0CH_08H_E:
 		wrmsr(MSR_GQ_SNOOP_MESF,0x2);
 		break;
 	case PMC_EV_UCP_EVENT_0CH_04H_F:
+	case PMC_EV_UCP_EVENT_0CH_08H_F:
 		wrmsr(MSR_GQ_SNOOP_MESF,0x8);
 		break;
 	case PMC_EV_UCP_EVENT_0CH_04H_M:
+	case PMC_EV_UCP_EVENT_0CH_08H_M:
 		wrmsr(MSR_GQ_SNOOP_MESF,0x1);
 		break;
 	case PMC_EV_UCP_EVENT_0CH_04H_S:
-		wrmsr(MSR_GQ_SNOOP_MESF,0x4);
-		break;
-	case PMC_EV_UCP_EVENT_0CH_08H_E:
-		wrmsr(MSR_GQ_SNOOP_MESF,0x2);
-		break;
-	case PMC_EV_UCP_EVENT_0CH_08H_F:
-		wrmsr(MSR_GQ_SNOOP_MESF,0x8);
-		break;	
-	case PMC_EV_UCP_EVENT_0CH_08H_M:
-		wrmsr(MSR_GQ_SNOOP_MESF,0x1);
-		break;
 	case PMC_EV_UCP_EVENT_0CH_08H_S:
 		wrmsr(MSR_GQ_SNOOP_MESF,0x4);
 		break;
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/hwpmc/hwpmc_uncore.h
--- a/head/sys/dev/hwpmc/hwpmc_uncore.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/hwpmc/hwpmc_uncore.h	Mon Jan 16 14:38:30 2012 +0200
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/dev/hwpmc/hwpmc_uncore.h 229469 2012-01-04 07:33:06Z fabient $
+ * $FreeBSD: head/sys/dev/hwpmc/hwpmc_uncore.h 230063 2012-01-13 17:13:46Z gnn $
  */
 
 #ifndef _DEV_HWPMC_UNCORE_H_
@@ -87,7 +87,6 @@
 #define	UC_GLOBAL_CTRL				0x391
 #define	UC_GLOBAL_OVF_CTRL			0x393
 
-
 #define	UC_GLOBAL_STATUS_FLAG_CLRCHG		(1ULL << 63)
 #define	UC_GLOBAL_STATUS_FLAG_OVFPMI		(1ULL << 61)
 #define	UC_GLOBAL_CTRL_FLAG_FRZ			(1ULL << 63)
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ieee488/ibfoo.c
--- a/head/sys/dev/ieee488/ibfoo.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ieee488/ibfoo.c	Mon Jan 16 14:38:30 2012 +0200
@@ -24,12 +24,12 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * High-level driver for µPD7210 based GPIB cards.
+ * High-level driver for µPD7210 based GPIB cards.
  *
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/ieee488/ibfoo.c 230134 2012-01-15 13:23:43Z uqs $");
 
 #  define	IBDEBUG
 #  undef	IBDEBUG
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ieee488/pcii.c
--- a/head/sys/dev/ieee488/pcii.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ieee488/pcii.c	Mon Jan 16 14:38:30 2012 +0200
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * Driver for GPIB cards based on NEC µPD7210 and compatibles.
+ * Driver for GPIB cards based on NEC µPD7210 and compatibles.
  *
  * This driver just hooks up to the hardware and leaves all the interesting
  * stuff to upd7210.c.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/ieee488/pcii.c 230134 2012-01-15 13:23:43Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -116,14 +116,14 @@
 	/*
 	 * The PCIIA decodes a fixed pattern of 0x2e1 for the lower 10
 	 * address bits A0 ... A9.  Bits A10 through A12 are used by
-	 * the µPD7210 register select lines.  This makes the
+	 * the µPD7210 register select lines.  This makes the
 	 * individual 7210 register being 0x400 bytes apart in the ISA
 	 * bus address space.  Address bits A13 and A14 are compared
 	 * to a DIP switch setting on the card, allowing for up to 4
 	 * different cards being installed (at base addresses 0x2e1,
 	 * 0x22e1, 0x42e1, and 0x62e1, respectively).  A15 has been
 	 * used to select an optional on-board time-of-day clock chip
-	 * (MM58167A) on the original PCIIA rather than the µPD7210
+	 * (MM58167A) on the original PCIIA rather than the µPD7210
 	 * (which is not implemented on later boards).  The
 	 * documentation states the respective addresses for that chip
 	 * should be handled as reserved addresses, which we don't do
@@ -174,7 +174,7 @@
 	}
 	error = ENXIO;
 	/*
-	 * Perform some basic tests on the µPD7210 registers.  At
+	 * Perform some basic tests on the µPD7210 registers.  At
 	 * least *some* register must read different from 0x00 or
 	 * 0xff.
 	 */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ieee488/upd7210.c
--- a/head/sys/dev/ieee488/upd7210.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ieee488/upd7210.c	Mon Jan 16 14:38:30 2012 +0200
@@ -24,12 +24,12 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * High-level driver for µPD7210 based GPIB cards.
+ * High-level driver for µPD7210 based GPIB cards.
  *
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/ieee488/upd7210.c 230134 2012-01-15 13:23:43Z uqs $");
 
 #  define	GPIB_DEBUG
 #  undef	GPIB_DEBUG
@@ -252,7 +252,7 @@
 		bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */
 		bus_write_1(u->reg_res[0], imr3, 0x04); /* NEF IE */
 	} else {
-		/* µPD7210/NAT7210, or TNT4882 in non-FIFO mode */
+		/* µPD7210/NAT7210, or TNT4882 in non-FIFO mode */
 		upd7210_wr(u, IMR1, 0x01); /* data in interrupt enable */
 	}
 	return (0);
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/ieee488/upd7210.h
--- a/head/sys/dev/ieee488/upd7210.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/ieee488/upd7210.h	Mon Jan 16 14:38:30 2012 +0200
@@ -24,15 +24,15 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/ieee488/upd7210.h 230134 2012-01-15 13:23:43Z uqs $
  *
- * Locating an actual µPD7210 data book has proven quite impossible for me.
- * There are a fair number of newer chips which are supersets of the µPD7210
+ * Locating an actual µPD7210 data book has proven quite impossible for me.
+ * There are a fair number of newer chips which are supersets of the µPD7210
  * but they are particular eager to comprehensively mark what the extensions
  * are and what is in the base set.  Some even give the registers and their
  * bits new names.
  *
- * The following information is based on a description of the µPD7210 found
+ * The following information is based on a description of the µPD7210 found
  * in an old manual for a VME board which used the chip.
  */
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/netmap/if_re_netmap.h
--- a/head/sys/dev/netmap/if_re_netmap.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/netmap/if_re_netmap.h	Mon Jan 16 14:38:30 2012 +0200
@@ -24,8 +24,8 @@
  */
 
 /*
- * $FreeBSD: head/sys/dev/netmap/if_re_netmap.h 229939 2012-01-10 19:57:23Z luigi $
- * $Id: if_re_netmap.h 9802 2011-12-02 18:42:37Z luigi $
+ * $FreeBSD: head/sys/dev/netmap/if_re_netmap.h 230055 2012-01-13 11:01:23Z luigi $
+ * $Id: if_re_netmap.h 10075 2011-12-25 22:55:48Z luigi $
  *
  * netmap support for if_re
  */
@@ -409,7 +409,7 @@
 		addr = PNMB(slot + l, &paddr);
 
 		netmap_reload_map(sc->rl_ldata.rl_rx_mtag,
-			sc->rl_ldata.rl_rx_desc[i].rx_dmamap, addr);
+		    sc->rl_ldata.rl_rx_desc[i].rx_dmamap, addr);
 		bus_dmamap_sync(sc->rl_ldata.rl_rx_mtag,
 		    sc->rl_ldata.rl_rx_desc[i].rx_dmamap, BUS_DMASYNC_PREREAD);
 		desc[i].rl_bufaddr_lo = htole32(RL_ADDR_LO(paddr));
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/netmap/netmap.c
--- a/head/sys/dev/netmap/netmap.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/netmap/netmap.c	Mon Jan 16 14:38:30 2012 +0200
@@ -24,7 +24,7 @@
  */
 
 /*
- * $FreeBSD: head/sys/dev/netmap/netmap.c 229947 2012-01-10 23:02:01Z luigi $
+ * $FreeBSD: head/sys/dev/netmap/netmap.c 230058 2012-01-13 11:58:06Z luigi $
  * $Id: netmap.c 9795 2011-12-02 11:39:08Z luigi $
  *
  * This module supports memory mapped access to network devices,
@@ -56,7 +56,7 @@
  */
 
 #include <sys/cdefs.h> /* prerequisite */
-__FBSDID("$FreeBSD: head/sys/dev/netmap/netmap.c 229947 2012-01-10 23:02:01Z luigi $");
+__FBSDID("$FreeBSD: head/sys/dev/netmap/netmap.c 230058 2012-01-13 11:58:06Z luigi $");
 
 #include <sys/types.h>
 #include <sys/module.h>
@@ -426,7 +426,6 @@
 }
 
 
-
 /*
  * Create and return a new ``netmap_if`` object, and possibly also
  * rings and packet buffors.
@@ -1057,6 +1056,7 @@
 	struct netmap_kring *kring;
 	u_int core_lock, i, check_all, want_tx, want_rx, revents = 0;
 	void *adapter;
+	enum {NO_CL, NEED_CL, LOCKED_CL }; /* see below */
 
 	if (devfs_get_cdevpriv((void **)&priv) != 0 || priv == NULL)
 		return POLLERR;
@@ -1131,8 +1131,7 @@
 	 *		to remember to release the lock once done.
 	 * LOCKED_CL	core lock is set, so we need to release it.
 	 */
-	enum {NO_CL, NEED_CL, LOCKED_CL };
-	core_lock = (check_all || !na->separate_locks) ?  NEED_CL:NO_CL;
+	core_lock = (check_all || !na->separate_locks) ? NEED_CL : NO_CL;
 	/*
 	 * We start with a lock free round which is good if we have
 	 * data available. If this fails, then lock and call the sync
@@ -1393,30 +1392,6 @@
 	return kring->ring->slot;
 }
 
-static void
-ns_dmamap_cb(__unused void *arg, __unused bus_dma_segment_t * segs,
-	__unused int nseg, __unused int error)
-{
-}
-
-/* unload a bus_dmamap and create a new one. Used when the
- * buffer in the slot is changed.
- * XXX buflen is probably not needed, buffers have constant size.
- */
-void
-netmap_reload_map(bus_dma_tag_t tag, bus_dmamap_t map, void *buf)
-{
-	bus_dmamap_unload(tag, map);
-	bus_dmamap_load(tag, map, buf, NETMAP_BUF_SIZE, ns_dmamap_cb,
-		NULL, BUS_DMA_NOWAIT);
-}
-
-void
-netmap_load_map(bus_dma_tag_t tag, bus_dmamap_t map, void *buf)
-{
-	bus_dmamap_load(tag, map, buf, NETMAP_BUF_SIZE, ns_dmamap_cb,
-		NULL, BUS_DMA_NOWAIT);
-}
 
 /*------ netmap memory allocator -------*/
 /*
@@ -1541,7 +1516,7 @@
 	int i, n, sz = NETMAP_MEMORY_SIZE;
 	int extra_sz = 0; // space for rings and two spare buffers
 
-	for (; !buf && sz >= 1<<20; sz >>=1) {
+	for (; sz >= 1<<20; sz >>=1) {
 		extra_sz = sz/200;
 		extra_sz = (extra_sz + 2*PAGE_SIZE - 1) & ~(PAGE_SIZE-1);
 	        buf = contigmalloc(sz + extra_sz,
@@ -1552,6 +1527,8 @@
 			     PAGE_SIZE, /* alignment */
 			     0 /* boundary */
 			    );
+		if (buf)
+			break;
 	} 
 	if (buf == NULL)
 		return (ENOMEM);
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/netmap/netmap_kern.h
--- a/head/sys/dev/netmap/netmap_kern.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/netmap/netmap_kern.h	Mon Jan 16 14:38:30 2012 +0200
@@ -24,7 +24,7 @@
  */
 
 /*
- * $FreeBSD: head/sys/dev/netmap/netmap_kern.h 229939 2012-01-10 19:57:23Z luigi $
+ * $FreeBSD: head/sys/dev/netmap/netmap_kern.h 230058 2012-01-13 11:58:06Z luigi $
  * $Id: netmap_kern.h 9795 2011-12-02 11:39:08Z luigi $
  *
  * The header contains the definitions of constants and function
@@ -39,13 +39,13 @@
 #endif
 
 #define ND(format, ...)
-#define D(format, ...)					\
-	do {						\
-		struct timeval __xxts;			\
+#define D(format, ...)						\
+	do {							\
+		struct timeval __xxts;				\
 		microtime(&__xxts);				\
-		printf("%03d.%06d %s [%d] " format "\n",\
-		(int)__xxts.tv_sec % 1000, (int)__xxts.tv_usec,		\
-		__FUNCTION__, __LINE__, ##__VA_ARGS__);	\
+		printf("%03d.%06d %s [%d] " format "\n",	\
+		(int)__xxts.tv_sec % 1000, (int)__xxts.tv_usec,	\
+		__FUNCTION__, __LINE__, ##__VA_ARGS__);		\
 	} while (0)
  
 struct netmap_adapter;
@@ -169,16 +169,8 @@
 enum txrx { NR_RX = 0, NR_TX = 1 };
 struct netmap_slot *netmap_reset(struct netmap_adapter *na,
 	enum txrx tx, int n, u_int new_cur);
-void netmap_load_map(bus_dma_tag_t tag, bus_dmamap_t map, void *buf);
-void netmap_reload_map(bus_dma_tag_t tag, bus_dmamap_t map, void *buf);
 int netmap_ring_reinit(struct netmap_kring *);
 
-/*
- * XXX eventually, get rid of netmap_total_buffers and netmap_buffer_base
- * in favour of the structure
- */
-// struct netmap_buf_pool;
-// extern struct netmap_buf_pool nm_buf_pool;
 extern u_int netmap_total_buffers;
 extern char *netmap_buffer_base;
 extern int netmap_verbose;	// XXX debugging
@@ -203,10 +195,38 @@
 #define	NA(_ifp)	((struct netmap_adapter *)WNA(_ifp))
 
 
+/* Callback invoked by the dma machinery after a successfull dmamap_load */
+static void netmap_dmamap_cb(__unused void *arg,
+    __unused bus_dma_segment_t * segs, __unused int nseg, __unused int error)
+{
+}
+
+/* bus_dmamap_load wrapper: call aforementioned function if map != NULL.
+ * XXX can we do it without a callback ?
+ */
+static inline void
+netmap_load_map(bus_dma_tag_t tag, bus_dmamap_t map, void *buf)
+{
+	if (map)
+		bus_dmamap_load(tag, map, buf, NETMAP_BUF_SIZE,
+		    netmap_dmamap_cb, NULL, BUS_DMA_NOWAIT);
+}
+
+/* update the map when a buffer changes. */
+static inline void
+netmap_reload_map(bus_dma_tag_t tag, bus_dmamap_t map, void *buf)
+{
+	if (map) {
+		bus_dmamap_unload(tag, map);
+		bus_dmamap_load(tag, map, buf, NETMAP_BUF_SIZE,
+		    netmap_dmamap_cb, NULL, BUS_DMA_NOWAIT);
+	}
+}
+
+
 /*
  * NMB return the virtual address of a buffer (buffer 0 on bad index)
  * PNMB also fills the physical address
- * XXX this is a special version with hardwired 2k bufs
  */
 static inline void *
 NMB(struct netmap_slot *slot)
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/nxge/include/xgehal-channel.h
--- a/head/sys/dev/nxge/include/xgehal-channel.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/nxge/include/xgehal-channel.h	Mon Jan 16 14:38:30 2012 +0200
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/nxge/include/xgehal-channel.h 230133 2012-01-15 13:23:33Z uqs $
  */
 
 #ifndef XGE_HAL_CHANNEL_H
@@ -139,7 +139,7 @@
  * Channel callback gets called by HAL if, and only if, there is at least
  * one new completion on a given ring or fifo channel. Upon processing the
  * first @dtrh ULD is _supposed_ to continue consuming completions
- * usingáone of the following HAL APIs:
+ * using one of the following HAL APIs:
  *    - xge_hal_fifo_dtr_next_completed()
  *      or
  *    - xge_hal_ring_dtr_next_completed().
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/nxge/include/xgehal-config.h
--- a/head/sys/dev/nxge/include/xgehal-config.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/nxge/include/xgehal-config.h	Mon Jan 16 14:38:30 2012 +0200
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/nxge/include/xgehal-config.h 230134 2012-01-15 13:23:43Z uqs $
  */
 
 #ifndef XGE_HAL_CONFIG_H
@@ -621,7 +621,7 @@
  * stable in order for the adapter to declare "LINK UP".
  * The enumerated settings (see Xframe-II UG) are:
  *      0 ........... instantaneous
- *      1 ........... 500 ³s
+ *      1 ........... 500 μs
  *      2 ........... 1 ms
  *      3 ........... 64 ms
  *      4 ........... 256 ms
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/nxge/xgehal/xgehal-fifo-fp.c
--- a/head/sys/dev/nxge/xgehal/xgehal-fifo-fp.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/nxge/xgehal/xgehal-fifo-fp.c	Mon Jan 16 14:38:30 2012 +0200
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/nxge/xgehal/xgehal-fifo-fp.c 230133 2012-01-15 13:23:33Z uqs $
  */
 
 #ifdef XGE_DEBUG_FP
@@ -794,7 +794,7 @@
  * in fifo descriptor.
  * @channelh: Channel handle.
  * @dtrh: Descriptor handle.
- * @frag_idx: Index of the data buffer in the caller's scatter-gather listá
+ * @frag_idx: Index of the data buffer in the caller's scatter-gather list
  *            (of buffers).
  * @vaddr: Virtual address of the data buffer.
  * @dma_pointer: DMA address of the data buffer referenced by @frag_idx.
@@ -1015,7 +1015,7 @@
  * descriptor.
  * @channelh: Channel handle.
  * @dtrh: Descriptor handle.
- * @frag_idx: Index of the data buffer in the caller's scatter-gather listá
+ * @frag_idx: Index of the data buffer in the caller's scatter-gather list
  *            (of buffers).
  * @dma_pointer: DMA address of the data buffer referenced by @frag_idx.
  * @size: Size of the data buffer (in bytes).
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/pst/pst-iop.c
--- a/head/sys/dev/pst/pst-iop.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/pst/pst-iop.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2001,2002,2003 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 2001,2002,2003 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/pst/pst-iop.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/pst/pst-iop.h
--- a/head/sys/dev/pst/pst-iop.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/pst/pst-iop.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2001,2002,2003 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 2001,2002,2003 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/pst/pst-iop.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 /* misc defines */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/pst/pst-pci.c
--- a/head/sys/dev/pst/pst-pci.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/pst/pst-pci.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2001,2002,2003 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 2001,2002,2003 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/pst/pst-pci.c 229984 2012-01-11 21:38:05Z truckman $");
+__FBSDID("$FreeBSD: head/sys/dev/pst/pst-pci.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/pst/pst-raid.c
--- a/head/sys/dev/pst/pst-raid.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/pst/pst-raid.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2001,2002,2003 Søren Schmidt <sos at FreeBSD.org>
+ * Copyright (c) 2001,2002,2003 Søren Schmidt <sos at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/pst/pst-raid.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/sound/pci/ds1-fw.h
--- a/head/sys/dev/sound/pci/ds1-fw.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/sound/pci/ds1-fw.h	Mon Jan 16 14:38:30 2012 +0200
@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/sound/pci/ds1-fw.h 230133 2012-01-15 13:23:33Z uqs $
  */
 #ifndef _HWMCODE_
 #define _HWMCODE_
@@ -822,9 +822,9 @@
 	1999/06/21
 	Buf441 slot is Enabled.
    --------------------------------------------
-   04/09@creat
+   04/09  @creat
    04/12  stop nise fix
-   06/21@WorkingOff timming
+   06/21  @WorkingOff timming
 */
 
 static u_int32_t	CntrlInst1E[] = {
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/sound/pci/emu10kx.c
--- a/head/sys/dev/sound/pci/emu10kx.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/sound/pci/emu10kx.c	Mon Jan 16 14:38:30 2012 +0200
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/dev/sound/pci/emu10kx.c 229981 2012-01-11 21:17:14Z pfg $
+ * $FreeBSD: head/sys/dev/sound/pci/emu10kx.c 230137 2012-01-15 13:36:47Z joel $
  */
 
 #include <sys/param.h>
@@ -158,7 +158,7 @@
 #define	OUT_ADC_REC	OUT_ADC_REC_L
 #define	OUT_MIC_CAP	0x0c
 
-/* Live! 5.1 Digital, non-standart 5.1 (center & sub) outputs */
+/* Live! 5.1 Digital, non-standard 5.1 (center & sub) outputs */
 #define	OUT_A_CENTER	0x11
 #define	OUT_A_SUB	0x12
 
@@ -806,7 +806,7 @@
 
 
 /*
- * emu_timer_ - HW timer managment
+ * emu_timer_ - HW timer management
  */
 int
 emu_timer_create(struct emu_sc_info *sc)
@@ -913,7 +913,7 @@
 }
 
 /*
- * emu_intr_ - HW interrupt handler managment
+ * emu_intr_ - HW interrupt handler management
  */
 int
 emu_intr_register(struct emu_sc_info *sc, uint32_t inte_mask, uint32_t intr_mask, uint32_t(*func) (void *softc, uint32_t irq), void *isc)
@@ -1012,7 +1012,7 @@
 			if (sc->dbg_level > 1)
 				device_printf(sc->dev, "EMU_IPR2: %08x\n", stat);
 
-			break;	/* to avoid infinite loop. shoud be removed
+			break;	/* to avoid infinite loop. should be removed
 				 * after completion of P16V interface. */
 		}
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/sound/pci/hda/hda_reg.h
--- a/head/sys/dev/sound/pci/hda/hda_reg.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/sound/pci/hda/hda_reg.h	Mon Jan 16 14:38:30 2012 +0200
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/sound/pci/hda/hda_reg.h 230130 2012-01-15 13:21:36Z mav $
  */
 
 #ifndef _HDA_REG_H_
@@ -400,7 +400,7 @@
     HDA_CMD_GET_UNSOLICITED_RESPONSE_TAG_SHIFT)
 
 #define HDA_CMD_SET_UNSOLICITED_RESPONSE_ENABLE		0x80
-#define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_MASK	0x1f
+#define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_MASK	0x3f
 #define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_SHIFT	0
 
 #define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG(param)			\
@@ -418,14 +418,10 @@
     (HDA_CMD_12BIT((cad), (nid),					\
     HDA_CMD_VERB_SET_PIN_SENSE, (payload)))
 
-#define HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT_MASK	0x80000000
-#define HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT_SHIFT	31
+#define HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT		0x80000000
 #define HDA_CMD_GET_PIN_SENSE_IMP_SENSE_MASK		0x7fffffff
 #define HDA_CMD_GET_PIN_SENSE_IMP_SENSE_SHIFT		0
 
-#define HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT(rsp)			\
-    (((rsp) & HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT_MASK) >>		\
-    HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT_SHIFT)
 #define HDA_CMD_GET_PIN_SENSE_IMP_SENSE(rsp)				\
     (((rsp) & HDA_CMD_GET_PIN_SENSE_IMP_SENSE_MASK) >>			\
     HDA_CMD_GET_PIN_SENSE_IMP_SENSE_SHIFT)
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/sound/pci/hda/hdaa.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/sound/pci/hda/hdaa.c	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,5903 @@
+/*-
+ * Copyright (c) 2006 Stephane E. Potvin <sepotvin at videotron.ca>
+ * Copyright (c) 2006 Ariff Abdullah <ariff at FreeBSD.org>
+ * Copyright (c) 2008-2012 Alexander Motin <mav at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Intel High Definition Audio (Audio function) driver for FreeBSD.
+ */
+
+#ifdef HAVE_KERNEL_OPTION_HEADERS
+#include "opt_snd.h"
+#endif
+
+#include <dev/sound/pcm/sound.h>
+
+#include <sys/ctype.h>
+#include <sys/taskqueue.h>
+
+#include <dev/sound/pci/hda/hdac.h>
+#include <dev/sound/pci/hda/hdaa.h>
+#include <dev/sound/pci/hda/hda_reg.h>
+
+#include "mixer_if.h"
+
+SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hda/hdaa.c 230181 2012-01-16 00:26:52Z mav $");
+
+#define hdaa_lock(devinfo)	snd_mtxlock((devinfo)->lock)
+#define hdaa_unlock(devinfo)	snd_mtxunlock((devinfo)->lock)
+#define hdaa_lockassert(devinfo) snd_mtxassert((devinfo)->lock)
+#define hdaa_lockowned(devinfo)	mtx_owned((devinfo)->lock)
+
+static const struct {
+	char *key;
+	uint32_t value;
+} hdaa_quirks_tab[] = {
+	{ "softpcmvol", HDAA_QUIRK_SOFTPCMVOL },
+	{ "fixedrate", HDAA_QUIRK_FIXEDRATE },
+	{ "forcestereo", HDAA_QUIRK_FORCESTEREO },
+	{ "eapdinv", HDAA_QUIRK_EAPDINV },
+	{ "senseinv", HDAA_QUIRK_SENSEINV },
+	{ "ivref50", HDAA_QUIRK_IVREF50 },
+	{ "ivref80", HDAA_QUIRK_IVREF80 },
+	{ "ivref100", HDAA_QUIRK_IVREF100 },
+	{ "ovref50", HDAA_QUIRK_OVREF50 },
+	{ "ovref80", HDAA_QUIRK_OVREF80 },
+	{ "ovref100", HDAA_QUIRK_OVREF100 },
+	{ "ivref", HDAA_QUIRK_IVREF },
+	{ "ovref", HDAA_QUIRK_OVREF },
+	{ "vref", HDAA_QUIRK_VREF },
+};
+#define HDAA_QUIRKS_TAB_LEN	\
+		(sizeof(hdaa_quirks_tab) / sizeof(hdaa_quirks_tab[0]))
+
+#define HDA_BDL_MIN	2
+#define HDA_BDL_MAX	256
+#define HDA_BDL_DEFAULT	HDA_BDL_MIN
+
+#define HDA_BLK_MIN	HDA_DMA_ALIGNMENT
+#define HDA_BLK_ALIGN	(~(HDA_BLK_MIN - 1))
+
+#define HDA_BUFSZ_MIN		4096
+#define HDA_BUFSZ_MAX		65536
+#define HDA_BUFSZ_DEFAULT	16384
+
+#define HDA_PARSE_MAXDEPTH	10
+
+MALLOC_DEFINE(M_HDAA, "hdaa", "HDA Audio");
+
+const char *HDA_COLORS[16] = {"Unknown", "Black", "Grey", "Blue", "Green", "Red",
+    "Orange", "Yellow", "Purple", "Pink", "Res.A", "Res.B", "Res.C", "Res.D",
+    "White", "Other"};
+
+const char *HDA_DEVS[16] = {"Line-out", "Speaker", "Headphones", "CD",
+    "SPDIF-out", "Digital-out", "Modem-line", "Modem-handset", "Line-in",
+    "AUX", "Mic", "Telephony", "SPDIF-in", "Digital-in", "Res.E", "Other"};
+
+const char *HDA_CONNS[4] = {"Jack", "None", "Fixed", "Both"};
+
+const char *HDA_CONNECTORS[16] = {
+    "Unknown", "1/8", "1/4", "ATAPI", "RCA", "Optical", "Digital", "Analog",
+    "DIN", "XLR", "RJ-11", "Combo", "0xc", "0xd", "0xe", "Other" };
+
+const char *HDA_LOCS[64] = {
+    "0x00", "Rear", "Front", "Left", "Right", "Top", "Bottom", "Rear-panel",
+	"Drive-bay", "0x09", "0x0a", "0x0b", "0x0c", "0x0d", "0x0e", "0x0f",
+    "Internal", "0x11", "0x12", "0x13", "0x14", "0x15", "0x16", "Riser",
+	"0x18", "Onboard", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f",
+    "External", "Ext-Rear", "Ext-Front", "Ext-Left", "Ext-Right", "Ext-Top", "Ext-Bottom", "0x07",
+	"0x28", "0x29", "0x2a", "0x2b", "0x2c", "0x2d", "0x2e", "0x2f",
+    "Other", "0x31", "0x32", "0x33", "0x34", "0x35", "Other-Bott", "Lid-In",
+	"Lid-Out", "0x39", "0x3a", "0x3b", "0x3c", "0x3d", "0x3e", "0x3f" };
+
+const char *HDA_GPIO_ACTIONS[8] = {
+    "keep", "set", "clear", "disable", "input", "0x05", "0x06", "0x07"};
+
+/* Default */
+static uint32_t hdaa_fmt[] = {
+	SND_FORMAT(AFMT_S16_LE, 2, 0),
+	0
+};
+
+static struct pcmchan_caps hdaa_caps = {48000, 48000, hdaa_fmt, 0};
+
+static const struct {
+	uint32_t	rate;
+	int		valid;
+	uint16_t	base;
+	uint16_t	mul;
+	uint16_t	div;
+} hda_rate_tab[] = {
+	{   8000, 1, 0x0000, 0x0000, 0x0500 },	/* (48000 * 1) / 6 */
+	{   9600, 0, 0x0000, 0x0000, 0x0400 },	/* (48000 * 1) / 5 */
+	{  12000, 0, 0x0000, 0x0000, 0x0300 },	/* (48000 * 1) / 4 */
+	{  16000, 1, 0x0000, 0x0000, 0x0200 },	/* (48000 * 1) / 3 */
+	{  18000, 0, 0x0000, 0x1000, 0x0700 },	/* (48000 * 3) / 8 */
+	{  19200, 0, 0x0000, 0x0800, 0x0400 },	/* (48000 * 2) / 5 */
+	{  24000, 0, 0x0000, 0x0000, 0x0100 },	/* (48000 * 1) / 2 */
+	{  28800, 0, 0x0000, 0x1000, 0x0400 },	/* (48000 * 3) / 5 */
+	{  32000, 1, 0x0000, 0x0800, 0x0200 },	/* (48000 * 2) / 3 */
+	{  36000, 0, 0x0000, 0x1000, 0x0300 },	/* (48000 * 3) / 4 */
+	{  38400, 0, 0x0000, 0x1800, 0x0400 },	/* (48000 * 4) / 5 */
+	{  48000, 1, 0x0000, 0x0000, 0x0000 },	/* (48000 * 1) / 1 */
+	{  64000, 0, 0x0000, 0x1800, 0x0200 },	/* (48000 * 4) / 3 */
+	{  72000, 0, 0x0000, 0x1000, 0x0100 },	/* (48000 * 3) / 2 */
+	{  96000, 1, 0x0000, 0x0800, 0x0000 },	/* (48000 * 2) / 1 */
+	{ 144000, 0, 0x0000, 0x1000, 0x0000 },	/* (48000 * 3) / 1 */
+	{ 192000, 1, 0x0000, 0x1800, 0x0000 },	/* (48000 * 4) / 1 */
+	{   8820, 0, 0x4000, 0x0000, 0x0400 },	/* (44100 * 1) / 5 */
+	{  11025, 1, 0x4000, 0x0000, 0x0300 },	/* (44100 * 1) / 4 */
+	{  12600, 0, 0x4000, 0x0800, 0x0600 },	/* (44100 * 2) / 7 */
+	{  14700, 0, 0x4000, 0x0000, 0x0200 },	/* (44100 * 1) / 3 */
+	{  17640, 0, 0x4000, 0x0800, 0x0400 },	/* (44100 * 2) / 5 */
+	{  18900, 0, 0x4000, 0x1000, 0x0600 },	/* (44100 * 3) / 7 */
+	{  22050, 1, 0x4000, 0x0000, 0x0100 },	/* (44100 * 1) / 2 */
+	{  25200, 0, 0x4000, 0x1800, 0x0600 },	/* (44100 * 4) / 7 */
+	{  26460, 0, 0x4000, 0x1000, 0x0400 },	/* (44100 * 3) / 5 */
+	{  29400, 0, 0x4000, 0x0800, 0x0200 },	/* (44100 * 2) / 3 */
+	{  33075, 0, 0x4000, 0x1000, 0x0300 },	/* (44100 * 3) / 4 */
+	{  35280, 0, 0x4000, 0x1800, 0x0400 },	/* (44100 * 4) / 5 */
+	{  44100, 1, 0x4000, 0x0000, 0x0000 },	/* (44100 * 1) / 1 */
+	{  58800, 0, 0x4000, 0x1800, 0x0200 },	/* (44100 * 4) / 3 */
+	{  66150, 0, 0x4000, 0x1000, 0x0100 },	/* (44100 * 3) / 2 */
+	{  88200, 1, 0x4000, 0x0800, 0x0000 },	/* (44100 * 2) / 1 */
+	{ 132300, 0, 0x4000, 0x1000, 0x0000 },	/* (44100 * 3) / 1 */
+	{ 176400, 1, 0x4000, 0x1800, 0x0000 },	/* (44100 * 4) / 1 */
+};
+#define HDA_RATE_TAB_LEN (sizeof(hda_rate_tab) / sizeof(hda_rate_tab[0]))
+
+/****************************************************************************
+ * Function prototypes
+ ****************************************************************************/
+static int	hdaa_pcmchannel_setup(struct hdaa_chan *);
+
+static void	hdaa_widget_connection_select(struct hdaa_widget *, uint8_t);
+static void	hdaa_audio_ctl_amp_set(struct hdaa_audio_ctl *,
+						uint32_t, int, int);
+static struct	hdaa_audio_ctl *hdaa_audio_ctl_amp_get(struct hdaa_devinfo *,
+							nid_t, int, int, int);
+static void	hdaa_audio_ctl_amp_set_internal(struct hdaa_devinfo *,
+				nid_t, int, int, int, int, int, int);
+
+static void	hdaa_dump_pin_config(struct hdaa_widget *w, uint32_t conf);
+
+static char *
+hdaa_audio_ctl_ossmixer_mask2allname(uint32_t mask, char *buf, size_t len)
+{
+	static char *ossname[] = SOUND_DEVICE_NAMES;
+	int i, first = 1;
+
+	bzero(buf, len);
+	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
+		if (mask & (1 << i)) {
+			if (first == 0)
+				strlcat(buf, ", ", len);
+			strlcat(buf, ossname[i], len);
+			first = 0;
+		}
+	}
+	return (buf);
+}
+
+static struct hdaa_audio_ctl *
+hdaa_audio_ctl_each(struct hdaa_devinfo *devinfo, int *index)
+{
+	if (devinfo == NULL ||
+	    index == NULL || devinfo->ctl == NULL ||
+	    devinfo->ctlcnt < 1 ||
+	    *index < 0 || *index >= devinfo->ctlcnt)
+		return (NULL);
+	return (&devinfo->ctl[(*index)++]);
+}
+
+static struct hdaa_audio_ctl *
+hdaa_audio_ctl_amp_get(struct hdaa_devinfo *devinfo, nid_t nid, int dir,
+						int index, int cnt)
+{
+	struct hdaa_audio_ctl *ctl;
+	int i, found = 0;
+
+	if (devinfo == NULL || devinfo->ctl == NULL)
+		return (NULL);
+
+	i = 0;
+	while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
+		if (ctl->enable == 0)
+			continue;
+		if (ctl->widget->nid != nid)
+			continue;
+		if (dir && ctl->ndir != dir)
+			continue;
+		if (index >= 0 && ctl->ndir == HDAA_CTL_IN &&
+		    ctl->dir == ctl->ndir && ctl->index != index)
+			continue;
+		found++;
+		if (found == cnt || cnt <= 0)
+			return (ctl);
+	}
+
+	return (NULL);
+}
+
+/*
+ * Jack detection (Speaker/HP redirection) event handler.
+ */
+static void
+hdaa_hp_switch_handler(struct hdaa_devinfo *devinfo, int asid)
+{
+	struct hdaa_audio_as *as;
+	struct hdaa_widget *w;
+	struct hdaa_audio_ctl *ctl;
+	uint32_t val, res;
+	int j;
+
+	as = &devinfo->as[asid];
+	if (as->hpredir < 0)
+		return;
+
+	w = hdaa_widget_get(devinfo, as->pins[15]);
+	if (w == NULL || w->enable == 0 || w->type !=
+	    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+		return;
+
+	res = hda_command(devinfo->dev,
+	    HDA_CMD_GET_PIN_SENSE(0, as->pins[15]));
+
+	HDA_BOOTVERBOSE(
+		device_printf(devinfo->dev,
+		    "Pin sense: nid=%d sence=0x%08x",
+		    as->pins[15], res);
+	);
+
+	res = (res & HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT) != 0;
+	if (devinfo->quirks & HDAA_QUIRK_SENSEINV)
+		res ^= 1;
+
+	HDA_BOOTVERBOSE(
+		printf(" %sconnected\n", res == 0 ? "dis" : "");
+	);
+
+	/* (Un)Mute headphone pin. */
+	ctl = hdaa_audio_ctl_amp_get(devinfo,
+	    as->pins[15], HDAA_CTL_IN, -1, 1);
+	if (ctl != NULL && ctl->mute) {
+		/* If pin has muter - use it. */
+		val = (res != 0) ? 0 : 1;
+		if (val != ctl->forcemute) {
+			ctl->forcemute = val;
+			hdaa_audio_ctl_amp_set(ctl,
+			    HDAA_AMP_MUTE_DEFAULT,
+			    HDAA_AMP_VOL_DEFAULT, HDAA_AMP_VOL_DEFAULT);
+		}
+	} else {
+		/* If there is no muter - disable pin output. */
+		w = hdaa_widget_get(devinfo, as->pins[15]);
+		if (w != NULL && w->type ==
+		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
+			if (res != 0)
+				val = w->wclass.pin.ctrl |
+				    HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
+			else
+				val = w->wclass.pin.ctrl &
+				    ~HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
+			if (val != w->wclass.pin.ctrl) {
+				w->wclass.pin.ctrl = val;
+				hda_command(devinfo->dev,
+				    HDA_CMD_SET_PIN_WIDGET_CTRL(0,
+				    w->nid, w->wclass.pin.ctrl));
+			}
+		}
+	}
+	/* (Un)Mute other pins. */
+	for (j = 0; j < 15; j++) {
+		if (as->pins[j] <= 0)
+			continue;
+		ctl = hdaa_audio_ctl_amp_get(devinfo,
+		    as->pins[j], HDAA_CTL_IN, -1, 1);
+		if (ctl != NULL && ctl->mute) {
+			/* If pin has muter - use it. */
+			val = (res != 0) ? 1 : 0;
+			if (val == ctl->forcemute)
+				continue;
+			ctl->forcemute = val;
+			hdaa_audio_ctl_amp_set(ctl,
+			    HDAA_AMP_MUTE_DEFAULT,
+			    HDAA_AMP_VOL_DEFAULT, HDAA_AMP_VOL_DEFAULT);
+			continue;
+		}
+		/* If there is no muter - disable pin output. */
+		w = hdaa_widget_get(devinfo, as->pins[j]);
+		if (w != NULL && w->type ==
+		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
+			if (res != 0)
+				val = w->wclass.pin.ctrl &
+				    ~HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
+			else
+				val = w->wclass.pin.ctrl |
+				    HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
+			if (val != w->wclass.pin.ctrl) {
+				w->wclass.pin.ctrl = val;
+				hda_command(devinfo->dev,
+				    HDA_CMD_SET_PIN_WIDGET_CTRL(0,
+				    w->nid, w->wclass.pin.ctrl));
+			}
+		}
+	}
+}
+
+/*
+ * Callback for poll based jack detection.
+ */
+static void
+hdaa_jack_poll_callback(void *arg)
+{
+	struct hdaa_devinfo *devinfo = arg;
+	int i;
+
+	hdaa_lock(devinfo);
+	if (devinfo->poll_ival == 0) {
+		hdaa_unlock(devinfo);
+		return;
+	}
+	for (i = 0; i < devinfo->ascnt; i++) {
+		if (devinfo->as[i].hpredir < 0)
+			continue;
+		hdaa_hp_switch_handler(devinfo, i);
+	}
+	callout_reset(&devinfo->poll_jack, devinfo->poll_ival,
+	    hdaa_jack_poll_callback, devinfo);
+	hdaa_unlock(devinfo);
+}
+
+/*
+ * Jack detection initializer.
+ */
+static void
+hdaa_hp_switch_init(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_as *as = devinfo->as;
+        struct hdaa_widget *w;
+        int i, poll = 0;
+
+	for (i = 0; i < devinfo->ascnt; i++) {
+		if (as[i].hpredir < 0)
+			continue;
+
+		w = hdaa_widget_get(devinfo, as[i].pins[15]);
+		if (w == NULL || w->enable == 0 || w->type !=
+		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+			continue;
+		if (HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(w->wclass.pin.cap) == 0 ||
+		    (HDA_CONFIG_DEFAULTCONF_MISC(w->wclass.pin.config) & 1) != 0) {
+			device_printf(devinfo->dev,
+			    "No jack detection support at pin %d\n",
+			    as[i].pins[15]);
+			continue;
+		}
+		if (HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP(w->param.widget_cap)) {
+			as[i].unsol = HDAC_UNSOL_ALLOC(
+			    device_get_parent(devinfo->dev), devinfo->dev,
+			    w->nid);
+			hda_command(devinfo->dev,
+			    HDA_CMD_SET_UNSOLICITED_RESPONSE(0, w->nid,
+			    HDA_CMD_SET_UNSOLICITED_RESPONSE_ENABLE |
+			    as[i].unsol));
+		} else
+			poll = 1;
+		HDA_BOOTVERBOSE(
+			device_printf(devinfo->dev,
+			    "Headphones redirection "
+			    "for as=%d nid=%d using %s.\n",
+			    i, w->nid,
+			    (poll != 0) ? "polling" : "unsolicited responses");
+		);
+		hdaa_hp_switch_handler(devinfo, i);
+	}
+	if (poll) {
+		callout_reset(&devinfo->poll_jack, 1,
+		    hdaa_jack_poll_callback, devinfo);
+	}
+}
+
+static void
+hdaa_hp_switch_deinit(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_as *as = devinfo->as;
+        struct hdaa_widget *w;
+        int i;
+
+	for (i = 0; i < devinfo->ascnt; i++) {
+		if (as[i].unsol < 0)
+			continue;
+		w = hdaa_widget_get(devinfo, as[i].pins[15]);
+		if (w == NULL || w->enable == 0 || w->type !=
+		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+			continue;
+		hda_command(devinfo->dev,
+		    HDA_CMD_SET_UNSOLICITED_RESPONSE(0, w->nid, 0));
+		HDAC_UNSOL_FREE(
+		    device_get_parent(devinfo->dev), devinfo->dev,
+		    as[i].unsol);
+		as[i].unsol = -1;
+	}
+}
+
+uint32_t
+hdaa_widget_pin_patch(uint32_t config, const char *str)
+{
+	char buf[256];
+	char *key, *value, *rest, *bad;
+	int ival, i;
+
+	strlcpy(buf, str, sizeof(buf));
+	rest = buf;
+	while ((key = strsep(&rest, "=")) != NULL) {
+		value = strsep(&rest, " \t");
+		if (value == NULL)
+			break;
+		ival = strtol(value, &bad, 10);
+		if (strcmp(key, "seq") == 0) {
+			config &= ~HDA_CONFIG_DEFAULTCONF_SEQUENCE_MASK;
+			config |= ((ival << HDA_CONFIG_DEFAULTCONF_SEQUENCE_SHIFT) &
+			    HDA_CONFIG_DEFAULTCONF_SEQUENCE_MASK);
+		} else if (strcmp(key, "as") == 0) {
+			config &= ~HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK;
+			config |= ((ival << HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT) &
+			    HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK);
+		} else if (strcmp(key, "misc") == 0) {
+			config &= ~HDA_CONFIG_DEFAULTCONF_MISC_MASK;
+			config |= ((ival << HDA_CONFIG_DEFAULTCONF_MISC_SHIFT) &
+			    HDA_CONFIG_DEFAULTCONF_MISC_MASK);
+		} else if (strcmp(key, "color") == 0) {
+			config &= ~HDA_CONFIG_DEFAULTCONF_COLOR_MASK;
+			if (bad[0] == 0) {
+				config |= ((ival << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT) &
+				    HDA_CONFIG_DEFAULTCONF_COLOR_MASK);
+			};
+			for (i = 0; i < 16; i++) {
+				if (strcasecmp(HDA_COLORS[i], value) == 0) {
+					config |= (i << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT);
+					break;
+				}
+			}
+		} else if (strcmp(key, "ctype") == 0) {
+			config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_MASK;
+			if (bad[0] == 0) {
+			config |= ((ival << HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_SHIFT) &
+			    HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_MASK);
+			}
+			for (i = 0; i < 16; i++) {
+				if (strcasecmp(HDA_CONNECTORS[i], value) == 0) {
+					config |= (i << HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_SHIFT);
+					break;
+				}
+			}
+		} else if (strcmp(key, "device") == 0) {
+			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
+			if (bad[0] == 0) {
+				config |= ((ival << HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT) &
+				    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK);
+				continue;
+			};
+			for (i = 0; i < 16; i++) {
+				if (strcasecmp(HDA_DEVS[i], value) == 0) {
+					config |= (i << HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT);
+					break;
+				}
+			}
+		} else if (strcmp(key, "loc") == 0) {
+			config &= ~HDA_CONFIG_DEFAULTCONF_LOCATION_MASK;
+			if (bad[0] == 0) {
+				config |= ((ival << HDA_CONFIG_DEFAULTCONF_LOCATION_SHIFT) &
+				    HDA_CONFIG_DEFAULTCONF_LOCATION_MASK);
+				continue;
+			}
+			for (i = 0; i < 64; i++) {
+				if (strcasecmp(HDA_LOCS[i], value) == 0) {
+					config |= (i << HDA_CONFIG_DEFAULTCONF_LOCATION_SHIFT);
+					break;
+				}
+			}
+		} else if (strcmp(key, "conn") == 0) {
+			config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
+			if (bad[0] == 0) {
+				config |= ((ival << HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT) &
+				    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
+				continue;
+			};
+			for (i = 0; i < 4; i++) {
+				if (strcasecmp(HDA_CONNS[i], value) == 0) {
+					config |= (i << HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT);
+					break;
+				}
+			}
+		}
+	}
+	return (config);
+}
+
+uint32_t
+hdaa_gpio_patch(uint32_t gpio, const char *str)
+{
+	char buf[256];
+	char *key, *value, *rest;
+	int ikey, i;
+
+	strlcpy(buf, str, sizeof(buf));
+	rest = buf;
+	while ((key = strsep(&rest, "=")) != NULL) {
+		value = strsep(&rest, " \t");
+		if (value == NULL)
+			break;
+		ikey = strtol(key, NULL, 10);
+		if (ikey < 0 || ikey > 7)
+			continue;
+		for (i = 0; i < 7; i++) {
+			if (strcasecmp(HDA_GPIO_ACTIONS[i], value) == 0) {
+				gpio &= ~HDAA_GPIO_MASK(ikey);
+				gpio |= i << HDAA_GPIO_SHIFT(ikey);
+				break;
+			}
+		}
+	}
+	return (gpio);
+}
+
+static void
+hdaa_local_patch_pin(struct hdaa_widget *w)
+{
+	device_t dev = w->devinfo->dev;
+	const char *res = NULL;
+	uint32_t config, orig;
+	char buf[32];
+
+	config = orig = w->wclass.pin.config;
+	snprintf(buf, sizeof(buf), "cad%u.nid%u.config",
+	    hda_get_codec_id(dev), w->nid);
+	if (resource_string_value(device_get_name(
+	    device_get_parent(device_get_parent(dev))),
+	    device_get_unit(device_get_parent(device_get_parent(dev))),
+	    buf, &res) == 0) {
+		if (strncmp(res, "0x", 2) == 0) {
+			config = strtol(res + 2, NULL, 16);
+		} else {
+			config = hdaa_widget_pin_patch(config, res);
+		}
+	}
+	snprintf(buf, sizeof(buf), "nid%u.config", w->nid);
+	if (resource_string_value(device_get_name(dev), device_get_unit(dev),
+	    buf, &res) == 0) {
+		if (strncmp(res, "0x", 2) == 0) {
+			config = strtol(res + 2, NULL, 16);
+		} else {
+			config = hdaa_widget_pin_patch(config, res);
+		}
+	}
+	HDA_BOOTVERBOSE(
+		if (config != orig)
+			device_printf(w->devinfo->dev,
+			    "Patching pin config nid=%u 0x%08x -> 0x%08x\n",
+			    w->nid, orig, config);
+	);
+	w->wclass.pin.newconf = w->wclass.pin.config = config;
+}
+
+static int
+hdaa_sysctl_config(SYSCTL_HANDLER_ARGS)
+{
+	char buf[256];
+	int error;
+	uint32_t conf;
+
+	conf = *(uint32_t *)oidp->oid_arg1;
+	snprintf(buf, sizeof(buf), "0x%08x as=%d seq=%d "
+	    "device=%s conn=%s ctype=%s loc=%s color=%s misc=%d",
+	    conf,
+	    HDA_CONFIG_DEFAULTCONF_ASSOCIATION(conf),
+	    HDA_CONFIG_DEFAULTCONF_SEQUENCE(conf),
+	    HDA_DEVS[HDA_CONFIG_DEFAULTCONF_DEVICE(conf)],
+	    HDA_CONNS[HDA_CONFIG_DEFAULTCONF_CONNECTIVITY(conf)],
+	    HDA_CONNECTORS[HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE(conf)],
+	    HDA_LOCS[HDA_CONFIG_DEFAULTCONF_LOCATION(conf)],
+	    HDA_COLORS[HDA_CONFIG_DEFAULTCONF_COLOR(conf)],
+	    HDA_CONFIG_DEFAULTCONF_MISC(conf));
+	error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+	if (strncmp(buf, "0x", 2) == 0)
+		conf = strtol(buf + 2, NULL, 16);
+	else
+		conf = hdaa_widget_pin_patch(conf, buf);
+	*(uint32_t *)oidp->oid_arg1 = conf;
+	return (0);
+}
+
+static void
+hdaa_config_fetch(const char *str, uint32_t *on, uint32_t *off)
+{
+	int i = 0, j, k, len, inv;
+
+	for (;;) {
+		while (str[i] != '\0' &&
+		    (str[i] == ',' || isspace(str[i]) != 0))
+			i++;
+		if (str[i] == '\0')
+			return;
+		j = i;
+		while (str[j] != '\0' &&
+		    !(str[j] == ',' || isspace(str[j]) != 0))
+			j++;
+		len = j - i;
+		if (len > 2 && strncmp(str + i, "no", 2) == 0)
+			inv = 2;
+		else
+			inv = 0;
+		for (k = 0; len > inv && k < HDAA_QUIRKS_TAB_LEN; k++) {
+			if (strncmp(str + i + inv,
+			    hdaa_quirks_tab[k].key, len - inv) != 0)
+				continue;
+			if (len - inv != strlen(hdaa_quirks_tab[k].key))
+				continue;
+			if (inv == 0) {
+				*on |= hdaa_quirks_tab[k].value;
+				*off &= ~hdaa_quirks_tab[k].value;
+			} else {
+				*off |= hdaa_quirks_tab[k].value;
+				*on &= ~hdaa_quirks_tab[k].value;
+			}
+			break;
+		}
+		i = j;
+	}
+}
+
+static int
+hdaa_sysctl_quirks(SYSCTL_HANDLER_ARGS)
+{
+	char buf[256];
+	int error, n = 0, i;
+	uint32_t quirks, quirks_off;
+
+	quirks = *(uint32_t *)oidp->oid_arg1;
+	buf[0] = 0;
+	for (i = 0; i < HDAA_QUIRKS_TAB_LEN; i++) {
+		if ((quirks & hdaa_quirks_tab[i].value) != 0)
+			n += snprintf(buf + n, sizeof(buf) - n, "%s%s",
+			    n != 0 ? "," : "", hdaa_quirks_tab[i].key);
+	}
+	error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+	if (strncmp(buf, "0x", 2) == 0)
+		quirks = strtol(buf + 2, NULL, 16);
+	else {
+		quirks = 0;
+		hdaa_config_fetch(buf, &quirks, &quirks_off);
+	}
+	*(uint32_t *)oidp->oid_arg1 = quirks;
+	return (0);
+}
+
+static void
+hdaa_local_patch(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_widget *w;
+	const char *res = NULL;
+	uint32_t quirks_on = 0, quirks_off = 0, x;
+	int i;
+
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL)
+			continue;
+		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+			hdaa_local_patch_pin(w);
+	}
+
+	if (resource_string_value(device_get_name(devinfo->dev),
+	    device_get_unit(devinfo->dev), "config", &res) == 0) {
+		if (res != NULL && strlen(res) > 0)
+			hdaa_config_fetch(res, &quirks_on, &quirks_off);
+		devinfo->quirks |= quirks_on;
+		devinfo->quirks &= ~quirks_off;
+	}
+	if (devinfo->newquirks == -1)
+		devinfo->newquirks = devinfo->quirks;
+	else
+		devinfo->quirks = devinfo->newquirks;
+	HDA_BOOTHVERBOSE(
+		device_printf(devinfo->dev,
+		    "Config options: 0x%08x\n", devinfo->quirks);
+	);
+
+	if (resource_string_value(device_get_name(devinfo->dev),
+	    device_get_unit(devinfo->dev), "gpio_config", &res) == 0) {
+		if (strncmp(res, "0x", 2) == 0) {
+			devinfo->gpio = strtol(res + 2, NULL, 16);
+		} else {
+			devinfo->gpio = hdaa_gpio_patch(devinfo->gpio, res);
+		}
+	}
+	if (devinfo->newgpio == -1)
+		devinfo->newgpio = devinfo->gpio;
+	else
+		devinfo->gpio = devinfo->newgpio;
+	if (devinfo->newgpo == -1)
+		devinfo->newgpo = devinfo->gpo;
+	else
+		devinfo->gpo = devinfo->newgpo;
+	HDA_BOOTHVERBOSE(
+		device_printf(devinfo->dev, "GPIO config options:");
+		for (i = 0; i < 7; i++) {
+			x = (devinfo->gpio & HDAA_GPIO_MASK(i)) >> HDAA_GPIO_SHIFT(i);
+			if (x != 0)
+				printf(" %d=%s", i, HDA_GPIO_ACTIONS[x]);
+		}
+		printf("\n");
+	);
+}
+
+static void
+hdaa_widget_connection_parse(struct hdaa_widget *w)
+{
+	uint32_t res;
+	int i, j, max, ents, entnum;
+	nid_t nid = w->nid;
+	nid_t cnid, addcnid, prevcnid;
+
+	w->nconns = 0;
+
+	res = hda_command(w->devinfo->dev,
+	    HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_CONN_LIST_LENGTH));
+
+	ents = HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH(res);
+
+	if (ents < 1)
+		return;
+
+	entnum = HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM(res) ? 2 : 4;
+	max = (sizeof(w->conns) / sizeof(w->conns[0])) - 1;
+	prevcnid = 0;
+
+#define CONN_RMASK(e)		(1 << ((32 / (e)) - 1))
+#define CONN_NMASK(e)		(CONN_RMASK(e) - 1)
+#define CONN_RESVAL(r, e, n)	((r) >> ((32 / (e)) * (n)))
+#define CONN_RANGE(r, e, n)	(CONN_RESVAL(r, e, n) & CONN_RMASK(e))
+#define CONN_CNID(r, e, n)	(CONN_RESVAL(r, e, n) & CONN_NMASK(e))
+
+	for (i = 0; i < ents; i += entnum) {
+		res = hda_command(w->devinfo->dev,
+		    HDA_CMD_GET_CONN_LIST_ENTRY(0, nid, i));
+		for (j = 0; j < entnum; j++) {
+			cnid = CONN_CNID(res, entnum, j);
+			if (cnid == 0) {
+				if (w->nconns < ents)
+					device_printf(w->devinfo->dev,
+					    "WARNING: nid=%d has zero cnid "
+					    "entnum=%d j=%d index=%d "
+					    "entries=%d found=%d res=0x%08x\n",
+					    nid, entnum, j, i,
+					    ents, w->nconns, res);
+				else
+					goto getconns_out;
+			}
+			if (cnid < w->devinfo->startnode ||
+			    cnid >= w->devinfo->endnode) {
+				HDA_BOOTVERBOSE(
+					device_printf(w->devinfo->dev,
+					    "WARNING: nid=%d has cnid outside "
+					    "of the AFG range j=%d "
+					    "entnum=%d index=%d res=0x%08x\n",
+					    nid, j, entnum, i, res);
+				);
+			}
+			if (CONN_RANGE(res, entnum, j) == 0)
+				addcnid = cnid;
+			else if (prevcnid == 0 || prevcnid >= cnid) {
+				device_printf(w->devinfo->dev,
+				    "WARNING: Invalid child range "
+				    "nid=%d index=%d j=%d entnum=%d "
+				    "prevcnid=%d cnid=%d res=0x%08x\n",
+				    nid, i, j, entnum, prevcnid,
+				    cnid, res);
+				addcnid = cnid;
+			} else
+				addcnid = prevcnid + 1;
+			while (addcnid <= cnid) {
+				if (w->nconns > max) {
+					device_printf(w->devinfo->dev,
+					    "Adding %d (nid=%d): "
+					    "Max connection reached! max=%d\n",
+					    addcnid, nid, max + 1);
+					goto getconns_out;
+				}
+				w->connsenable[w->nconns] = 1;
+				w->conns[w->nconns++] = addcnid++;
+			}
+			prevcnid = cnid;
+		}
+	}
+
+getconns_out:
+	return;
+}
+
+static void
+hdaa_widget_parse(struct hdaa_widget *w)
+{
+	device_t dev = w->devinfo->dev;
+	uint32_t wcap, cap;
+	nid_t nid = w->nid;
+	char buf[64];
+
+	w->param.widget_cap = wcap = hda_command(dev,
+	    HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_AUDIO_WIDGET_CAP));
+	w->type = HDA_PARAM_AUDIO_WIDGET_CAP_TYPE(wcap);
+
+	hdaa_widget_connection_parse(w);
+
+	if (HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP(wcap)) {
+		if (HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR(wcap))
+			w->param.outamp_cap =
+			    hda_command(dev,
+			    HDA_CMD_GET_PARAMETER(0, nid,
+			    HDA_PARAM_OUTPUT_AMP_CAP));
+		else
+			w->param.outamp_cap =
+			    w->devinfo->outamp_cap;
+	} else
+		w->param.outamp_cap = 0;
+
+	if (HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP(wcap)) {
+		if (HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR(wcap))
+			w->param.inamp_cap =
+			    hda_command(dev,
+			    HDA_CMD_GET_PARAMETER(0, nid,
+			    HDA_PARAM_INPUT_AMP_CAP));
+		else
+			w->param.inamp_cap =
+			    w->devinfo->inamp_cap;
+	} else
+		w->param.inamp_cap = 0;
+
+	if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT ||
+	    w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) {
+		if (HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR(wcap)) {
+			cap = hda_command(dev,
+			    HDA_CMD_GET_PARAMETER(0, nid,
+			    HDA_PARAM_SUPP_STREAM_FORMATS));
+			w->param.supp_stream_formats = (cap != 0) ? cap :
+			    w->devinfo->supp_stream_formats;
+			cap = hda_command(dev,
+			    HDA_CMD_GET_PARAMETER(0, nid,
+			    HDA_PARAM_SUPP_PCM_SIZE_RATE));
+			w->param.supp_pcm_size_rate = (cap != 0) ? cap :
+			    w->devinfo->supp_pcm_size_rate;
+		} else {
+			w->param.supp_stream_formats =
+			    w->devinfo->supp_stream_formats;
+			w->param.supp_pcm_size_rate =
+			    w->devinfo->supp_pcm_size_rate;
+		}
+	} else {
+		w->param.supp_stream_formats = 0;
+		w->param.supp_pcm_size_rate = 0;
+	}
+
+	if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
+		w->wclass.pin.original = w->wclass.pin.newconf =
+		    w->wclass.pin.config = hda_command(dev,
+			HDA_CMD_GET_CONFIGURATION_DEFAULT(0, w->nid));
+		w->wclass.pin.cap = hda_command(dev,
+		    HDA_CMD_GET_PARAMETER(0, w->nid, HDA_PARAM_PIN_CAP));;
+		w->wclass.pin.ctrl = hda_command(dev,
+		    HDA_CMD_GET_PIN_WIDGET_CTRL(0, nid));
+		if (HDA_PARAM_PIN_CAP_EAPD_CAP(w->wclass.pin.cap)) {
+			w->param.eapdbtl = hda_command(dev,
+			    HDA_CMD_GET_EAPD_BTL_ENABLE(0, nid));
+			w->param.eapdbtl &= 0x7;
+			w->param.eapdbtl |= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
+		} else
+			w->param.eapdbtl = HDA_INVALID;
+
+		hdaa_unlock(w->devinfo);
+		snprintf(buf, sizeof(buf), "nid%d_config", w->nid);
+		SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+		    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+		    buf, CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE,
+		    &w->wclass.pin.newconf, sizeof(&w->wclass.pin.newconf),
+		    hdaa_sysctl_config, "A", "Current pin configuration");
+		snprintf(buf, sizeof(buf), "nid%d_original", w->nid);
+		SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+		    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+		    buf, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+		    &w->wclass.pin.original, sizeof(&w->wclass.pin.original),
+		    hdaa_sysctl_config, "A", "Original pin configuration");
+		hdaa_lock(w->devinfo);
+	}
+}
+
+static void
+hdaa_widget_postprocess(struct hdaa_widget *w)
+{
+	char *typestr;
+
+	w->type = HDA_PARAM_AUDIO_WIDGET_CAP_TYPE(w->param.widget_cap);
+	switch (w->type) {
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT:
+		typestr = "audio output";
+		break;
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT:
+		typestr = "audio input";
+		break;
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER:
+		typestr = "audio mixer";
+		break;
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR:
+		typestr = "audio selector";
+		break;
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
+		typestr = "pin";
+		break;
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_POWER_WIDGET:
+		typestr = "power widget";
+		break;
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VOLUME_WIDGET:
+		typestr = "volume widget";
+		break;
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET:
+		typestr = "beep widget";
+		break;
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VENDOR_WIDGET:
+		typestr = "vendor widget";
+		break;
+	default:
+		typestr = "unknown type";
+		break;
+	}
+	strlcpy(w->name, typestr, sizeof(w->name));
+
+	if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
+		uint32_t config;
+		const char *devstr;
+		int conn, color;
+
+		config = w->wclass.pin.config;
+		devstr = HDA_DEVS[(config & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) >>
+		    HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT];
+		conn = (config & HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) >>
+		    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT;
+		color = (config & HDA_CONFIG_DEFAULTCONF_COLOR_MASK) >>
+		    HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT;
+		strlcat(w->name, ": ", sizeof(w->name));
+		strlcat(w->name, devstr, sizeof(w->name));
+		strlcat(w->name, " (", sizeof(w->name));
+		if (conn == 0 && color != 0 && color != 15) {
+			strlcat(w->name, HDA_COLORS[color], sizeof(w->name));
+			strlcat(w->name, " ", sizeof(w->name));
+		}
+		strlcat(w->name, HDA_CONNS[conn], sizeof(w->name));
+		strlcat(w->name, ")", sizeof(w->name));
+	}
+}
+
+struct hdaa_widget *
+hdaa_widget_get(struct hdaa_devinfo *devinfo, nid_t nid)
+{
+	if (devinfo == NULL || devinfo->widget == NULL ||
+		    nid < devinfo->startnode || nid >= devinfo->endnode)
+		return (NULL);
+	return (&devinfo->widget[nid - devinfo->startnode]);
+}
+
+static void
+hdaa_audio_ctl_amp_set_internal(struct hdaa_devinfo *devinfo, nid_t nid,
+					int index, int lmute, int rmute,
+					int left, int right, int dir)
+{
+	uint16_t v = 0;
+
+	HDA_BOOTHVERBOSE(
+		device_printf(devinfo->dev,
+		    "Setting amplifier nid=%d index=%d %s mute=%d/%d vol=%d/%d\n",
+		    nid,index,dir ? "in" : "out",lmute,rmute,left,right);
+	);
+	if (left != right || lmute != rmute) {
+		v = (1 << (15 - dir)) | (1 << 13) | (index << 8) |
+		    (lmute << 7) | left;
+		hda_command(devinfo->dev,
+		    HDA_CMD_SET_AMP_GAIN_MUTE(0, nid, v));
+		v = (1 << (15 - dir)) | (1 << 12) | (index << 8) |
+		    (rmute << 7) | right;
+	} else
+		v = (1 << (15 - dir)) | (3 << 12) | (index << 8) |
+		    (lmute << 7) | left;
+
+	hda_command(devinfo->dev,
+	    HDA_CMD_SET_AMP_GAIN_MUTE(0, nid, v));
+}
+
+static void
+hdaa_audio_ctl_amp_set(struct hdaa_audio_ctl *ctl, uint32_t mute,
+						int left, int right)
+{
+	nid_t nid;
+	int lmute, rmute;
+
+	nid = ctl->widget->nid;
+
+	/* Save new values if valid. */
+	if (mute != HDAA_AMP_MUTE_DEFAULT)
+		ctl->muted = mute;
+	if (left != HDAA_AMP_VOL_DEFAULT)
+		ctl->left = left;
+	if (right != HDAA_AMP_VOL_DEFAULT)
+		ctl->right = right;
+	/* Prepare effective values */
+	if (ctl->forcemute) {
+		lmute = 1;
+		rmute = 1;
+		left = 0;
+		right = 0;
+	} else {
+		lmute = HDAA_AMP_LEFT_MUTED(ctl->muted);
+		rmute = HDAA_AMP_RIGHT_MUTED(ctl->muted);
+		left = ctl->left;
+		right = ctl->right;
+	}
+	/* Apply effective values */
+	if (ctl->dir & HDAA_CTL_OUT)
+		hdaa_audio_ctl_amp_set_internal(ctl->widget->devinfo, nid, ctl->index,
+		    lmute, rmute, left, right, 0);
+	if (ctl->dir & HDAA_CTL_IN)
+		hdaa_audio_ctl_amp_set_internal(ctl->widget->devinfo, nid, ctl->index,
+		    lmute, rmute, left, right, 1);
+}
+
+static void
+hdaa_widget_connection_select(struct hdaa_widget *w, uint8_t index)
+{
+	if (w == NULL || w->nconns < 1 || index > (w->nconns - 1))
+		return;
+	HDA_BOOTHVERBOSE(
+		device_printf(w->devinfo->dev,
+		    "Setting selector nid=%d index=%d\n", w->nid, index);
+	);
+	hda_command(w->devinfo->dev,
+	    HDA_CMD_SET_CONNECTION_SELECT_CONTROL(0, w->nid, index));
+	w->selconn = index;
+}
+
+/****************************************************************************
+ * Device Methods
+ ****************************************************************************/
+
+static void *
+hdaa_channel_init(kobj_t obj, void *data, struct snd_dbuf *b,
+					struct pcm_channel *c, int dir)
+{
+	struct hdaa_chan *ch = data;
+	struct hdaa_pcm_devinfo *pdevinfo = ch->pdevinfo;
+	struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
+
+	hdaa_lock(devinfo);
+	if (devinfo->quirks & HDAA_QUIRK_FIXEDRATE) {
+		ch->caps.minspeed = ch->caps.maxspeed = 48000;
+		ch->pcmrates[0] = 48000;
+		ch->pcmrates[1] = 0;
+	}
+	ch->dir = dir;
+	ch->b = b;
+	ch->c = c;
+	ch->blksz = pdevinfo->chan_size / pdevinfo->chan_blkcnt;
+	ch->blkcnt = pdevinfo->chan_blkcnt;
+	hdaa_unlock(devinfo);
+
+	if (sndbuf_alloc(ch->b, bus_get_dma_tag(devinfo->dev),
+	    hda_get_dma_nocache(devinfo->dev) ? BUS_DMA_NOCACHE : 0,
+	    pdevinfo->chan_size) != 0)
+		return (NULL);
+
+	return (ch);
+}
+
+static int
+hdaa_channel_setformat(kobj_t obj, void *data, uint32_t format)
+{
+	struct hdaa_chan *ch = data;
+	int i;
+
+	for (i = 0; ch->caps.fmtlist[i] != 0; i++) {
+		if (format == ch->caps.fmtlist[i]) {
+			ch->fmt = format;
+			return (0);
+		}
+	}
+
+	return (EINVAL);
+}
+
+static uint32_t
+hdaa_channel_setspeed(kobj_t obj, void *data, uint32_t speed)
+{
+	struct hdaa_chan *ch = data;
+	uint32_t spd = 0, threshold;
+	int i;
+
+	/* First look for equal or multiple frequency. */
+	for (i = 0; ch->pcmrates[i] != 0; i++) {
+		spd = ch->pcmrates[i];
+		if (speed != 0 && spd / speed * speed == spd) {
+			ch->spd = spd;
+			return (spd);
+		}
+	}
+	/* If no match, just find nearest. */
+	for (i = 0; ch->pcmrates[i] != 0; i++) {
+		spd = ch->pcmrates[i];
+		threshold = spd + ((ch->pcmrates[i + 1] != 0) ?
+		    ((ch->pcmrates[i + 1] - spd) >> 1) : 0);
+		if (speed < threshold)
+			break;
+	}
+	ch->spd = spd;
+	return (spd);
+}
+
+static uint16_t
+hdaa_stream_format(struct hdaa_chan *ch)
+{
+	int i;
+	uint16_t fmt;
+
+	fmt = 0;
+	if (ch->fmt & AFMT_S16_LE)
+		fmt |= ch->bit16 << 4;
+	else if (ch->fmt & AFMT_S32_LE)
+		fmt |= ch->bit32 << 4;
+	else
+		fmt |= 1 << 4;
+	for (i = 0; i < HDA_RATE_TAB_LEN; i++) {
+		if (hda_rate_tab[i].valid && ch->spd == hda_rate_tab[i].rate) {
+			fmt |= hda_rate_tab[i].base;
+			fmt |= hda_rate_tab[i].mul;
+			fmt |= hda_rate_tab[i].div;
+			break;
+		}
+	}
+	fmt |= (AFMT_CHANNEL(ch->fmt) - 1);
+
+	return (fmt);
+}
+
+static void
+hdaa_audio_setup(struct hdaa_chan *ch)
+{
+	struct hdaa_audio_as *as = &ch->devinfo->as[ch->as];
+	struct hdaa_widget *w;
+	int i, chn, totalchn, c;
+	uint16_t fmt, dfmt;
+	uint16_t chmap[2][5] = {{ 0x0010, 0x0001, 0x0201, 0x0231, 0x0231 }, /* 5.1 */
+				{ 0x0010, 0x0001, 0x2001, 0x2031, 0x2431 }};/* 7.1 */
+	int map = -1;
+
+	totalchn = AFMT_CHANNEL(ch->fmt);
+	HDA_BOOTHVERBOSE(
+		device_printf(ch->pdevinfo->dev,
+		    "PCMDIR_%s: Stream setup fmt=%08x speed=%d\n",
+		    (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC",
+		    ch->fmt, ch->spd);
+	);
+	fmt = hdaa_stream_format(ch);
+
+	/* Set channel mapping for known speaker setups. */
+	if ((as->pinset == 0x0007 || as->pinset == 0x0013)) /* Standard 5.1 */
+		map = 0;
+	else if (as->pinset == 0x0017) /* Standard 7.1 */
+		map = 1;
+
+	dfmt = HDA_CMD_SET_DIGITAL_CONV_FMT1_DIGEN;
+	if (ch->fmt & AFMT_AC3)
+		dfmt |= HDA_CMD_SET_DIGITAL_CONV_FMT1_NAUDIO;
+
+	chn = 0;
+	for (i = 0; ch->io[i] != -1; i++) {
+		w = hdaa_widget_get(ch->devinfo, ch->io[i]);
+		if (w == NULL)
+			continue;
+
+		/* If HP redirection is enabled, but failed to use same
+		   DAC, make last DAC to duplicate first one. */
+		if (as->fakeredir && i == (as->pincnt - 1)) {
+			c = (ch->sid << 4);
+		} else {
+			if (map >= 0) /* Map known speaker setups. */
+				chn = (((chmap[map][totalchn / 2] >> i * 4) &
+				    0xf) - 1) * 2;
+			if (chn < 0 || chn >= totalchn) {
+				c = 0;
+			} else {
+				c = (ch->sid << 4) | chn;
+			}
+		}
+		HDA_BOOTHVERBOSE(
+			device_printf(ch->pdevinfo->dev,
+			    "PCMDIR_%s: Stream setup nid=%d: "
+			    "fmt=0x%04x, dfmt=0x%04x, chan=0x%04x\n",
+			    (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC",
+			    ch->io[i], fmt, dfmt, c);
+		);
+		hda_command(ch->devinfo->dev,
+		    HDA_CMD_SET_CONV_FMT(0, ch->io[i], fmt));
+		if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) {
+			hda_command(ch->devinfo->dev,
+			    HDA_CMD_SET_DIGITAL_CONV_FMT1(0, ch->io[i], dfmt));
+		}
+		hda_command(ch->devinfo->dev,
+		    HDA_CMD_SET_CONV_STREAM_CHAN(0, ch->io[i], c));
+#if 0
+		hda_command(ch->devinfo->dev,
+		    HDA_CMD_SET_CONV_CHAN_COUNT(0, ch->io[i], 1));
+		hda_command(ch->devinfo->dev,
+		    HDA_CMD_SET_HDMI_CHAN_SLOT(0, ch->io[i], 0x00));
+		hda_command(ch->devinfo->dev,
+		    HDA_CMD_SET_HDMI_CHAN_SLOT(0, ch->io[i], 0x11));
+#endif
+		chn += HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) + 1;
+	}
+}
+
+/*
+ * Greatest Common Divisor.
+ */
+static unsigned
+gcd(unsigned a, unsigned b)
+{
+	u_int c;
+
+	while (b != 0) {
+		c = a;
+		a = b;
+		b = (c % b);
+	}
+	return (a);
+}
+
+/*
+ * Least Common Multiple.
+ */
+static unsigned
+lcm(unsigned a, unsigned b)
+{
+
+	return ((a * b) / gcd(a, b));
+}
+
+static int
+hdaa_channel_setfragments(kobj_t obj, void *data,
+					uint32_t blksz, uint32_t blkcnt)
+{
+	struct hdaa_chan *ch = data;
+
+	blksz -= blksz % lcm(HDA_DMA_ALIGNMENT, sndbuf_getalign(ch->b));
+
+	if (blksz > (sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN))
+		blksz = sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN;
+	if (blksz < HDA_BLK_MIN)
+		blksz = HDA_BLK_MIN;
+	if (blkcnt > HDA_BDL_MAX)
+		blkcnt = HDA_BDL_MAX;
+	if (blkcnt < HDA_BDL_MIN)
+		blkcnt = HDA_BDL_MIN;
+
+	while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->b)) {
+		if ((blkcnt >> 1) >= HDA_BDL_MIN)
+			blkcnt >>= 1;
+		else if ((blksz >> 1) >= HDA_BLK_MIN)
+			blksz >>= 1;
+		else
+			break;
+	}
+
+	if ((sndbuf_getblksz(ch->b) != blksz ||
+	    sndbuf_getblkcnt(ch->b) != blkcnt) &&
+	    sndbuf_resize(ch->b, blkcnt, blksz) != 0)
+		device_printf(ch->devinfo->dev, "%s: failed blksz=%u blkcnt=%u\n",
+		    __func__, blksz, blkcnt);
+
+	ch->blksz = sndbuf_getblksz(ch->b);
+	ch->blkcnt = sndbuf_getblkcnt(ch->b);
+
+	return (0);
+}
+
+static uint32_t
+hdaa_channel_setblocksize(kobj_t obj, void *data, uint32_t blksz)
+{
+	struct hdaa_chan *ch = data;
+
+	hdaa_channel_setfragments(obj, data, blksz, ch->pdevinfo->chan_blkcnt);
+
+	return (ch->blksz);
+}
+
+static void
+hdaa_channel_stop(struct hdaa_chan *ch)
+{
+	struct hdaa_devinfo *devinfo = ch->devinfo;
+	struct hdaa_widget *w;
+	int i;
+
+	if ((ch->flags & HDAA_CHN_RUNNING) == 0)
+		return;
+	ch->flags &= ~HDAA_CHN_RUNNING;
+	HDAC_STREAM_STOP(device_get_parent(devinfo->dev), devinfo->dev,
+	    ch->dir == PCMDIR_PLAY ? 1 : 0, ch->sid);
+	for (i = 0; ch->io[i] != -1; i++) {
+		w = hdaa_widget_get(ch->devinfo, ch->io[i]);
+		if (w == NULL)
+			continue;
+		if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) {
+			hda_command(devinfo->dev,
+			    HDA_CMD_SET_DIGITAL_CONV_FMT1(0, ch->io[i], 0));
+		}
+		hda_command(devinfo->dev,
+		    HDA_CMD_SET_CONV_STREAM_CHAN(0, ch->io[i],
+		    0));
+	}
+	HDAC_STREAM_FREE(device_get_parent(devinfo->dev), devinfo->dev,
+	    ch->dir == PCMDIR_PLAY ? 1 : 0, ch->sid);
+}
+
+static int
+hdaa_channel_start(struct hdaa_chan *ch)
+{
+	struct hdaa_devinfo *devinfo = ch->devinfo;
+
+	ch->ptr = 0;
+	ch->prevptr = 0;
+	ch->sid = HDAC_STREAM_ALLOC(device_get_parent(devinfo->dev), devinfo->dev,
+	    ch->dir == PCMDIR_PLAY ? 1 : 0, hdaa_stream_format(ch), &ch->dmapos);
+	if (ch->sid <= 0)
+		return (EBUSY);
+	hdaa_audio_setup(ch);
+	HDAC_STREAM_RESET(device_get_parent(devinfo->dev), devinfo->dev,
+	    ch->dir == PCMDIR_PLAY ? 1 : 0, ch->sid);
+	HDAC_STREAM_START(device_get_parent(devinfo->dev), devinfo->dev,
+	    ch->dir == PCMDIR_PLAY ? 1 : 0, ch->sid,
+	    sndbuf_getbufaddr(ch->b), ch->blksz, ch->blkcnt);
+	ch->flags |= HDAA_CHN_RUNNING;
+	return (0);
+}
+
+static int
+hdaa_channel_trigger(kobj_t obj, void *data, int go)
+{
+	struct hdaa_chan *ch = data;
+	int error = 0;
+
+	if (!PCMTRIG_COMMON(go))
+		return (0);
+
+	hdaa_lock(ch->devinfo);
+	switch (go) {
+	case PCMTRIG_START:
+		error = hdaa_channel_start(ch);
+		break;
+	case PCMTRIG_STOP:
+	case PCMTRIG_ABORT:
+		hdaa_channel_stop(ch);
+		break;
+	default:
+		break;
+	}
+	hdaa_unlock(ch->devinfo);
+
+	return (error);
+}
+
+static uint32_t
+hdaa_channel_getptr(kobj_t obj, void *data)
+{
+	struct hdaa_chan *ch = data;
+	struct hdaa_devinfo *devinfo = ch->devinfo;
+	uint32_t ptr;
+
+	hdaa_lock(devinfo);
+	if (ch->dmapos != NULL) {
+		ptr = *(ch->dmapos);
+	} else {
+		ptr = HDAC_STREAM_GETPTR(
+		    device_get_parent(devinfo->dev), devinfo->dev,
+		    ch->dir == PCMDIR_PLAY ? 1 : 0, ch->sid);
+	}
+	hdaa_unlock(devinfo);
+
+	/*
+	 * Round to available space and force 128 bytes aligment.
+	 */
+	ptr %= ch->blksz * ch->blkcnt;
+	ptr &= HDA_BLK_ALIGN;
+
+	return (ptr);
+}
+
+static struct pcmchan_caps *
+hdaa_channel_getcaps(kobj_t obj, void *data)
+{
+	return (&((struct hdaa_chan *)data)->caps);
+}
+
+static kobj_method_t hdaa_channel_methods[] = {
+	KOBJMETHOD(channel_init,		hdaa_channel_init),
+	KOBJMETHOD(channel_setformat,		hdaa_channel_setformat),
+	KOBJMETHOD(channel_setspeed,		hdaa_channel_setspeed),
+	KOBJMETHOD(channel_setblocksize,	hdaa_channel_setblocksize),
+	KOBJMETHOD(channel_setfragments,	hdaa_channel_setfragments),
+	KOBJMETHOD(channel_trigger,		hdaa_channel_trigger),
+	KOBJMETHOD(channel_getptr,		hdaa_channel_getptr),
+	KOBJMETHOD(channel_getcaps,		hdaa_channel_getcaps),
+	KOBJMETHOD_END
+};
+CHANNEL_DECLARE(hdaa_channel);
+
+static int
+hdaa_audio_ctl_ossmixer_init(struct snd_mixer *m)
+{
+	struct hdaa_pcm_devinfo *pdevinfo = mix_getdevinfo(m);
+	struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
+	struct hdaa_widget *w, *cw;
+	struct hdaa_audio_ctl *ctl;
+	uint32_t mask, recmask;
+	int i, j, softpcmvol;
+
+	hdaa_lock(devinfo);
+
+	/* Make sure that in case of soft volume it won't stay muted. */
+	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
+		pdevinfo->left[i] = 100;
+		pdevinfo->right[i] = 100;
+	}
+
+	mask = 0;
+	recmask = 0;
+
+	/* Declate EAPD as ogain control. */
+	if (pdevinfo->playas >= 0) {
+		for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+			w = hdaa_widget_get(devinfo, i);
+			if (w == NULL || w->enable == 0)
+				continue;
+			if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX ||
+			    w->param.eapdbtl == HDA_INVALID ||
+			    w->bindas != pdevinfo->playas)
+				continue;
+			mask |= SOUND_MASK_OGAIN;
+			break;
+		}
+	}
+
+	/* Declare volume controls assigned to this association. */
+	i = 0;
+	ctl = NULL;
+	while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
+		if (ctl->enable == 0)
+			continue;
+		if ((pdevinfo->playas >= 0 &&
+		    ctl->widget->bindas == pdevinfo->playas) ||
+		    (pdevinfo->recas >= 0 &&
+		    ctl->widget->bindas == pdevinfo->recas) ||
+		    (ctl->widget->bindas == -2 && pdevinfo->index == 0))
+			mask |= ctl->ossmask;
+	}
+
+	/* Declare record sources available to this association. */
+	if (pdevinfo->recas >= 0) {
+		for (i = 0; i < 16; i++) {
+			if (devinfo->as[pdevinfo->recas].dacs[0][i] < 0)
+				continue;
+			w = hdaa_widget_get(devinfo,
+			    devinfo->as[pdevinfo->recas].dacs[0][i]);
+			if (w == NULL || w->enable == 0)
+				continue;
+			for (j = 0; j < w->nconns; j++) {
+				if (w->connsenable[j] == 0)
+					continue;
+				cw = hdaa_widget_get(devinfo, w->conns[j]);
+				if (cw == NULL || cw->enable == 0)
+					continue;
+				if (cw->bindas != pdevinfo->recas &&
+				    cw->bindas != -2)
+					continue;
+				recmask |= cw->ossmask;
+			}
+		}
+	}
+
+	/* Declare soft PCM volume if needed. */
+	if (pdevinfo->playas >= 0) {
+		ctl = NULL;
+		if ((mask & SOUND_MASK_PCM) == 0 ||
+		    (devinfo->quirks & HDAA_QUIRK_SOFTPCMVOL)) {
+			softpcmvol = 1;
+			mask |= SOUND_MASK_PCM;
+		} else {
+			softpcmvol = 0;
+			i = 0;
+			while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
+				if (ctl->enable == 0)
+					continue;
+				if (ctl->widget->bindas != pdevinfo->playas &&
+				    (ctl->widget->bindas != -2 || pdevinfo->index != 0))
+					continue;
+				if (!(ctl->ossmask & SOUND_MASK_PCM))
+					continue;
+				if (ctl->step > 0)
+					break;
+			}
+		}
+
+		if (softpcmvol == 1 || ctl == NULL) {
+			pcm_setflags(pdevinfo->dev, pcm_getflags(pdevinfo->dev) | SD_F_SOFTPCMVOL);
+			HDA_BOOTVERBOSE(
+				device_printf(pdevinfo->dev,
+				    "%s Soft PCM volume\n",
+				    (softpcmvol == 1) ? "Forcing" : "Enabling");
+			);
+		}
+	}
+
+	/* Declare master volume if needed. */
+	if (pdevinfo->playas >= 0) {
+		if ((mask & (SOUND_MASK_VOLUME | SOUND_MASK_PCM)) ==
+		    SOUND_MASK_PCM) {
+			mask |= SOUND_MASK_VOLUME;
+			mix_setparentchild(m, SOUND_MIXER_VOLUME,
+			    SOUND_MASK_PCM);
+			mix_setrealdev(m, SOUND_MIXER_VOLUME,
+			    SOUND_MIXER_NONE);
+			HDA_BOOTVERBOSE(
+				device_printf(pdevinfo->dev,
+				    "Forcing master volume with PCM\n");
+			);
+		}
+	}
+
+	recmask &= (1 << SOUND_MIXER_NRDEVICES) - 1;
+	mask &= (1 << SOUND_MIXER_NRDEVICES) - 1;
+
+	mix_setrecdevs(m, recmask);
+	mix_setdevs(m, mask);
+
+	hdaa_unlock(devinfo);
+
+	return (0);
+}
+
+static int
+hdaa_audio_ctl_ossmixer_set(struct snd_mixer *m, unsigned dev,
+					unsigned left, unsigned right)
+{
+	struct hdaa_pcm_devinfo *pdevinfo = mix_getdevinfo(m);
+	struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
+	struct hdaa_widget *w;
+	struct hdaa_audio_ctl *ctl;
+	uint32_t mute;
+	int lvol, rvol;
+	int i, j;
+
+	hdaa_lock(devinfo);
+	/* Save new values. */
+	pdevinfo->left[dev] = left;
+	pdevinfo->right[dev] = right;
+
+	/* 'ogain' is the special case implemented with EAPD. */
+	if (dev == SOUND_MIXER_OGAIN) {
+		uint32_t orig;
+		w = NULL;
+		for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+			w = hdaa_widget_get(devinfo, i);
+			if (w == NULL || w->enable == 0)
+				continue;
+			if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX ||
+			    w->param.eapdbtl == HDA_INVALID)
+				continue;
+			break;
+		}
+		if (i >= devinfo->endnode) {
+			hdaa_unlock(devinfo);
+			return (-1);
+		}
+		orig = w->param.eapdbtl;
+		if (left == 0)
+			w->param.eapdbtl &= ~HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
+		else
+			w->param.eapdbtl |= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
+		if (orig != w->param.eapdbtl) {
+			uint32_t val;
+
+			val = w->param.eapdbtl;
+			if (devinfo->quirks & HDAA_QUIRK_EAPDINV)
+				val ^= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
+			hda_command(devinfo->dev,
+			    HDA_CMD_SET_EAPD_BTL_ENABLE(0, w->nid, val));
+		}
+		hdaa_unlock(devinfo);
+		return (left | (left << 8));
+	}
+
+	/* Recalculate all controls related to this OSS device. */
+	i = 0;
+	while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
+		if (ctl->enable == 0 ||
+		    !(ctl->ossmask & (1 << dev)))
+			continue;
+		if (!((pdevinfo->playas >= 0 &&
+		    ctl->widget->bindas == pdevinfo->playas) ||
+		    (pdevinfo->recas >= 0 &&
+		    ctl->widget->bindas == pdevinfo->recas) ||
+		    ctl->widget->bindas == -2))
+			continue;
+
+		lvol = 100;
+		rvol = 100;
+		for (j = 0; j < SOUND_MIXER_NRDEVICES; j++) {
+			if (ctl->ossmask & (1 << j)) {
+				lvol = lvol * pdevinfo->left[j] / 100;
+				rvol = rvol * pdevinfo->right[j] / 100;
+			}
+		}
+		mute = (lvol == 0) ? HDAA_AMP_MUTE_LEFT : 0;
+		mute |= (rvol == 0) ? HDAA_AMP_MUTE_RIGHT : 0;
+		lvol = (lvol * ctl->step + 50) / 100;
+		rvol = (rvol * ctl->step + 50) / 100;
+		hdaa_audio_ctl_amp_set(ctl, mute, lvol, rvol);
+	}
+	hdaa_unlock(devinfo);
+
+	return (left | (right << 8));
+}
+
+/*
+ * Commutate specified record source.
+ */
+static uint32_t
+hdaa_audio_ctl_recsel_comm(struct hdaa_pcm_devinfo *pdevinfo, uint32_t src, nid_t nid, int depth)
+{
+	struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
+	struct hdaa_widget *w, *cw;
+	struct hdaa_audio_ctl *ctl;
+	char buf[64];
+	int i, muted;
+	uint32_t res = 0;
+
+	if (depth > HDA_PARSE_MAXDEPTH)
+		return (0);
+
+	w = hdaa_widget_get(devinfo, nid);
+	if (w == NULL || w->enable == 0)
+		return (0);
+
+	for (i = 0; i < w->nconns; i++) {
+		if (w->connsenable[i] == 0)
+			continue;
+		cw = hdaa_widget_get(devinfo, w->conns[i]);
+		if (cw == NULL || cw->enable == 0 || cw->bindas == -1)
+			continue;
+		/* Call recursively to trace signal to it's source if needed. */
+		if ((src & cw->ossmask) != 0) {
+			if (cw->ossdev < 0) {
+				res |= hdaa_audio_ctl_recsel_comm(pdevinfo, src,
+				    w->conns[i], depth + 1);
+			} else {
+				res |= cw->ossmask;
+			}
+		}
+		/* We have two special cases: mixers and others (selectors). */
+		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER) {
+			ctl = hdaa_audio_ctl_amp_get(devinfo,
+			    w->nid, HDAA_CTL_IN, i, 1);
+			if (ctl == NULL) 
+				continue;
+			/* If we have input control on this node mute them
+			 * according to requested sources. */
+			muted = (src & cw->ossmask) ? 0 : 1;
+			if (muted != ctl->forcemute) {
+				ctl->forcemute = muted;
+				hdaa_audio_ctl_amp_set(ctl,
+				    HDAA_AMP_MUTE_DEFAULT,
+				    HDAA_AMP_VOL_DEFAULT, HDAA_AMP_VOL_DEFAULT);
+			}
+			HDA_BOOTHVERBOSE(
+				device_printf(pdevinfo->dev,
+				    "Recsel (%s): nid %d source %d %s\n",
+				    hdaa_audio_ctl_ossmixer_mask2allname(
+				    src, buf, sizeof(buf)),
+				    nid, i, muted?"mute":"unmute");
+			);
+		} else {
+			if (w->nconns == 1)
+				break;
+			if ((src & cw->ossmask) == 0)
+				continue;
+			/* If we found requested source - select it and exit. */
+			hdaa_widget_connection_select(w, i);
+			HDA_BOOTHVERBOSE(
+				device_printf(pdevinfo->dev,
+				    "Recsel (%s): nid %d source %d select\n",
+				    hdaa_audio_ctl_ossmixer_mask2allname(
+				    src, buf, sizeof(buf)),
+				    nid, i);
+			);
+			break;
+		}
+	}
+	return (res);
+}
+
+static uint32_t
+hdaa_audio_ctl_ossmixer_setrecsrc(struct snd_mixer *m, uint32_t src)
+{
+	struct hdaa_pcm_devinfo *pdevinfo = mix_getdevinfo(m);
+	struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
+	struct hdaa_widget *w;
+	struct hdaa_audio_as *as;
+	struct hdaa_chan *ch;
+	int i, j;
+	uint32_t ret = 0xffffffff;
+
+	hdaa_lock(devinfo);
+	if (pdevinfo->recas < 0) {
+		hdaa_unlock(devinfo);
+		return (0);
+	}
+	as = &devinfo->as[pdevinfo->recas];
+
+	/* For non-mixed associations we always recording everything. */
+	if (!as->mixed) {
+		hdaa_unlock(devinfo);
+		return (mix_getrecdevs(m));
+	}
+
+	/* Commutate requested recsrc for each ADC. */
+	for (j = 0; j < as->num_chans; j++) {
+		ch = &devinfo->chans[as->chans[j]];
+		for (i = 0; ch->io[i] >= 0; i++) {
+			w = hdaa_widget_get(devinfo, ch->io[i]);
+			if (w == NULL || w->enable == 0)
+				continue;
+			ret &= hdaa_audio_ctl_recsel_comm(pdevinfo, src,
+			    ch->io[i], 0);
+		}
+	}
+
+	hdaa_unlock(devinfo);
+	return ((ret == 0xffffffff)? 0 : ret);
+}
+
+static kobj_method_t hdaa_audio_ctl_ossmixer_methods[] = {
+	KOBJMETHOD(mixer_init,		hdaa_audio_ctl_ossmixer_init),
+	KOBJMETHOD(mixer_set,		hdaa_audio_ctl_ossmixer_set),
+	KOBJMETHOD(mixer_setrecsrc,	hdaa_audio_ctl_ossmixer_setrecsrc),
+	KOBJMETHOD_END
+};
+MIXER_DECLARE(hdaa_audio_ctl_ossmixer);
+
+static void
+hdaa_dump_gpi(struct hdaa_devinfo *devinfo)
+{
+	device_t dev = devinfo->dev;
+	int i;
+	uint32_t data, wake, unsol, sticky;
+
+	if (HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->gpio_cap) > 0) {
+		data = hda_command(dev,
+		    HDA_CMD_GET_GPI_DATA(0, devinfo->nid));
+		wake = hda_command(dev,
+		    HDA_CMD_GET_GPI_WAKE_ENABLE_MASK(0, devinfo->nid));
+		unsol = hda_command(dev,
+		    HDA_CMD_GET_GPI_UNSOLICITED_ENABLE_MASK(0, devinfo->nid));
+		sticky = hda_command(dev,
+		    HDA_CMD_GET_GPI_STICKY_MASK(0, devinfo->nid));
+		for (i = 0; i < HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->gpio_cap); i++) {
+			device_printf(dev, " GPI%d:%s%s%s state=%d", i,
+				    (sticky & (1 << i)) ? " sticky" : "",
+				    (unsol & (1 << i)) ? " unsol" : "",
+				    (wake & (1 << i)) ? " wake" : "",
+				    (data >> i) & 1);
+		}
+	}
+}
+
+static void
+hdaa_dump_gpio(struct hdaa_devinfo *devinfo)
+{
+	device_t dev = devinfo->dev;
+	int i;
+	uint32_t data, dir, enable, wake, unsol, sticky;
+
+	if (HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap) > 0) {
+		data = hda_command(dev,
+		    HDA_CMD_GET_GPIO_DATA(0, devinfo->nid));
+		enable = hda_command(dev,
+		    HDA_CMD_GET_GPIO_ENABLE_MASK(0, devinfo->nid));
+		dir = hda_command(dev,
+		    HDA_CMD_GET_GPIO_DIRECTION(0, devinfo->nid));
+		wake = hda_command(dev,
+		    HDA_CMD_GET_GPIO_WAKE_ENABLE_MASK(0, devinfo->nid));
+		unsol = hda_command(dev,
+		    HDA_CMD_GET_GPIO_UNSOLICITED_ENABLE_MASK(0, devinfo->nid));
+		sticky = hda_command(dev,
+		    HDA_CMD_GET_GPIO_STICKY_MASK(0, devinfo->nid));
+		for (i = 0; i < HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap); i++) {
+			device_printf(dev, " GPIO%d: ", i);
+			if ((enable & (1 << i)) == 0) {
+				printf("disabled\n");
+				continue;
+			}
+			if ((dir & (1 << i)) == 0) {
+				printf("input%s%s%s",
+				    (sticky & (1 << i)) ? " sticky" : "",
+				    (unsol & (1 << i)) ? " unsol" : "",
+				    (wake & (1 << i)) ? " wake" : "");
+			} else
+				printf("output");
+			printf(" state=%d\n", (data >> i) & 1);
+		}
+	}
+}
+
+static void
+hdaa_dump_gpo(struct hdaa_devinfo *devinfo)
+{
+	device_t dev = devinfo->dev;
+	int i;
+	uint32_t data;
+
+	if (HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap) > 0) {
+		data = hda_command(dev,
+		    HDA_CMD_GET_GPO_DATA(0, devinfo->nid));
+		for (i = 0; i < HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap); i++) {
+			device_printf(dev, " GPO%d: state=%d", i,
+				    (data >> i) & 1);
+		}
+	}
+}
+
+static void
+hdaa_audio_parse(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_widget *w;
+	uint32_t res;
+	int i;
+	nid_t nid;
+
+	nid = devinfo->nid;
+
+	res = hda_command(devinfo->dev,
+	    HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_GPIO_COUNT));
+	devinfo->gpio_cap = res;
+
+	HDA_BOOTVERBOSE(
+		device_printf(devinfo->dev,
+		    "NumGPIO=%d NumGPO=%d "
+		    "NumGPI=%d GPIWake=%d GPIUnsol=%d\n",
+		    HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap),
+		    HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap),
+		    HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->gpio_cap),
+		    HDA_PARAM_GPIO_COUNT_GPI_WAKE(devinfo->gpio_cap),
+		    HDA_PARAM_GPIO_COUNT_GPI_UNSOL(devinfo->gpio_cap));
+		hdaa_dump_gpi(devinfo);
+		hdaa_dump_gpio(devinfo);
+		hdaa_dump_gpo(devinfo);
+	);
+
+	res = hda_command(devinfo->dev,
+	    HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_SUPP_STREAM_FORMATS));
+	devinfo->supp_stream_formats = res;
+
+	res = hda_command(devinfo->dev,
+	    HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_SUPP_PCM_SIZE_RATE));
+	devinfo->supp_pcm_size_rate = res;
+
+	res = hda_command(devinfo->dev,
+	    HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_OUTPUT_AMP_CAP));
+	devinfo->outamp_cap = res;
+
+	res = hda_command(devinfo->dev,
+	    HDA_CMD_GET_PARAMETER(0, nid, HDA_PARAM_INPUT_AMP_CAP));
+	devinfo->inamp_cap = res;
+
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL)
+			device_printf(devinfo->dev, "Ghost widget! nid=%d!\n", i);
+		else {
+			w->devinfo = devinfo;
+			w->nid = i;
+			w->enable = 1;
+			w->selconn = -1;
+			w->pflags = 0;
+			w->ossdev = -1;
+			w->bindas = -1;
+			w->param.eapdbtl = HDA_INVALID;
+			hdaa_widget_parse(w);
+		}
+	}
+}
+
+static void
+hdaa_audio_postprocess(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_widget *w;
+	int i;
+
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL)
+			continue;
+		hdaa_widget_postprocess(w);
+	}
+}
+
+static void
+hdaa_audio_ctl_parse(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_ctl *ctls;
+	struct hdaa_widget *w, *cw;
+	int i, j, cnt, max, ocap, icap;
+	int mute, offset, step, size;
+
+	/* XXX This is redundant */
+	max = 0;
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->param.outamp_cap != 0)
+			max++;
+		if (w->param.inamp_cap != 0) {
+			switch (w->type) {
+			case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR:
+			case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER:
+				for (j = 0; j < w->nconns; j++) {
+					cw = hdaa_widget_get(devinfo,
+					    w->conns[j]);
+					if (cw == NULL || cw->enable == 0)
+						continue;
+					max++;
+				}
+				break;
+			default:
+				max++;
+				break;
+			}
+		}
+	}
+	devinfo->ctlcnt = max;
+
+	if (max < 1)
+		return;
+
+	ctls = (struct hdaa_audio_ctl *)malloc(
+	    sizeof(*ctls) * max, M_HDAA, M_ZERO | M_NOWAIT);
+
+	if (ctls == NULL) {
+		/* Blekh! */
+		device_printf(devinfo->dev, "unable to allocate ctls!\n");
+		devinfo->ctlcnt = 0;
+		return;
+	}
+
+	cnt = 0;
+	for (i = devinfo->startnode; cnt < max && i < devinfo->endnode; i++) {
+		if (cnt >= max) {
+			device_printf(devinfo->dev, "%s: Ctl overflow!\n",
+			    __func__);
+			break;
+		}
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		ocap = w->param.outamp_cap;
+		icap = w->param.inamp_cap;
+		if (ocap != 0) {
+			mute = HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(ocap);
+			step = HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(ocap);
+			size = HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(ocap);
+			offset = HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(ocap);
+			/*if (offset > step) {
+				HDA_BOOTVERBOSE(
+					device_printf(devinfo->dev,
+					    "BUGGY outamp: nid=%d "
+					    "[offset=%d > step=%d]\n",
+					    w->nid, offset, step);
+				);
+				offset = step;
+			}*/
+			ctls[cnt].enable = 1;
+			ctls[cnt].widget = w;
+			ctls[cnt].mute = mute;
+			ctls[cnt].step = step;
+			ctls[cnt].size = size;
+			ctls[cnt].offset = offset;
+			ctls[cnt].left = offset;
+			ctls[cnt].right = offset;
+			if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX ||
+			    w->waspin)
+				ctls[cnt].ndir = HDAA_CTL_IN;
+			else 
+				ctls[cnt].ndir = HDAA_CTL_OUT;
+			ctls[cnt++].dir = HDAA_CTL_OUT;
+		}
+
+		if (icap != 0) {
+			mute = HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(icap);
+			step = HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(icap);
+			size = HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(icap);
+			offset = HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(icap);
+			/*if (offset > step) {
+				HDA_BOOTVERBOSE(
+					device_printf(devinfo->dev,
+					    "BUGGY inamp: nid=%d "
+					    "[offset=%d > step=%d]\n",
+					    w->nid, offset, step);
+				);
+				offset = step;
+			}*/
+			switch (w->type) {
+			case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR:
+			case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER:
+				for (j = 0; j < w->nconns; j++) {
+					if (cnt >= max) {
+						device_printf(devinfo->dev,
+						    "%s: Ctl overflow!\n",
+						    __func__);
+						break;
+					}
+					cw = hdaa_widget_get(devinfo,
+					    w->conns[j]);
+					if (cw == NULL || cw->enable == 0)
+						continue;
+					ctls[cnt].enable = 1;
+					ctls[cnt].widget = w;
+					ctls[cnt].childwidget = cw;
+					ctls[cnt].index = j;
+					ctls[cnt].mute = mute;
+					ctls[cnt].step = step;
+					ctls[cnt].size = size;
+					ctls[cnt].offset = offset;
+					ctls[cnt].left = offset;
+					ctls[cnt].right = offset;
+				ctls[cnt].ndir = HDAA_CTL_IN;
+					ctls[cnt++].dir = HDAA_CTL_IN;
+				}
+				break;
+			default:
+				if (cnt >= max) {
+					device_printf(devinfo->dev,
+					    "%s: Ctl overflow!\n",
+					    __func__);
+					break;
+				}
+				ctls[cnt].enable = 1;
+				ctls[cnt].widget = w;
+				ctls[cnt].mute = mute;
+				ctls[cnt].step = step;
+				ctls[cnt].size = size;
+				ctls[cnt].offset = offset;
+				ctls[cnt].left = offset;
+				ctls[cnt].right = offset;
+				if (w->type ==
+				    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+					ctls[cnt].ndir = HDAA_CTL_OUT;
+				else 
+					ctls[cnt].ndir = HDAA_CTL_IN;
+				ctls[cnt++].dir = HDAA_CTL_IN;
+				break;
+			}
+		}
+	}
+
+	devinfo->ctl = ctls;
+}
+
+static void
+hdaa_audio_as_parse(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_as *as;
+	struct hdaa_widget *w;
+	int i, j, cnt, max, type, dir, assoc, seq, first, hpredir;
+
+	/* Count present associations */
+	max = 0;
+	for (j = 1; j < 16; j++) {
+		for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+			w = hdaa_widget_get(devinfo, i);
+			if (w == NULL || w->enable == 0)
+				continue;
+			if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+				continue;
+			if (HDA_CONFIG_DEFAULTCONF_ASSOCIATION(w->wclass.pin.config)
+			    != j)
+				continue;
+			max++;
+			if (j != 15)  /* There could be many 1-pin assocs #15 */
+				break;
+		}
+	}
+
+	devinfo->ascnt = max;
+
+	if (max < 1)
+		return;
+
+	as = (struct hdaa_audio_as *)malloc(
+	    sizeof(*as) * max, M_HDAA, M_ZERO | M_NOWAIT);
+
+	if (as == NULL) {
+		/* Blekh! */
+		device_printf(devinfo->dev, "unable to allocate assocs!\n");
+		devinfo->ascnt = 0;
+		return;
+	}
+
+	for (i = 0; i < max; i++) {
+		as[i].hpredir = -1;
+		as[i].digital = 0;
+		as[i].num_chans = 1;
+		as[i].unsol = -1;
+		as[i].location = -1;
+	}
+
+	/* Scan associations skipping as=0. */
+	cnt = 0;
+	for (j = 1; j < 16; j++) {
+		first = 16;
+		hpredir = 0;
+		for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+			w = hdaa_widget_get(devinfo, i);
+			if (w == NULL || w->enable == 0)
+				continue;
+			if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+				continue;
+			assoc = HDA_CONFIG_DEFAULTCONF_ASSOCIATION(w->wclass.pin.config);
+			seq = HDA_CONFIG_DEFAULTCONF_SEQUENCE(w->wclass.pin.config);
+			if (assoc != j) {
+				continue;
+			}
+			KASSERT(cnt < max,
+			    ("%s: Associations owerflow (%d of %d)",
+			    __func__, cnt, max));
+			type = w->wclass.pin.config &
+			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
+			/* Get pin direction. */
+			if (type == HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT ||
+			    type == HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER ||
+			    type == HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT ||
+			    type == HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_OUT ||
+			    type == HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_OUT)
+				dir = HDAA_CTL_OUT;
+			else
+				dir = HDAA_CTL_IN;
+			/* If this is a first pin - create new association. */
+			if (as[cnt].pincnt == 0) {
+				as[cnt].enable = 1;
+				as[cnt].index = j;
+				as[cnt].dir = dir;
+			}
+			if (seq < first)
+				first = seq;
+			/* Check association correctness. */
+			if (as[cnt].pins[seq] != 0) {
+				device_printf(devinfo->dev, "%s: Duplicate pin %d (%d) "
+				    "in association %d! Disabling association.\n",
+				    __func__, seq, w->nid, j);
+				as[cnt].enable = 0;
+			}
+			if (dir != as[cnt].dir) {
+				device_printf(devinfo->dev, "%s: Pin %d has wrong "
+				    "direction for association %d! Disabling "
+				    "association.\n",
+				    __func__, w->nid, j);
+				as[cnt].enable = 0;
+			}
+			if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) {
+				if (HDA_PARAM_PIN_CAP_DP(w->wclass.pin.cap))
+					as[cnt].digital = 3;
+				else if (HDA_PARAM_PIN_CAP_HDMI(w->wclass.pin.cap))
+					as[cnt].digital = 2;
+				else
+					as[cnt].digital = 1;
+			}
+			if (as[cnt].location == -1) {
+				as[cnt].location =
+				    HDA_CONFIG_DEFAULTCONF_LOCATION(w->wclass.pin.config);
+			} else if (as[cnt].location !=
+			    HDA_CONFIG_DEFAULTCONF_LOCATION(w->wclass.pin.config)) {
+				as[cnt].location = -2;
+			}
+			/* Headphones with seq=15 may mean redirection. */
+			if (type == HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT &&
+			    seq == 15)
+				hpredir = 1;
+			as[cnt].pins[seq] = w->nid;
+			as[cnt].pincnt++;
+			/* Association 15 is a multiple unassociated pins. */
+			if (j == 15)
+				cnt++;
+		}
+		if (j != 15 && as[cnt].pincnt > 0) {
+			if (hpredir && as[cnt].pincnt > 1)
+				as[cnt].hpredir = first;
+			cnt++;
+		}
+	}
+	for (i = 0; i < max; i++) {
+		if (as[i].dir == HDAA_CTL_IN && (as[i].pincnt == 1 ||
+		    as[i].pins[14] > 0 || as[i].pins[15] > 0))
+			as[i].mixed = 1;
+	}
+	HDA_BOOTVERBOSE(
+		device_printf(devinfo->dev,
+		    "%d associations found:\n", max);
+		for (i = 0; i < max; i++) {
+			device_printf(devinfo->dev,
+			    "Association %d (%d) %s%s:\n",
+			    i, as[i].index, (as[i].dir == HDAA_CTL_IN)?"in":"out",
+			    as[i].enable?"":" (disabled)");
+			for (j = 0; j < 16; j++) {
+				if (as[i].pins[j] == 0)
+					continue;
+				device_printf(devinfo->dev,
+				    " Pin nid=%d seq=%d\n",
+				    as[i].pins[j], j);
+			}
+		}
+	);
+
+	devinfo->as = as;
+}
+
+/*
+ * Trace path from DAC to pin.
+ */
+static nid_t
+hdaa_audio_trace_dac(struct hdaa_devinfo *devinfo, int as, int seq, nid_t nid,
+    int dupseq, int min, int only, int depth)
+{
+	struct hdaa_widget *w;
+	int i, im = -1;
+	nid_t m = 0, ret;
+
+	if (depth > HDA_PARSE_MAXDEPTH)
+		return (0);
+	w = hdaa_widget_get(devinfo, nid);
+	if (w == NULL || w->enable == 0)
+		return (0);
+	HDA_BOOTHVERBOSE(
+		if (!only) {
+			device_printf(devinfo->dev,
+			    " %*stracing via nid %d\n",
+				depth + 1, "", w->nid);
+		}
+	);
+	/* Use only unused widgets */
+	if (w->bindas >= 0 && w->bindas != as) {
+		HDA_BOOTHVERBOSE(
+			if (!only) {
+				device_printf(devinfo->dev,
+				    " %*snid %d busy by association %d\n",
+					depth + 1, "", w->nid, w->bindas);
+			}
+		);
+		return (0);
+	}
+	if (dupseq < 0) {
+		if (w->bindseqmask != 0) {
+			HDA_BOOTHVERBOSE(
+				if (!only) {
+					device_printf(devinfo->dev,
+					    " %*snid %d busy by seqmask %x\n",
+						depth + 1, "", w->nid, w->bindseqmask);
+				}
+			);
+			return (0);
+		}
+	} else {
+		/* If this is headphones - allow duplicate first pin. */
+		if (w->bindseqmask != 0 &&
+		    (w->bindseqmask & (1 << dupseq)) == 0) {
+			HDA_BOOTHVERBOSE(
+				device_printf(devinfo->dev,
+				    " %*snid %d busy by seqmask %x\n",
+					depth + 1, "", w->nid, w->bindseqmask);
+			);
+			return (0);
+		}
+	}
+
+	switch (w->type) {
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT:
+		/* Do not traverse input. AD1988 has digital monitor
+		for which we are not ready. */
+		break;
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT:
+		/* If we are tracing HP take only dac of first pin. */
+		if ((only == 0 || only == w->nid) &&
+		    (w->nid >= min) && (dupseq < 0 || w->nid ==
+		    devinfo->as[as].dacs[0][dupseq]))
+			m = w->nid;
+		break;
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
+		if (depth > 0)
+			break;
+		/* Fall */
+	default:
+		/* Find reachable DACs with smallest nid respecting constraints. */
+		for (i = 0; i < w->nconns; i++) {
+			if (w->connsenable[i] == 0)
+				continue;
+			if (w->selconn != -1 && w->selconn != i)
+				continue;
+			if ((ret = hdaa_audio_trace_dac(devinfo, as, seq,
+			    w->conns[i], dupseq, min, only, depth + 1)) != 0) {
+				if (m == 0 || ret < m) {
+					m = ret;
+					im = i;
+				}
+				if (only || dupseq >= 0)
+					break;
+			}
+		}
+		if (im >= 0 && only && ((w->nconns > 1 &&
+		    w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER) ||
+		    w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR))
+			w->selconn = im;
+		break;
+	}
+	if (m && only) {
+		w->bindas = as;
+		w->bindseqmask |= (1 << seq);
+	}
+	HDA_BOOTHVERBOSE(
+		if (!only) {
+			device_printf(devinfo->dev,
+			    " %*snid %d returned %d\n",
+				depth + 1, "", w->nid, m);
+		}
+	);
+	return (m);
+}
+
+/*
+ * Trace path from widget to ADC.
+ */
+static nid_t
+hdaa_audio_trace_adc(struct hdaa_devinfo *devinfo, int as, int seq, nid_t nid,
+    int mixed, int min, int only, int depth, int *length, int onlylength)
+{
+	struct hdaa_widget *w, *wc;
+	int i, j, im, lm = HDA_PARSE_MAXDEPTH;
+	nid_t m = 0, ret;
+
+	if (depth > HDA_PARSE_MAXDEPTH)
+		return (0);
+	w = hdaa_widget_get(devinfo, nid);
+	if (w == NULL || w->enable == 0)
+		return (0);
+	HDA_BOOTHVERBOSE(
+		device_printf(devinfo->dev,
+		    " %*stracing via nid %d\n",
+			depth + 1, "", w->nid);
+	);
+	/* Use only unused widgets */
+	if (w->bindas >= 0 && w->bindas != as) {
+		HDA_BOOTHVERBOSE(
+			device_printf(devinfo->dev,
+			    " %*snid %d busy by association %d\n",
+				depth + 1, "", w->nid, w->bindas);
+		);
+		return (0);
+	}
+	if (!mixed && w->bindseqmask != 0) {
+		HDA_BOOTHVERBOSE(
+			device_printf(devinfo->dev,
+			    " %*snid %d busy by seqmask %x\n",
+				depth + 1, "", w->nid, w->bindseqmask);
+		);
+		return (0);
+	}
+	switch (w->type) {
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT:
+		if ((only == 0 || only == w->nid) && (w->nid >= min) &&
+		    (onlylength == 0 || onlylength == depth)) {
+			m = w->nid;
+			if (length != NULL)
+				*length = depth;
+		}
+		break;
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
+		if (depth > 0)
+			break;
+		/* Fall */
+	default:
+		/* Try to find reachable ADCs with specified nid. */
+		for (j = devinfo->startnode; j < devinfo->endnode; j++) {
+			wc = hdaa_widget_get(devinfo, j);
+			if (wc == NULL || wc->enable == 0)
+				continue;
+			im = -1;
+			for (i = 0; i < wc->nconns; i++) {
+				if (wc->connsenable[i] == 0)
+					continue;
+				if (wc->conns[i] != nid)
+					continue;
+				if ((ret = hdaa_audio_trace_adc(devinfo, as, seq,
+				    j, mixed, min, only, depth + 1,
+				    length, onlylength)) != 0) {
+					if (m == 0 || ret < m ||
+					    (ret == m && length != NULL &&
+					     *length < lm)) {
+						m = ret;
+						im = i;
+						lm = *length;
+					}
+					if (only)
+						break;
+				}
+			}
+			if (im >= 0 && only && ((wc->nconns > 1 &&
+			    wc->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER) ||
+			    wc->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR))
+				wc->selconn = im;
+		}
+		break;
+	}
+	if (m && only) {
+		w->bindas = as;
+		w->bindseqmask |= (1 << seq);
+	}
+	HDA_BOOTHVERBOSE(
+		device_printf(devinfo->dev,
+		    " %*snid %d returned %d\n",
+			depth + 1, "", w->nid, m);
+	);
+	return (m);
+}
+
+/*
+ * Erase trace path of the specified association.
+ */
+static void
+hdaa_audio_undo_trace(struct hdaa_devinfo *devinfo, int as, int seq)
+{
+	struct hdaa_widget *w;
+	int i;
+
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->bindas == as) {
+			if (seq >= 0) {
+				w->bindseqmask &= ~(1 << seq);
+				if (w->bindseqmask == 0) {
+					w->bindas = -1;
+					w->selconn = -1;
+				}
+			} else {
+				w->bindas = -1;
+				w->bindseqmask = 0;
+				w->selconn = -1;
+			}
+		}
+	}
+}
+
+/*
+ * Trace association path from DAC to output
+ */
+static int
+hdaa_audio_trace_as_out(struct hdaa_devinfo *devinfo, int as, int seq)
+{
+	struct hdaa_audio_as *ases = devinfo->as;
+	int i, hpredir;
+	nid_t min, res;
+
+	/* Find next pin */
+	for (i = seq; i < 16 && ases[as].pins[i] == 0; i++)
+		;
+	/* Check if there is no any left. If so - we succeeded. */
+	if (i == 16)
+		return (1);
+
+	hpredir = (i == 15 && ases[as].fakeredir == 0)?ases[as].hpredir:-1;
+	min = 0;
+	do {
+		HDA_BOOTHVERBOSE(
+			device_printf(devinfo->dev,
+			    " Tracing pin %d with min nid %d",
+			    ases[as].pins[i], min);
+			if (hpredir >= 0)
+				printf(" and hpredir %d", hpredir);
+			printf("\n");
+		);
+		/* Trace this pin taking min nid into account. */
+		res = hdaa_audio_trace_dac(devinfo, as, i,
+		    ases[as].pins[i], hpredir, min, 0, 0);
+		if (res == 0) {
+			/* If we failed - return to previous and redo it. */
+			HDA_BOOTVERBOSE(
+				device_printf(devinfo->dev,
+				    " Unable to trace pin %d seq %d with min "
+				    "nid %d",
+				    ases[as].pins[i], i, min);
+				if (hpredir >= 0)
+					printf(" and hpredir %d", hpredir);
+				printf("\n");
+			);
+			return (0);
+		}
+		HDA_BOOTVERBOSE(
+			device_printf(devinfo->dev,
+			    " Pin %d traced to DAC %d",
+			    ases[as].pins[i], res);
+			if (hpredir >= 0)
+				printf(" and hpredir %d", hpredir);
+			if (ases[as].fakeredir)
+				printf(" with fake redirection");
+			printf("\n");
+		);
+		/* Trace again to mark the path */
+		hdaa_audio_trace_dac(devinfo, as, i,
+		    ases[as].pins[i], hpredir, min, res, 0);
+		ases[as].dacs[0][i] = res;
+		/* We succeeded, so call next. */
+		if (hdaa_audio_trace_as_out(devinfo, as, i + 1))
+			return (1);
+		/* If next failed, we should retry with next min */
+		hdaa_audio_undo_trace(devinfo, as, i);
+		ases[as].dacs[0][i] = 0;
+		min = res + 1;
+	} while (1);
+}
+
+/*
+ * Check equivalency of two DACs.
+ */
+static int
+hdaa_audio_dacs_equal(struct hdaa_widget *w1, struct hdaa_widget *w2)
+{
+	struct hdaa_devinfo *devinfo = w1->devinfo;
+	struct hdaa_widget *w3;
+	int i, j, c1, c2;
+
+	if (memcmp(&w1->param, &w2->param, sizeof(w1->param)))
+		return (0);
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w3 = hdaa_widget_get(devinfo, i);
+		if (w3 == NULL || w3->enable == 0)
+			continue;
+		if (w3->bindas != w1->bindas)
+			continue;
+		if (w3->nconns == 0)
+			continue;
+		c1 = c2 = -1;
+		for (j = 0; j < w3->nconns; j++) {
+			if (w3->connsenable[j] == 0)
+				continue;
+			if (w3->conns[j] == w1->nid)
+				c1 = j;
+			if (w3->conns[j] == w2->nid)
+				c2 = j;
+		}
+		if (c1 < 0)
+			continue;
+		if (c2 < 0)
+			return (0);
+		if (w3->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
+			return (0);
+	}
+	return (1);
+}
+
+/*
+ * Check equivalency of two ADCs.
+ */
+static int
+hdaa_audio_adcs_equal(struct hdaa_widget *w1, struct hdaa_widget *w2)
+{
+	struct hdaa_devinfo *devinfo = w1->devinfo;
+	struct hdaa_widget *w3, *w4;
+	int i;
+
+	if (memcmp(&w1->param, &w2->param, sizeof(w1->param)))
+		return (0);
+	if (w1->nconns != 1 || w2->nconns != 1)
+		return (0);
+	if (w1->conns[0] == w2->conns[0])
+		return (1);
+	w3 = hdaa_widget_get(devinfo, w1->conns[0]);
+	if (w3 == NULL || w3->enable == 0)
+		return (0);
+	w4 = hdaa_widget_get(devinfo, w2->conns[0]);
+	if (w4 == NULL || w4->enable == 0)
+		return (0);
+	if (w3->bindas == w4->bindas && w3->bindseqmask == w4->bindseqmask)
+		return (1);
+	if (w4->bindas >= 0)
+		return (0);
+	if (w3->type != w4->type)
+		return (0);
+	if (memcmp(&w3->param, &w4->param, sizeof(w3->param)))
+		return (0);
+	if (w3->nconns != w4->nconns)
+		return (0);
+	for (i = 0; i < w3->nconns; i++) {
+		if (w3->conns[i] != w4->conns[i])
+			return (0);
+	}
+	return (1);
+}
+
+/*
+ * Look for equivalent DAC/ADC to implement second channel.
+ */
+static void
+hdaa_audio_adddac(struct hdaa_devinfo *devinfo, int asid)
+{
+	struct hdaa_audio_as *as = &devinfo->as[asid];
+	struct hdaa_widget *w1, *w2;
+	int i, pos;
+	nid_t nid1, nid2;
+
+	HDA_BOOTVERBOSE(
+		device_printf(devinfo->dev,
+		    "Looking for additional %sC "
+		    "for association %d (%d)\n",
+		    (as->dir == HDAA_CTL_OUT) ? "DA" : "AD",
+		    asid, as->index);
+	);
+
+	/* Find the exisitng DAC position and return if found more the one. */
+	pos = -1;
+	for (i = 0; i < 16; i++) {
+		if (as->dacs[0][i] <= 0)
+			continue;
+		if (pos >= 0 && as->dacs[0][i] != as->dacs[0][pos])
+			return;
+		pos = i;
+	}
+
+	nid1 = as->dacs[0][pos];
+	w1 = hdaa_widget_get(devinfo, nid1);
+	w2 = NULL;
+	for (nid2 = devinfo->startnode; nid2 < devinfo->endnode; nid2++) {
+		w2 = hdaa_widget_get(devinfo, nid2);
+		if (w2 == NULL || w2->enable == 0)
+			continue;
+		if (w2->bindas >= 0)
+			continue;
+		if (w1->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT) {
+			if (w2->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT)
+				continue;
+			if (hdaa_audio_dacs_equal(w1, w2))
+				break;
+		} else {
+			if (w2->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT)
+				continue;
+			if (hdaa_audio_adcs_equal(w1, w2))
+				break;
+		}
+	}
+	if (nid2 >= devinfo->endnode)
+		return;
+	w2->bindas = w1->bindas;
+	w2->bindseqmask = w1->bindseqmask;
+	if (w1->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) {
+		HDA_BOOTVERBOSE(
+			device_printf(devinfo->dev,
+			    " ADC %d considered equal to ADC %d\n", nid2, nid1);
+		);
+		w1 = hdaa_widget_get(devinfo, w1->conns[0]);
+		w2 = hdaa_widget_get(devinfo, w2->conns[0]);
+		w2->bindas = w1->bindas;
+		w2->bindseqmask = w1->bindseqmask;
+	} else {
+		HDA_BOOTVERBOSE(
+			device_printf(devinfo->dev,
+			    " DAC %d considered equal to DAC %d\n", nid2, nid1);
+		);
+	}
+	for (i = 0; i < 16; i++) {
+		if (as->dacs[0][i] <= 0)
+			continue;
+		as->dacs[as->num_chans][i] = nid2;
+	}
+	as->num_chans++;
+}
+
+/*
+ * Trace association path from input to ADC
+ */
+static int
+hdaa_audio_trace_as_in(struct hdaa_devinfo *devinfo, int as)
+{
+	struct hdaa_audio_as *ases = devinfo->as;
+	struct hdaa_widget *w;
+	int i, j, k, length;
+
+	for (j = devinfo->startnode; j < devinfo->endnode; j++) {
+		w = hdaa_widget_get(devinfo, j);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT)
+			continue;
+		if (w->bindas >= 0 && w->bindas != as)
+			continue;
+
+		/* Find next pin */
+		for (i = 0; i < 16; i++) {
+			if (ases[as].pins[i] == 0)
+				continue;
+
+			HDA_BOOTHVERBOSE(
+				device_printf(devinfo->dev,
+				    " Tracing pin %d to ADC %d\n",
+				    ases[as].pins[i], j);
+			);
+			/* Trace this pin taking goal into account. */
+			if (hdaa_audio_trace_adc(devinfo, as, i,
+			    ases[as].pins[i], 1, 0, j, 0, &length, 0) == 0) {
+				/* If we failed - return to previous and redo it. */
+				HDA_BOOTVERBOSE(
+					device_printf(devinfo->dev,
+					    " Unable to trace pin %d to ADC %d, undo traces\n",
+					    ases[as].pins[i], j);
+				);
+				hdaa_audio_undo_trace(devinfo, as, -1);
+				for (k = 0; k < 16; k++)
+					ases[as].dacs[0][k] = 0;
+				break;
+			}
+			HDA_BOOTVERBOSE(
+				device_printf(devinfo->dev,
+				    " Pin %d traced to ADC %d\n",
+				    ases[as].pins[i], j);
+			);
+			ases[as].dacs[0][i] = j;
+		}
+		if (i == 16)
+			return (1);
+	}
+	return (0);
+}
+
+/*
+ * Trace association path from input to multiple ADCs
+ */
+static int
+hdaa_audio_trace_as_in_mch(struct hdaa_devinfo *devinfo, int as, int seq)
+{
+	struct hdaa_audio_as *ases = devinfo->as;
+	int i, length;
+	nid_t min, res;
+
+	/* Find next pin */
+	for (i = seq; i < 16 && ases[as].pins[i] == 0; i++)
+		;
+	/* Check if there is no any left. If so - we succeeded. */
+	if (i == 16)
+		return (1);
+
+	min = 0;
+	do {
+		HDA_BOOTHVERBOSE(
+			device_printf(devinfo->dev,
+			    " Tracing pin %d with min nid %d",
+			    ases[as].pins[i], min);
+			printf("\n");
+		);
+		/* Trace this pin taking min nid into account. */
+		res = hdaa_audio_trace_adc(devinfo, as, i,
+		    ases[as].pins[i], 0, min, 0, 0, &length, 0);
+		if (res == 0) {
+			/* If we failed - return to previous and redo it. */
+			HDA_BOOTVERBOSE(
+				device_printf(devinfo->dev,
+				    " Unable to trace pin %d seq %d with min "
+				    "nid %d",
+				    ases[as].pins[i], i, min);
+				printf("\n");
+			);
+			return (0);
+		}
+		HDA_BOOTVERBOSE(
+			device_printf(devinfo->dev,
+			    " Pin %d traced to ADC %d\n",
+			    ases[as].pins[i], res);
+		);
+		/* Trace again to mark the path */
+		hdaa_audio_trace_adc(devinfo, as, i,
+		    ases[as].pins[i], 0, min, res, 0, &length, length);
+		ases[as].dacs[0][i] = res;
+		/* We succeeded, so call next. */
+		if (hdaa_audio_trace_as_in_mch(devinfo, as, i + 1))
+			return (1);
+		/* If next failed, we should retry with next min */
+		hdaa_audio_undo_trace(devinfo, as, i);
+		ases[as].dacs[0][i] = 0;
+		min = res + 1;
+	} while (1);
+}
+
+/*
+ * Trace input monitor path from mixer to output association.
+ */
+static int
+hdaa_audio_trace_to_out(struct hdaa_devinfo *devinfo, nid_t nid, int depth)
+{
+	struct hdaa_audio_as *ases = devinfo->as;
+	struct hdaa_widget *w, *wc;
+	int i, j;
+	nid_t res = 0;
+
+	if (depth > HDA_PARSE_MAXDEPTH)
+		return (0);
+	w = hdaa_widget_get(devinfo, nid);
+	if (w == NULL || w->enable == 0)
+		return (0);
+	HDA_BOOTHVERBOSE(
+		device_printf(devinfo->dev,
+		    " %*stracing via nid %d\n",
+			depth + 1, "", w->nid);
+	);
+	/* Use only unused widgets */
+	if (depth > 0 && w->bindas != -1) {
+		if (w->bindas < 0 || ases[w->bindas].dir == HDAA_CTL_OUT) {
+			HDA_BOOTHVERBOSE(
+				device_printf(devinfo->dev,
+				    " %*snid %d found output association %d\n",
+					depth + 1, "", w->nid, w->bindas);
+			);
+			if (w->bindas >= 0)
+				w->pflags |= HDAA_ADC_MONITOR;
+			return (1);
+		} else {
+			HDA_BOOTHVERBOSE(
+				device_printf(devinfo->dev,
+				    " %*snid %d busy by input association %d\n",
+					depth + 1, "", w->nid, w->bindas);
+			);
+			return (0);
+		}
+	}
+
+	switch (w->type) {
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT:
+		/* Do not traverse input. AD1988 has digital monitor
+		for which we are not ready. */
+		break;
+	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
+		if (depth > 0)
+			break;
+		/* Fall */
+	default:
+		/* Try to find reachable ADCs with specified nid. */
+		for (j = devinfo->startnode; j < devinfo->endnode; j++) {
+			wc = hdaa_widget_get(devinfo, j);
+			if (wc == NULL || wc->enable == 0)
+				continue;
+			for (i = 0; i < wc->nconns; i++) {
+				if (wc->connsenable[i] == 0)
+					continue;
+				if (wc->conns[i] != nid)
+					continue;
+				if (hdaa_audio_trace_to_out(devinfo,
+				    j, depth + 1) != 0) {
+					res = 1;
+					if (wc->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR &&
+					    wc->selconn == -1)
+						wc->selconn = i;
+				}
+			}
+		}
+		break;
+	}
+	if (res && w->bindas == -1)
+		w->bindas = -2;
+
+	HDA_BOOTHVERBOSE(
+		device_printf(devinfo->dev,
+		    " %*snid %d returned %d\n",
+			depth + 1, "", w->nid, res);
+	);
+	return (res);
+}
+
+/*
+ * Trace extra associations (beeper, monitor)
+ */
+static void
+hdaa_audio_trace_as_extra(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_as *as = devinfo->as;
+	struct hdaa_widget *w;
+	int j;
+
+	/* Input monitor */
+	/* Find mixer associated with input, but supplying signal
+	   for output associations. Hope it will be input monitor. */
+	HDA_BOOTVERBOSE(
+		device_printf(devinfo->dev,
+		    "Tracing input monitor\n");
+	);
+	for (j = devinfo->startnode; j < devinfo->endnode; j++) {
+		w = hdaa_widget_get(devinfo, j);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
+			continue;
+		if (w->bindas < 0 || as[w->bindas].dir != HDAA_CTL_IN)
+			continue;
+		HDA_BOOTVERBOSE(
+			device_printf(devinfo->dev,
+			    " Tracing nid %d to out\n",
+			    j);
+		);
+		if (hdaa_audio_trace_to_out(devinfo, w->nid, 0)) {
+			HDA_BOOTVERBOSE(
+				device_printf(devinfo->dev,
+				    " nid %d is input monitor\n",
+					w->nid);
+			);
+			w->ossdev = SOUND_MIXER_IMIX;
+		}
+	}
+
+	/* Other inputs monitor */
+	/* Find input pins supplying signal for output associations.
+	   Hope it will be input monitoring. */
+	HDA_BOOTVERBOSE(
+		device_printf(devinfo->dev,
+		    "Tracing other input monitors\n");
+	);
+	for (j = devinfo->startnode; j < devinfo->endnode; j++) {
+		w = hdaa_widget_get(devinfo, j);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+			continue;
+		if (w->bindas < 0 || as[w->bindas].dir != HDAA_CTL_IN)
+			continue;
+		HDA_BOOTVERBOSE(
+			device_printf(devinfo->dev,
+			    " Tracing nid %d to out\n",
+			    j);
+		);
+		if (hdaa_audio_trace_to_out(devinfo, w->nid, 0)) {
+			HDA_BOOTVERBOSE(
+				device_printf(devinfo->dev,
+				    " nid %d is input monitor\n",
+					w->nid);
+			);
+		}
+	}
+
+	/* Beeper */
+	HDA_BOOTVERBOSE(
+		device_printf(devinfo->dev,
+		    "Tracing beeper\n");
+	);
+	for (j = devinfo->startnode; j < devinfo->endnode; j++) {
+		w = hdaa_widget_get(devinfo, j);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET)
+			continue;
+		HDA_BOOTHVERBOSE(
+			device_printf(devinfo->dev,
+			    " Tracing nid %d to out\n",
+			    j);
+		);
+		if (hdaa_audio_trace_to_out(devinfo, w->nid, 0)) {
+			HDA_BOOTVERBOSE(
+				device_printf(devinfo->dev,
+				    " nid %d traced to out\n",
+				    j);
+			);
+		}
+		w->bindas = -2;
+	}
+}
+
+/*
+ * Bind assotiations to PCM channels
+ */
+static void
+hdaa_audio_bind_as(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_as *as = devinfo->as;
+	int i, j, cnt = 0, free;
+
+	for (j = 0; j < devinfo->ascnt; j++) {
+		if (as[j].enable)
+			cnt += as[j].num_chans;
+	}
+	if (devinfo->num_chans == 0) {
+		devinfo->chans = (struct hdaa_chan *)malloc(
+		    sizeof(struct hdaa_chan) * cnt,
+		    M_HDAA, M_ZERO | M_NOWAIT);
+		if (devinfo->chans == NULL) {
+			device_printf(devinfo->dev,
+			    "Channels memory allocation failed!\n");
+			return;
+		}
+	} else {
+		devinfo->chans = (struct hdaa_chan *)realloc(devinfo->chans,
+		    sizeof(struct hdaa_chan) * (devinfo->num_chans + cnt),
+		    M_HDAA, M_ZERO | M_NOWAIT);
+		if (devinfo->chans == NULL) {
+			devinfo->num_chans = 0;
+			device_printf(devinfo->dev,
+			    "Channels memory allocation failed!\n");
+			return;
+		}
+		/* Fixup relative pointers after realloc */
+		for (j = 0; j < devinfo->num_chans; j++)
+			devinfo->chans[j].caps.fmtlist = devinfo->chans[j].fmtlist;
+	}
+	free = devinfo->num_chans;
+	devinfo->num_chans += cnt;
+
+	for (j = free; j < free + cnt; j++) {
+		devinfo->chans[j].devinfo = devinfo;
+		devinfo->chans[j].as = -1;
+	}
+
+	/* Assign associations in order of their numbers, */
+	for (j = 0; j < devinfo->ascnt; j++) {
+		if (as[j].enable == 0)
+			continue;
+		for (i = 0; i < as[j].num_chans; i++) {
+			devinfo->chans[free].as = j;
+			devinfo->chans[free].asindex = i;
+			devinfo->chans[free].dir =
+			    (as[j].dir == HDAA_CTL_IN) ? PCMDIR_REC : PCMDIR_PLAY;
+			hdaa_pcmchannel_setup(&devinfo->chans[free]);
+			as[j].chans[i] = free;
+			free++;
+		}
+	}
+}
+
+static void
+hdaa_audio_disable_nonaudio(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_widget *w;
+	int i;
+
+	/* Disable power and volume widgets. */
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_POWER_WIDGET ||
+		    w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VOLUME_WIDGET) {
+			w->enable = 0;
+			HDA_BOOTHVERBOSE(
+				device_printf(devinfo->dev, 
+				    " Disabling nid %d due to it's"
+				    " non-audio type.\n",
+				    w->nid);
+			);
+		}
+	}
+}
+
+static void
+hdaa_audio_disable_useless(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_widget *w, *cw;
+	struct hdaa_audio_ctl *ctl;
+	int done, found, i, j, k;
+
+	/* Disable useless pins. */
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
+			if ((w->wclass.pin.config &
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) ==
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE) {
+				w->enable = 0;
+				HDA_BOOTHVERBOSE(
+					device_printf(devinfo->dev, 
+					    " Disabling pin nid %d due"
+					    " to None connectivity.\n",
+					    w->nid);
+				);
+			} else if ((w->wclass.pin.config &
+			    HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK) == 0) {
+				w->enable = 0;
+				HDA_BOOTHVERBOSE(
+					device_printf(devinfo->dev, 
+					    " Disabling unassociated"
+					    " pin nid %d.\n",
+					    w->nid);
+				);
+			}
+		}
+	}
+	do {
+		done = 1;
+		/* Disable and mute controls for disabled widgets. */
+		i = 0;
+		while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
+			if (ctl->enable == 0)
+				continue;
+			if (ctl->widget->enable == 0 ||
+			    (ctl->childwidget != NULL &&
+			    ctl->childwidget->enable == 0)) {
+				ctl->forcemute = 1;
+				ctl->muted = HDAA_AMP_MUTE_ALL;
+				ctl->left = 0;
+				ctl->right = 0;
+				ctl->enable = 0;
+				if (ctl->ndir == HDAA_CTL_IN)
+					ctl->widget->connsenable[ctl->index] = 0;
+				done = 0;
+				HDA_BOOTHVERBOSE(
+					device_printf(devinfo->dev, 
+					    " Disabling ctl %d nid %d cnid %d due"
+					    " to disabled widget.\n", i,
+					    ctl->widget->nid,
+					    (ctl->childwidget != NULL)?
+					    ctl->childwidget->nid:-1);
+				);
+			}
+		}
+		/* Disable useless widgets. */
+		for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+			w = hdaa_widget_get(devinfo, i);
+			if (w == NULL || w->enable == 0)
+				continue;
+			/* Disable inputs with disabled child widgets. */
+			for (j = 0; j < w->nconns; j++) {
+				if (w->connsenable[j]) {
+					cw = hdaa_widget_get(devinfo, w->conns[j]);
+					if (cw == NULL || cw->enable == 0) {
+						w->connsenable[j] = 0;
+						HDA_BOOTHVERBOSE(
+							device_printf(devinfo->dev, 
+							    " Disabling nid %d connection %d due"
+							    " to disabled child widget.\n",
+							    i, j);
+						);
+					}
+				}
+			}
+			if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR &&
+			    w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
+				continue;
+			/* Disable mixers and selectors without inputs. */
+			found = 0;
+			for (j = 0; j < w->nconns; j++) {
+				if (w->connsenable[j]) {
+					found = 1;
+					break;
+				}
+			}
+			if (found == 0) {
+				w->enable = 0;
+				done = 0;
+				HDA_BOOTHVERBOSE(
+					device_printf(devinfo->dev, 
+					    " Disabling nid %d due to all it's"
+					    " inputs disabled.\n", w->nid);
+				);
+			}
+			/* Disable nodes without consumers. */
+			if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR &&
+			    w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
+				continue;
+			found = 0;
+			for (k = devinfo->startnode; k < devinfo->endnode; k++) {
+				cw = hdaa_widget_get(devinfo, k);
+				if (cw == NULL || cw->enable == 0)
+					continue;
+				for (j = 0; j < cw->nconns; j++) {
+					if (cw->connsenable[j] && cw->conns[j] == i) {
+						found = 1;
+						break;
+					}
+				}
+			}
+			if (found == 0) {
+				w->enable = 0;
+				done = 0;
+				HDA_BOOTHVERBOSE(
+					device_printf(devinfo->dev, 
+					    " Disabling nid %d due to all it's"
+					    " consumers disabled.\n", w->nid);
+				);
+			}
+		}
+	} while (done == 0);
+
+}
+
+static void
+hdaa_audio_disable_unas(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_as *as = devinfo->as;
+	struct hdaa_widget *w, *cw;
+	struct hdaa_audio_ctl *ctl;
+	int i, j, k;
+
+	/* Disable unassosiated widgets. */
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->bindas == -1) {
+			w->enable = 0;
+			HDA_BOOTHVERBOSE(
+				device_printf(devinfo->dev, 
+				    " Disabling unassociated nid %d.\n",
+				    w->nid);
+			);
+		}
+	}
+	/* Disable input connections on input pin and
+	 * output on output. */
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+			continue;
+		if (w->bindas < 0)
+			continue;
+		if (as[w->bindas].dir == HDAA_CTL_IN) {
+			for (j = 0; j < w->nconns; j++) {
+				if (w->connsenable[j] == 0)
+					continue;
+				w->connsenable[j] = 0;
+				HDA_BOOTHVERBOSE(
+					device_printf(devinfo->dev, 
+					    " Disabling connection to input pin "
+					    "nid %d conn %d.\n",
+					    i, j);
+				);
+			}
+			ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid,
+			    HDAA_CTL_IN, -1, 1);
+			if (ctl && ctl->enable) {
+				ctl->forcemute = 1;
+				ctl->muted = HDAA_AMP_MUTE_ALL;
+				ctl->left = 0;
+				ctl->right = 0;
+				ctl->enable = 0;
+			}
+		} else {
+			ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid,
+			    HDAA_CTL_OUT, -1, 1);
+			if (ctl && ctl->enable) {
+				ctl->forcemute = 1;
+				ctl->muted = HDAA_AMP_MUTE_ALL;
+				ctl->left = 0;
+				ctl->right = 0;
+				ctl->enable = 0;
+			}
+			for (k = devinfo->startnode; k < devinfo->endnode; k++) {
+				cw = hdaa_widget_get(devinfo, k);
+				if (cw == NULL || cw->enable == 0)
+					continue;
+				for (j = 0; j < cw->nconns; j++) {
+					if (cw->connsenable[j] && cw->conns[j] == i) {
+						cw->connsenable[j] = 0;
+						HDA_BOOTHVERBOSE(
+							device_printf(devinfo->dev, 
+							    " Disabling connection from output pin "
+							    "nid %d conn %d cnid %d.\n",
+							    k, j, i);
+						);
+						if (cw->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
+						    cw->nconns > 1)
+							continue;
+						ctl = hdaa_audio_ctl_amp_get(devinfo, k,
+					    HDAA_CTL_IN, j, 1);
+						if (ctl && ctl->enable) {
+							ctl->forcemute = 1;
+							ctl->muted = HDAA_AMP_MUTE_ALL;
+							ctl->left = 0;
+							ctl->right = 0;
+							ctl->enable = 0;
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+static void
+hdaa_audio_disable_notselected(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_as *as = devinfo->as;
+	struct hdaa_widget *w;
+	int i, j;
+
+	/* On playback path we can safely disable all unseleted inputs. */
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->nconns <= 1)
+			continue;
+		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
+			continue;
+		if (w->bindas < 0 || as[w->bindas].dir == HDAA_CTL_IN)
+			continue;
+		for (j = 0; j < w->nconns; j++) {
+			if (w->connsenable[j] == 0)
+				continue;
+			if (w->selconn < 0 || w->selconn == j)
+				continue;
+			w->connsenable[j] = 0;
+			HDA_BOOTHVERBOSE(
+				device_printf(devinfo->dev, 
+				    " Disabling unselected connection "
+				    "nid %d conn %d.\n",
+				    i, j);
+			);
+		}
+	}
+}
+
+static void
+hdaa_audio_disable_crossas(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_as *ases = devinfo->as;
+	struct hdaa_widget *w, *cw;
+	struct hdaa_audio_ctl *ctl;
+	int i, j;
+
+	/* Disable crossassociatement and unwanted crosschannel connections. */
+	/* ... using selectors */
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->nconns <= 1)
+			continue;
+		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
+			continue;
+		/* Allow any -> mix */
+		if (w->bindas == -2)
+			continue;
+		for (j = 0; j < w->nconns; j++) {
+			if (w->connsenable[j] == 0)
+				continue;
+			cw = hdaa_widget_get(devinfo, w->conns[j]);
+			if (cw == NULL || w->enable == 0)
+				continue;
+			/* Allow mix -> out. */
+			if (cw->bindas == -2 && w->bindas >= 0 &&
+			    ases[w->bindas].dir == HDAA_CTL_OUT)
+				continue;
+			/* Allow mix -> mixed-in. */
+			if (cw->bindas == -2 && w->bindas >= 0 &&
+			    ases[w->bindas].mixed)
+				continue;
+			/* Allow in -> mix. */
+			if ((w->pflags & HDAA_ADC_MONITOR) &&
+			     cw->bindas >= 0 &&
+			     ases[cw->bindas].dir == HDAA_CTL_IN)
+				continue;
+			/* Allow if have common as/seqs. */
+			if (w->bindas == cw->bindas &&
+			    (w->bindseqmask & cw->bindseqmask) != 0)
+				continue;
+			w->connsenable[j] = 0;
+			HDA_BOOTHVERBOSE(
+				device_printf(devinfo->dev, 
+				    " Disabling crossassociatement connection "
+				    "nid %d conn %d cnid %d.\n",
+				    i, j, cw->nid);
+			);
+		}
+	}
+	/* ... using controls */
+	i = 0;
+	while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
+		if (ctl->enable == 0 || ctl->childwidget == NULL)
+			continue;
+		/* Allow any -> mix */
+		if (ctl->widget->bindas == -2)
+			continue;
+		/* Allow mix -> out. */
+		if (ctl->childwidget->bindas == -2 &&
+		    ctl->widget->bindas >= 0 &&
+		    ases[ctl->widget->bindas].dir == HDAA_CTL_OUT)
+			continue;
+		/* Allow mix -> mixed-in. */
+		if (ctl->childwidget->bindas == -2 &&
+		    ctl->widget->bindas >= 0 &&
+		    ases[ctl->widget->bindas].mixed)
+			continue;
+		/* Allow in -> mix. */
+		if ((ctl->widget->pflags & HDAA_ADC_MONITOR) &&
+		    ctl->childwidget->bindas >= 0 &&
+		    ases[ctl->childwidget->bindas].dir == HDAA_CTL_IN)
+			continue;
+		/* Allow if have common as/seqs. */
+		if (ctl->widget->bindas == ctl->childwidget->bindas &&
+		    (ctl->widget->bindseqmask & ctl->childwidget->bindseqmask) != 0)
+			continue;
+		ctl->forcemute = 1;
+		ctl->muted = HDAA_AMP_MUTE_ALL;
+		ctl->left = 0;
+		ctl->right = 0;
+		ctl->enable = 0;
+		if (ctl->ndir == HDAA_CTL_IN)
+			ctl->widget->connsenable[ctl->index] = 0;
+		HDA_BOOTHVERBOSE(
+			device_printf(devinfo->dev, 
+			    " Disabling crossassociatement connection "
+			    "ctl %d nid %d cnid %d.\n", i,
+			    ctl->widget->nid,
+			    ctl->childwidget->nid);
+		);
+	}
+
+}
+
+#define HDA_CTL_GIVE(ctl)	((ctl)->step?1:0)
+
+/*
+ * Find controls to control amplification for source.
+ */
+static int
+hdaa_audio_ctl_source_amp(struct hdaa_devinfo *devinfo, nid_t nid, int index,
+    int ossdev, int ctlable, int depth, int need)
+{
+	struct hdaa_widget *w, *wc;
+	struct hdaa_audio_ctl *ctl;
+	int i, j, conns = 0, rneed;
+
+	if (depth > HDA_PARSE_MAXDEPTH)
+		return (need);
+
+	w = hdaa_widget_get(devinfo, nid);
+	if (w == NULL || w->enable == 0)
+		return (need);
+
+	/* Count number of active inputs. */
+	if (depth > 0) {
+		for (j = 0; j < w->nconns; j++) {
+			if (w->connsenable[j])
+				conns++;
+		}
+	}
+
+	/* If this is not a first step - use input mixer.
+	   Pins have common input ctl so care must be taken. */
+	if (depth > 0 && ctlable && (conns == 1 ||
+	    w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)) {
+		ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid, HDAA_CTL_IN,
+		    index, 1);
+		if (ctl) {
+			if (HDA_CTL_GIVE(ctl) & need)
+				ctl->ossmask |= (1 << ossdev);
+			else
+				ctl->possmask |= (1 << ossdev);
+			need &= ~HDA_CTL_GIVE(ctl);
+		}
+	}
+
+	/* If widget has own ossdev - not traverse it.
+	   It will be traversed on it's own. */
+	if (w->ossdev >= 0 && depth > 0)
+		return (need);
+
+	/* We must not traverse pin */
+	if ((w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT ||
+	    w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) &&
+	    depth > 0)
+		return (need);
+
+	/* record that this widget exports such signal, */
+	w->ossmask |= (1 << ossdev);
+
+	/* If signals mixed, we can't assign controls farther.
+	 * Ignore this on depth zero. Caller must knows why.
+	 * Ignore this for static selectors if this input selected.
+	 */
+	if (conns > 1)
+		ctlable = 0;
+
+	if (ctlable) {
+		ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid, HDAA_CTL_OUT, -1, 1);
+		if (ctl) {
+			if (HDA_CTL_GIVE(ctl) & need)
+				ctl->ossmask |= (1 << ossdev);
+			else
+				ctl->possmask |= (1 << ossdev);
+			need &= ~HDA_CTL_GIVE(ctl);
+		}
+	}
+
+	rneed = 0;
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		wc = hdaa_widget_get(devinfo, i);
+		if (wc == NULL || wc->enable == 0)
+			continue;
+		for (j = 0; j < wc->nconns; j++) {
+			if (wc->connsenable[j] && wc->conns[j] == nid) {
+				rneed |= hdaa_audio_ctl_source_amp(devinfo,
+				    wc->nid, j, ossdev, ctlable, depth + 1, need);
+			}
+		}
+	}
+	rneed &= need;
+
+	return (rneed);
+}
+
+/*
+ * Find controls to control amplification for destination.
+ */
+static void
+hdaa_audio_ctl_dest_amp(struct hdaa_devinfo *devinfo, nid_t nid, int index,
+    int ossdev, int depth, int need)
+{
+	struct hdaa_audio_as *as = devinfo->as;
+	struct hdaa_widget *w, *wc;
+	struct hdaa_audio_ctl *ctl;
+	int i, j, consumers;
+
+	if (depth > HDA_PARSE_MAXDEPTH)
+		return;
+
+	w = hdaa_widget_get(devinfo, nid);
+	if (w == NULL || w->enable == 0)
+		return;
+
+	if (depth > 0) {
+		/* If this node produce output for several consumers,
+		   we can't touch it. */
+		consumers = 0;
+		for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+			wc = hdaa_widget_get(devinfo, i);
+			if (wc == NULL || wc->enable == 0)
+				continue;
+			for (j = 0; j < wc->nconns; j++) {
+				if (wc->connsenable[j] && wc->conns[j] == nid)
+					consumers++;
+			}
+		}
+		/* The only exception is if real HP redirection is configured
+		   and this is a duplication point.
+		   XXX: Actually exception is not completely correct.
+		   XXX: Duplication point check is not perfect. */
+		if ((consumers == 2 && (w->bindas < 0 ||
+		    as[w->bindas].hpredir < 0 || as[w->bindas].fakeredir ||
+		    (w->bindseqmask & (1 << 15)) == 0)) ||
+		    consumers > 2)
+			return;
+
+		/* Else use it's output mixer. */
+		ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid,
+		    HDAA_CTL_OUT, -1, 1);
+		if (ctl) {
+			if (HDA_CTL_GIVE(ctl) & need)
+				ctl->ossmask |= (1 << ossdev);
+			else
+				ctl->possmask |= (1 << ossdev);
+			need &= ~HDA_CTL_GIVE(ctl);
+		}
+	}
+
+	/* We must not traverse pin */
+	if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
+	    depth > 0)
+		return;
+
+	for (i = 0; i < w->nconns; i++) {
+		int tneed = need;
+		if (w->connsenable[i] == 0)
+			continue;
+		if (index >= 0 && i != index)
+			continue;
+		ctl = hdaa_audio_ctl_amp_get(devinfo, w->nid,
+		    HDAA_CTL_IN, i, 1);
+		if (ctl) {
+			if (HDA_CTL_GIVE(ctl) & tneed)
+				ctl->ossmask |= (1 << ossdev);
+			else
+				ctl->possmask |= (1 << ossdev);
+			tneed &= ~HDA_CTL_GIVE(ctl);
+		}
+		hdaa_audio_ctl_dest_amp(devinfo, w->conns[i], -1, ossdev,
+		    depth + 1, tneed);
+	}
+}
+
+/*
+ * Assign OSS names to sound sources
+ */
+static void
+hdaa_audio_assign_names(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_as *as = devinfo->as;
+	struct hdaa_widget *w;
+	int i, j;
+	int type = -1, use, used = 0;
+	static const int types[7][13] = {
+	    { SOUND_MIXER_LINE, SOUND_MIXER_LINE1, SOUND_MIXER_LINE2, 
+	      SOUND_MIXER_LINE3, -1 },	/* line */
+	    { SOUND_MIXER_MONITOR, SOUND_MIXER_MIC, -1 }, /* int mic */
+	    { SOUND_MIXER_MIC, SOUND_MIXER_MONITOR, -1 }, /* ext mic */
+	    { SOUND_MIXER_CD, -1 },	/* cd */
+	    { SOUND_MIXER_SPEAKER, -1 },	/* speaker */
+	    { SOUND_MIXER_DIGITAL1, SOUND_MIXER_DIGITAL2, SOUND_MIXER_DIGITAL3,
+	      -1 },	/* digital */
+	    { SOUND_MIXER_LINE, SOUND_MIXER_LINE1, SOUND_MIXER_LINE2,
+	      SOUND_MIXER_LINE3, SOUND_MIXER_PHONEIN, SOUND_MIXER_PHONEOUT,
+	      SOUND_MIXER_VIDEO, SOUND_MIXER_RADIO, SOUND_MIXER_DIGITAL1,
+	      SOUND_MIXER_DIGITAL2, SOUND_MIXER_DIGITAL3, SOUND_MIXER_MONITOR,
+	      -1 }	/* others */
+	};
+
+	/* Surely known names */
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->bindas == -1)
+			continue;
+		use = -1;
+		switch (w->type) {
+		case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
+			if (as[w->bindas].dir == HDAA_CTL_OUT)
+				break;
+			type = -1;
+			switch (w->wclass.pin.config & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) {
+			case HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN:
+				type = 0;
+				break;
+			case HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN:
+				if ((w->wclass.pin.config & HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK)
+				    == HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK)
+					break;
+				type = 1;
+				break;
+			case HDA_CONFIG_DEFAULTCONF_DEVICE_CD:
+				type = 3;
+				break;
+			case HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER:
+				type = 4;
+				break;
+			case HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_IN:
+			case HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_IN:
+				type = 5;
+				break;
+			}
+			if (type == -1)
+				break;
+			j = 0;
+			while (types[type][j] >= 0 &&
+			    (used & (1 << types[type][j])) != 0) {
+				j++;
+			}
+			if (types[type][j] >= 0)
+				use = types[type][j];
+			break;
+		case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT:
+			use = SOUND_MIXER_PCM;
+			break;
+		case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET:
+			use = SOUND_MIXER_SPEAKER;
+			break;
+		default:
+			break;
+		}
+		if (use >= 0) {
+			w->ossdev = use;
+			used |= (1 << use);
+		}
+	}
+	/* Semi-known names */
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->ossdev >= 0)
+			continue;
+		if (w->bindas == -1)
+			continue;
+		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+			continue;
+		if (as[w->bindas].dir == HDAA_CTL_OUT)
+			continue;
+		type = -1;
+		switch (w->wclass.pin.config & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) {
+		case HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT:
+		case HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER:
+		case HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT:
+		case HDA_CONFIG_DEFAULTCONF_DEVICE_AUX:
+			type = 0;
+			break;
+		case HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN:
+			type = 2;
+			break;
+		case HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_OUT:
+		case HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_OUT:
+			type = 5;
+			break;
+		}
+		if (type == -1)
+			break;
+		j = 0;
+		while (types[type][j] >= 0 &&
+		    (used & (1 << types[type][j])) != 0) {
+			j++;
+		}
+		if (types[type][j] >= 0) {
+			w->ossdev = types[type][j];
+			used |= (1 << types[type][j]);
+		}
+	}
+	/* Others */
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->ossdev >= 0)
+			continue;
+		if (w->bindas == -1)
+			continue;
+		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+			continue;
+		if (as[w->bindas].dir == HDAA_CTL_OUT)
+			continue;
+		j = 0;
+		while (types[6][j] >= 0 &&
+		    (used & (1 << types[6][j])) != 0) {
+			j++;
+		}
+		if (types[6][j] >= 0) {
+			w->ossdev = types[6][j];
+			used |= (1 << types[6][j]);
+		}
+	}
+}
+
+static void
+hdaa_audio_build_tree(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_as *as = devinfo->as;
+	int j, res;
+
+	/* Trace all associations in order of their numbers. */
+	for (j = 0; j < devinfo->ascnt; j++) {
+		if (as[j].enable == 0)
+			continue;
+		HDA_BOOTVERBOSE(
+			device_printf(devinfo->dev,
+			    "Tracing association %d (%d)\n", j, as[j].index);
+		);
+		if (as[j].dir == HDAA_CTL_OUT) {
+retry:
+			res = hdaa_audio_trace_as_out(devinfo, j, 0);
+			if (res == 0 && as[j].hpredir >= 0 &&
+			    as[j].fakeredir == 0) {
+				/* If CODEC can't do analog HP redirection
+				   try to make it using one more DAC. */
+				as[j].fakeredir = 1;
+				goto retry;
+			}
+		} else if (as[j].mixed)
+			res = hdaa_audio_trace_as_in(devinfo, j);
+		else
+			res = hdaa_audio_trace_as_in_mch(devinfo, j, 0);
+		if (res) {
+			HDA_BOOTVERBOSE(
+				device_printf(devinfo->dev,
+				    "Association %d (%d) trace succeeded\n",
+				    j, as[j].index);
+			);
+		} else {
+			HDA_BOOTVERBOSE(
+				device_printf(devinfo->dev,
+				    "Association %d (%d) trace failed\n",
+				    j, as[j].index);
+			);
+			as[j].enable = 0;
+		}
+	}
+
+	/* Look for additional DACs/ADCs. */
+	for (j = 0; j < devinfo->ascnt; j++) {
+		if (as[j].enable == 0)
+			continue;
+		hdaa_audio_adddac(devinfo, j);
+	}
+
+	/* Trace mixer and beeper pseudo associations. */
+	hdaa_audio_trace_as_extra(devinfo);
+}
+
+static void
+hdaa_audio_assign_mixers(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_as *as = devinfo->as;
+	struct hdaa_audio_ctl *ctl;
+	struct hdaa_widget *w, *cw;
+	int i, j;
+
+	/* Assign mixers to the tree. */
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT ||
+		    w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET ||
+		    (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
+		    as[w->bindas].dir == HDAA_CTL_IN)) {
+			if (w->ossdev < 0)
+				continue;
+			hdaa_audio_ctl_source_amp(devinfo, w->nid, -1,
+			    w->ossdev, 1, 0, 1);
+		} else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) {
+			hdaa_audio_ctl_dest_amp(devinfo, w->nid, -1,
+			    SOUND_MIXER_RECLEV, 0, 1);
+		} else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
+		    as[w->bindas].dir == HDAA_CTL_OUT) {
+			hdaa_audio_ctl_dest_amp(devinfo, w->nid, -1,
+			    SOUND_MIXER_VOLUME, 0, 1);
+		}
+		if (w->ossdev == SOUND_MIXER_IMIX) {
+			if (hdaa_audio_ctl_source_amp(devinfo, w->nid, -1,
+			    w->ossdev, 1, 0, 1)) {
+				/* If we are unable to control input monitor
+				   as source - try to control it as destination. */
+				hdaa_audio_ctl_dest_amp(devinfo, w->nid, -1,
+				    w->ossdev, 0, 1);
+			}
+		}
+		if (w->pflags & HDAA_ADC_MONITOR) {
+			for (j = 0; j < w->nconns; j++) {
+				if (!w->connsenable[j])
+				    continue;
+				cw = hdaa_widget_get(devinfo, w->conns[j]);
+				if (cw == NULL || cw->enable == 0)
+				    continue;
+				if (cw->bindas == -1)
+				    continue;
+				if (cw->bindas >= 0 &&
+				    as[cw->bindas].dir != HDAA_CTL_IN)
+					continue;
+				hdaa_audio_ctl_dest_amp(devinfo,
+				    w->nid, j, SOUND_MIXER_IGAIN, 0, 1);
+			}
+		}
+	}
+	/* Treat unrequired as possible. */
+	i = 0;
+	while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
+		if (ctl->ossmask == 0)
+			ctl->ossmask = ctl->possmask;
+	}
+}
+
+static void
+hdaa_audio_prepare_pin_ctrl(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_as *as = devinfo->as;
+	struct hdaa_widget *w;
+	uint32_t pincap;
+	int i;
+
+	for (i = 0; i < devinfo->nodecnt; i++) {
+		w = &devinfo->widget[i];
+		if (w == NULL)
+			continue;
+		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
+		    w->waspin == 0)
+			continue;
+
+		pincap = w->wclass.pin.cap;
+
+		/* Disable everything. */
+		w->wclass.pin.ctrl &= ~(
+		    HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE |
+		    HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE |
+		    HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE |
+		    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK);
+
+		if (w->enable == 0) {
+			/* Pin is unused so left it disabled. */
+			continue;
+		} else if (w->waspin) {
+			/* Enable input for beeper input. */
+			w->wclass.pin.ctrl |=
+			    HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE;
+		} else if (w->bindas < 0 || as[w->bindas].enable == 0) {
+			/* Pin is unused so left it disabled. */
+			continue;
+		} else if (as[w->bindas].dir == HDAA_CTL_IN) {
+			/* Input pin, configure for input. */
+			if (HDA_PARAM_PIN_CAP_INPUT_CAP(pincap))
+				w->wclass.pin.ctrl |=
+				    HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE;
+
+			if ((devinfo->quirks & HDAA_QUIRK_IVREF100) &&
+			    HDA_PARAM_PIN_CAP_VREF_CTRL_100(pincap))
+				w->wclass.pin.ctrl |=
+				    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
+				    HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_100);
+			else if ((devinfo->quirks & HDAA_QUIRK_IVREF80) &&
+			    HDA_PARAM_PIN_CAP_VREF_CTRL_80(pincap))
+				w->wclass.pin.ctrl |=
+				    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
+				    HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_80);
+			else if ((devinfo->quirks & HDAA_QUIRK_IVREF50) &&
+			    HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap))
+				w->wclass.pin.ctrl |=
+				    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
+				    HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_50);
+		} else {
+			/* Output pin, configure for output. */
+			if (HDA_PARAM_PIN_CAP_OUTPUT_CAP(pincap))
+				w->wclass.pin.ctrl |=
+				    HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
+
+			if (HDA_PARAM_PIN_CAP_HEADPHONE_CAP(pincap) &&
+			    (w->wclass.pin.config &
+			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
+			    HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT)
+				w->wclass.pin.ctrl |=
+				    HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE;
+
+			if ((devinfo->quirks & HDAA_QUIRK_OVREF100) &&
+			    HDA_PARAM_PIN_CAP_VREF_CTRL_100(pincap))
+				w->wclass.pin.ctrl |=
+				    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
+				    HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_100);
+			else if ((devinfo->quirks & HDAA_QUIRK_OVREF80) &&
+			    HDA_PARAM_PIN_CAP_VREF_CTRL_80(pincap))
+				w->wclass.pin.ctrl |=
+				    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
+				    HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_80);
+			else if ((devinfo->quirks & HDAA_QUIRK_OVREF50) &&
+			    HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap))
+				w->wclass.pin.ctrl |=
+				    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
+				    HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_50);
+		}
+	}
+}
+
+static void
+hdaa_audio_ctl_commit(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_ctl *ctl;
+	int i, z;
+
+	i = 0;
+	while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
+		if (ctl->enable == 0 || ctl->ossmask != 0) {
+			/* Mute disabled and mixer controllable controls.
+			 * Last will be initialized by mixer_init().
+			 * This expected to reduce click on startup. */
+			hdaa_audio_ctl_amp_set(ctl, HDAA_AMP_MUTE_ALL, 0, 0);
+			continue;
+		}
+		/* Init fixed controls to 0dB amplification. */
+		z = ctl->offset;
+		if (z > ctl->step)
+			z = ctl->step;
+		hdaa_audio_ctl_amp_set(ctl, HDAA_AMP_MUTE_NONE, z, z);
+	}
+}
+
+static void
+hdaa_gpio_commit(struct hdaa_devinfo *devinfo)
+{
+	uint32_t gdata, gmask, gdir;
+	int i, numgpio;
+
+	numgpio = HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap);
+	if (devinfo->gpio != 0 && numgpio != 0) {
+		gdata = hda_command(devinfo->dev,
+		    HDA_CMD_GET_GPIO_DATA(0, devinfo->nid));
+		gmask = hda_command(devinfo->dev,
+		    HDA_CMD_GET_GPIO_ENABLE_MASK(0, devinfo->nid));
+		gdir = hda_command(devinfo->dev,
+		    HDA_CMD_GET_GPIO_DIRECTION(0, devinfo->nid));
+		for (i = 0; i < numgpio; i++) {
+			if ((devinfo->gpio & HDAA_GPIO_MASK(i)) ==
+			    HDAA_GPIO_SET(i)) {
+				gdata |= (1 << i);
+				gmask |= (1 << i);
+				gdir |= (1 << i);
+			} else if ((devinfo->gpio & HDAA_GPIO_MASK(i)) ==
+			    HDAA_GPIO_CLEAR(i)) {
+				gdata &= ~(1 << i);
+				gmask |= (1 << i);
+				gdir |= (1 << i);
+			} else if ((devinfo->gpio & HDAA_GPIO_MASK(i)) ==
+			    HDAA_GPIO_DISABLE(i)) {
+				gmask &= ~(1 << i);
+			} else if ((devinfo->gpio & HDAA_GPIO_MASK(i)) ==
+			    HDAA_GPIO_INPUT(i)) {
+				gmask |= (1 << i);
+				gdir &= ~(1 << i);
+			}
+		}
+		HDA_BOOTVERBOSE(
+			device_printf(devinfo->dev, "GPIO commit\n");
+		);
+		hda_command(devinfo->dev,
+		    HDA_CMD_SET_GPIO_ENABLE_MASK(0, devinfo->nid, gmask));
+		hda_command(devinfo->dev,
+		    HDA_CMD_SET_GPIO_DIRECTION(0, devinfo->nid, gdir));
+		hda_command(devinfo->dev,
+		    HDA_CMD_SET_GPIO_DATA(0, devinfo->nid, gdata));
+		HDA_BOOTVERBOSE(
+			hdaa_dump_gpio(devinfo);
+		);
+	}
+}
+
+static void
+hdaa_gpo_commit(struct hdaa_devinfo *devinfo)
+{
+	uint32_t gdata;
+	int i, numgpo;
+
+	numgpo = HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap);
+	if (devinfo->gpo != 0 && numgpo != 0) {
+		gdata = hda_command(devinfo->dev,
+		    HDA_CMD_GET_GPO_DATA(0, devinfo->nid));
+		for (i = 0; i < numgpo; i++) {
+			if ((devinfo->gpio & HDAA_GPIO_MASK(i)) ==
+			    HDAA_GPIO_SET(i)) {
+				gdata |= (1 << i);
+			} else if ((devinfo->gpio & HDAA_GPIO_MASK(i)) ==
+			    HDAA_GPIO_CLEAR(i)) {
+				gdata &= ~(1 << i);
+			}
+		}
+		HDA_BOOTVERBOSE(
+			device_printf(devinfo->dev, "GPO commit\n");
+		);
+		hda_command(devinfo->dev,
+		    HDA_CMD_SET_GPO_DATA(0, devinfo->nid, gdata));
+		HDA_BOOTVERBOSE(
+			hdaa_dump_gpo(devinfo);
+		);
+	}
+}
+
+static void
+hdaa_audio_commit(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_widget *w;
+	int i;
+
+	/* Commit controls. */
+	hdaa_audio_ctl_commit(devinfo);
+
+	/* Commit selectors, pins and EAPD. */
+	for (i = 0; i < devinfo->nodecnt; i++) {
+		w = &devinfo->widget[i];
+		if (w == NULL)
+			continue;
+		if (w->selconn == -1)
+			w->selconn = 0;
+		if (w->nconns > 0)
+			hdaa_widget_connection_select(w, w->selconn);
+		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX ||
+		    w->waspin) {
+			hda_command(devinfo->dev,
+			    HDA_CMD_SET_PIN_WIDGET_CTRL(0, w->nid,
+			    w->wclass.pin.ctrl));
+		}
+		if (w->param.eapdbtl != HDA_INVALID) {
+			uint32_t val;
+
+			val = w->param.eapdbtl;
+			if (devinfo->quirks &
+			    HDAA_QUIRK_EAPDINV)
+				val ^= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
+			hda_command(devinfo->dev,
+			    HDA_CMD_SET_EAPD_BTL_ENABLE(0, w->nid,
+			    val));
+		}
+	}
+
+	hdaa_gpio_commit(devinfo);
+	hdaa_gpo_commit(devinfo);
+}
+
+static void
+hdaa_powerup(struct hdaa_devinfo *devinfo)
+{
+	int i;
+
+	hda_command(devinfo->dev,
+	    HDA_CMD_SET_POWER_STATE(0,
+	    devinfo->nid, HDA_CMD_POWER_STATE_D0));
+	DELAY(100);
+
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		hda_command(devinfo->dev,
+		    HDA_CMD_SET_POWER_STATE(0,
+		    i, HDA_CMD_POWER_STATE_D0));
+	}
+	DELAY(1000);
+}
+
+static int
+hdaa_pcmchannel_setup(struct hdaa_chan *ch)
+{
+	struct hdaa_devinfo *devinfo = ch->devinfo;
+	struct hdaa_audio_as *as = devinfo->as;
+	struct hdaa_widget *w;
+	uint32_t cap, fmtcap, pcmcap;
+	int i, j, ret, channels, onlystereo;
+	uint16_t pinset;
+
+	ch->caps = hdaa_caps;
+	ch->caps.fmtlist = ch->fmtlist;
+	ch->bit16 = 1;
+	ch->bit32 = 0;
+	ch->pcmrates[0] = 48000;
+	ch->pcmrates[1] = 0;
+
+	ret = 0;
+	channels = 0;
+	onlystereo = 1;
+	pinset = 0;
+	fmtcap = devinfo->supp_stream_formats;
+	pcmcap = devinfo->supp_pcm_size_rate;
+
+	for (i = 0; i < 16; i++) {
+		/* Check as is correct */
+		if (ch->as < 0)
+			break;
+		/* Cound only present DACs */
+		if (as[ch->as].dacs[ch->asindex][i] <= 0)
+			continue;
+		/* Ignore duplicates */
+		for (j = 0; j < ret; j++) {
+			if (ch->io[j] == as[ch->as].dacs[ch->asindex][i])
+				break;
+		}
+		if (j < ret)
+			continue;
+
+		w = hdaa_widget_get(devinfo, as[ch->as].dacs[ch->asindex][i]);
+		if (w == NULL || w->enable == 0)
+			continue;
+		cap = w->param.supp_stream_formats;
+		if (!HDA_PARAM_SUPP_STREAM_FORMATS_PCM(cap) &&
+		    !HDA_PARAM_SUPP_STREAM_FORMATS_AC3(cap))
+			continue;
+		/* Many CODECs does not declare AC3 support on SPDIF.
+		   I don't beleave that they doesn't support it! */
+		if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap))
+			cap |= HDA_PARAM_SUPP_STREAM_FORMATS_AC3_MASK;
+		if (ret == 0) {
+			fmtcap = cap;
+			pcmcap = w->param.supp_pcm_size_rate;
+		} else {
+			fmtcap &= cap;
+			pcmcap &= w->param.supp_pcm_size_rate;
+		}
+		ch->io[ret++] = as[ch->as].dacs[ch->asindex][i];
+		/* Do not count redirection pin/dac channels. */
+		if (i == 15 && as[ch->as].hpredir >= 0)
+			continue;
+		channels += HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) + 1;
+		if (HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) != 1)
+			onlystereo = 0;
+		pinset |= (1 << i);
+	}
+	ch->io[ret] = -1;
+	ch->channels = channels;
+
+	if (as[ch->as].fakeredir)
+		ret--;
+	/* Standard speaks only about stereo pins and playback, ... */
+	if ((!onlystereo) || as[ch->as].mixed)
+		pinset = 0;
+	/* ..., but there it gives us info about speakers layout. */
+	as[ch->as].pinset = pinset;
+
+	ch->supp_stream_formats = fmtcap;
+	ch->supp_pcm_size_rate = pcmcap;
+
+	/*
+	 *  8bit = 0
+	 * 16bit = 1
+	 * 20bit = 2
+	 * 24bit = 3
+	 * 32bit = 4
+	 */
+	if (ret > 0) {
+		i = 0;
+		if (HDA_PARAM_SUPP_STREAM_FORMATS_PCM(fmtcap)) {
+			if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT(pcmcap))
+				ch->bit16 = 1;
+			else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT(pcmcap))
+				ch->bit16 = 0;
+			if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT(pcmcap))
+				ch->bit32 = 4;
+			else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT(pcmcap))
+				ch->bit32 = 3;
+			else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT(pcmcap))
+				ch->bit32 = 2;
+			if (!(devinfo->quirks & HDAA_QUIRK_FORCESTEREO)) {
+				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 1, 0);
+				if (ch->bit32)
+					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 1, 0);
+			}
+			if (channels >= 2) {
+				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 2, 0);
+				if (ch->bit32)
+					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 2, 0);
+			}
+			if (channels == 4 || /* Any 4-channel */
+			    pinset == 0x0007 || /* 5.1 */
+			    pinset == 0x0013 || /* 5.1 */
+			    pinset == 0x0017) {  /* 7.1 */
+				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 4, 0);
+				if (ch->bit32)
+					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 4, 0);
+			}
+			if (channels == 6 || /* Any 6-channel */
+			    pinset == 0x0017) {  /* 7.1 */
+				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 6, 1);
+				if (ch->bit32)
+					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 6, 1);
+			}
+			if (channels == 8) { /* Any 8-channel */
+				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 8, 1);
+				if (ch->bit32)
+					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 8, 1);
+			}
+		}
+		if (HDA_PARAM_SUPP_STREAM_FORMATS_AC3(fmtcap)) {
+			ch->fmtlist[i++] = SND_FORMAT(AFMT_AC3, 2, 0);
+		}
+		ch->fmtlist[i] = 0;
+		i = 0;
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ(pcmcap))
+			ch->pcmrates[i++] = 8000;
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ(pcmcap))
+			ch->pcmrates[i++] = 11025;
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ(pcmcap))
+			ch->pcmrates[i++] = 16000;
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ(pcmcap))
+			ch->pcmrates[i++] = 22050;
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ(pcmcap))
+			ch->pcmrates[i++] = 32000;
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ(pcmcap))
+			ch->pcmrates[i++] = 44100;
+		/* if (HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ(pcmcap)) */
+		ch->pcmrates[i++] = 48000;
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ(pcmcap))
+			ch->pcmrates[i++] = 88200;
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ(pcmcap))
+			ch->pcmrates[i++] = 96000;
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ(pcmcap))
+			ch->pcmrates[i++] = 176400;
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ(pcmcap))
+			ch->pcmrates[i++] = 192000;
+		/* if (HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ(pcmcap)) */
+		ch->pcmrates[i] = 0;
+		if (i > 0) {
+			ch->caps.minspeed = ch->pcmrates[0];
+			ch->caps.maxspeed = ch->pcmrates[i - 1];
+		}
+	}
+
+	return (ret);
+}
+
+static void
+hdaa_create_pcms(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_audio_as *as = devinfo->as;
+	int i, j, k, apdev = 0, ardev = 0, dpdev = 0, drdev = 0;
+
+	for (i = 0; i < devinfo->ascnt; i++) {
+		if (as[i].enable == 0)
+			continue;
+		if (as[i].dir == HDAA_CTL_IN) {
+			if (as[i].digital)
+				drdev++;
+			else
+				ardev++;
+		} else {
+			if (as[i].digital)
+				dpdev++;
+			else
+				apdev++;
+		}
+	}
+	devinfo->num_devs =
+	    max(ardev, apdev) + max(drdev, dpdev);
+	devinfo->devs =
+	    (struct hdaa_pcm_devinfo *)malloc(
+	    devinfo->num_devs * sizeof(struct hdaa_pcm_devinfo),
+	    M_HDAA, M_ZERO | M_NOWAIT);
+	if (devinfo->devs == NULL) {
+		device_printf(devinfo->dev,
+		    "Unable to allocate memory for devices\n");
+		return;
+	}
+	for (i = 0; i < devinfo->num_devs; i++) {
+		devinfo->devs[i].index = i;
+		devinfo->devs[i].devinfo = devinfo;
+		devinfo->devs[i].playas = -1;
+		devinfo->devs[i].recas = -1;
+		devinfo->devs[i].digital = 255;
+	}
+	for (i = 0; i < devinfo->ascnt; i++) {
+		if (as[i].enable == 0)
+			continue;
+		for (j = 0; j < devinfo->num_devs; j++) {
+			if (devinfo->devs[j].digital != 255 &&
+			    (!devinfo->devs[j].digital) !=
+			    (!as[i].digital))
+				continue;
+			if (as[i].dir == HDAA_CTL_IN) {
+				if (devinfo->devs[j].recas >= 0)
+					continue;
+				devinfo->devs[j].recas = i;
+			} else {
+				if (devinfo->devs[j].playas >= 0)
+					continue;
+				devinfo->devs[j].playas = i;
+			}
+			for (k = 0; k < as[i].num_chans; k++) {
+				devinfo->chans[as[i].chans[k]].pdevinfo =
+				    &devinfo->devs[j];
+			}
+			devinfo->devs[j].digital = as[i].digital;
+			break;
+		}
+	}
+	for (i = 0; i < devinfo->num_devs; i++) {
+		struct hdaa_pcm_devinfo *pdevinfo = &devinfo->devs[i];
+
+		pdevinfo->dev = device_add_child(devinfo->dev, "pcm", -1);
+		device_set_ivars(pdevinfo->dev, (void *)pdevinfo);
+	}
+}
+
+static void
+hdaa_dump_ctls(struct hdaa_pcm_devinfo *pdevinfo, const char *banner, uint32_t flag)
+{
+	struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
+	struct hdaa_audio_ctl *ctl;
+	char buf[64];
+	int i, j, printed;
+
+	if (flag == 0) {
+		flag = ~(SOUND_MASK_VOLUME | SOUND_MASK_PCM |
+		    SOUND_MASK_CD | SOUND_MASK_LINE | SOUND_MASK_RECLEV |
+		    SOUND_MASK_MIC | SOUND_MASK_SPEAKER | SOUND_MASK_IGAIN |
+		    SOUND_MASK_OGAIN | SOUND_MASK_IMIX | SOUND_MASK_MONITOR);
+	}
+
+	for (j = 0; j < SOUND_MIXER_NRDEVICES; j++) {
+		if ((flag & (1 << j)) == 0)
+			continue;
+		i = 0;
+		printed = 0;
+		while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
+			if (ctl->enable == 0 ||
+			    ctl->widget->enable == 0)
+				continue;
+			if (!((pdevinfo->playas >= 0 &&
+			    ctl->widget->bindas == pdevinfo->playas) ||
+			    (pdevinfo->recas >= 0 &&
+			    ctl->widget->bindas == pdevinfo->recas) ||
+			    (ctl->widget->bindas == -2 && pdevinfo->index == 0)))
+				continue;
+			if ((ctl->ossmask & (1 << j)) == 0)
+				continue;
+
+			if (printed == 0) {
+				device_printf(pdevinfo->dev, "\n");
+				if (banner != NULL) {
+					device_printf(pdevinfo->dev, "%s", banner);
+				} else {
+					device_printf(pdevinfo->dev, "Unknown Ctl");
+				}
+				printf(" (OSS: %s)\n",
+				    hdaa_audio_ctl_ossmixer_mask2allname(1 << j,
+				    buf, sizeof(buf)));
+				device_printf(pdevinfo->dev, "   |\n");
+				printed = 1;
+			}
+			device_printf(pdevinfo->dev, "   +- ctl %2d (nid %3d %s", i,
+				ctl->widget->nid,
+				(ctl->ndir == HDAA_CTL_IN)?"in ":"out");
+			if (ctl->ndir == HDAA_CTL_IN && ctl->ndir == ctl->dir)
+				printf(" %2d): ", ctl->index);
+			else
+				printf("):    ");
+			if (ctl->step > 0) {
+				printf("%+d/%+ddB (%d steps)%s\n",
+				    (0 - ctl->offset) * (ctl->size + 1) / 4,
+				    (ctl->step - ctl->offset) * (ctl->size + 1) / 4,
+				    ctl->step + 1,
+				    ctl->mute?" + mute":"");
+			} else
+				printf("%s\n", ctl->mute?"mute":"");
+		}
+	}
+}
+
+static void
+hdaa_dump_audio_formats(device_t dev, uint32_t fcap, uint32_t pcmcap)
+{
+	uint32_t cap;
+
+	cap = fcap;
+	if (cap != 0) {
+		device_printf(dev, "     Stream cap: 0x%08x\n", cap);
+		device_printf(dev, "                ");
+		if (HDA_PARAM_SUPP_STREAM_FORMATS_AC3(cap))
+			printf(" AC3");
+		if (HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32(cap))
+			printf(" FLOAT32");
+		if (HDA_PARAM_SUPP_STREAM_FORMATS_PCM(cap))
+			printf(" PCM");
+		printf("\n");
+	}
+	cap = pcmcap;
+	if (cap != 0) {
+		device_printf(dev, "        PCM cap: 0x%08x\n", cap);
+		device_printf(dev, "                ");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT(cap))
+			printf(" 8");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT(cap))
+			printf(" 16");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT(cap))
+			printf(" 20");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT(cap))
+			printf(" 24");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT(cap))
+			printf(" 32");
+		printf(" bits,");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ(cap))
+			printf(" 8");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ(cap))
+			printf(" 11");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ(cap))
+			printf(" 16");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ(cap))
+			printf(" 22");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ(cap))
+			printf(" 32");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ(cap))
+			printf(" 44");
+		printf(" 48");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ(cap))
+			printf(" 88");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ(cap))
+			printf(" 96");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ(cap))
+			printf(" 176");
+		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ(cap))
+			printf(" 192");
+		printf(" KHz\n");
+	}
+}
+
+static void
+hdaa_dump_pin(struct hdaa_widget *w)
+{
+	uint32_t pincap;
+
+	pincap = w->wclass.pin.cap;
+
+	device_printf(w->devinfo->dev, "        Pin cap: 0x%08x\n", pincap);
+	device_printf(w->devinfo->dev, "                ");
+	if (HDA_PARAM_PIN_CAP_IMP_SENSE_CAP(pincap))
+		printf(" ISC");
+	if (HDA_PARAM_PIN_CAP_TRIGGER_REQD(pincap))
+		printf(" TRQD");
+	if (HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(pincap))
+		printf(" PDC");
+	if (HDA_PARAM_PIN_CAP_HEADPHONE_CAP(pincap))
+		printf(" HP");
+	if (HDA_PARAM_PIN_CAP_OUTPUT_CAP(pincap))
+		printf(" OUT");
+	if (HDA_PARAM_PIN_CAP_INPUT_CAP(pincap))
+		printf(" IN");
+	if (HDA_PARAM_PIN_CAP_BALANCED_IO_PINS(pincap))
+		printf(" BAL");
+	if (HDA_PARAM_PIN_CAP_HDMI(pincap))
+		printf(" HDMI");
+	if (HDA_PARAM_PIN_CAP_VREF_CTRL(pincap)) {
+		printf(" VREF[");
+		if (HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap))
+			printf(" 50");
+		if (HDA_PARAM_PIN_CAP_VREF_CTRL_80(pincap))
+			printf(" 80");
+		if (HDA_PARAM_PIN_CAP_VREF_CTRL_100(pincap))
+			printf(" 100");
+		if (HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND(pincap))
+			printf(" GROUND");
+		if (HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ(pincap))
+			printf(" HIZ");
+		printf(" ]");
+	}
+	if (HDA_PARAM_PIN_CAP_EAPD_CAP(pincap))
+		printf(" EAPD");
+	if (HDA_PARAM_PIN_CAP_DP(pincap))
+		printf(" DP");
+	if (HDA_PARAM_PIN_CAP_HBR(pincap))
+		printf(" HBR");
+	printf("\n");
+	device_printf(w->devinfo->dev, "     Pin config: 0x%08x\n",
+	    w->wclass.pin.config);
+	device_printf(w->devinfo->dev, "    Pin control: 0x%08x", w->wclass.pin.ctrl);
+	if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE)
+		printf(" HP");
+	if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE)
+		printf(" IN");
+	if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE)
+		printf(" OUT");
+	if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK)
+		printf(" VREFs");
+	printf("\n");
+}
+
+static void
+hdaa_dump_pin_config(struct hdaa_widget *w, uint32_t conf)
+{
+
+	device_printf(w->devinfo->dev, "%2d %08x %-2d %-2d "
+	    "%-13s %-5s %-7s %-10s %-7s %d%s\n",
+	    w->nid, conf,
+	    HDA_CONFIG_DEFAULTCONF_ASSOCIATION(conf),
+	    HDA_CONFIG_DEFAULTCONF_SEQUENCE(conf),
+	    HDA_DEVS[HDA_CONFIG_DEFAULTCONF_DEVICE(conf)],
+	    HDA_CONNS[HDA_CONFIG_DEFAULTCONF_CONNECTIVITY(conf)],
+	    HDA_CONNECTORS[HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE(conf)],
+	    HDA_LOCS[HDA_CONFIG_DEFAULTCONF_LOCATION(conf)],
+	    HDA_COLORS[HDA_CONFIG_DEFAULTCONF_COLOR(conf)],
+	    HDA_CONFIG_DEFAULTCONF_MISC(conf),
+	    (w->enable == 0)?" DISA":"");
+}
+
+static void
+hdaa_dump_pin_configs(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_widget *w;
+	int i;
+
+	device_printf(devinfo->dev, "nid   0x    as seq "
+	    "device       conn  jack    loc        color   misc\n");
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL)
+			continue;
+		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+			continue;
+		hdaa_dump_pin_config(w, w->wclass.pin.config);
+	}
+}
+
+static void
+hdaa_dump_amp(device_t dev, uint32_t cap, char *banner)
+{
+	device_printf(dev, "     %s amp: 0x%08x\n", banner, cap);
+	device_printf(dev, "                 "
+	    "mute=%d step=%d size=%d offset=%d\n",
+	    HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(cap),
+	    HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(cap),
+	    HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(cap),
+	    HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(cap));
+}
+
+static void
+hdaa_dump_nodes(struct hdaa_devinfo *devinfo)
+{
+	static char *ossname[] = SOUND_DEVICE_NAMES;
+	struct hdaa_widget *w, *cw;
+	char buf[64];
+	int i, j;
+
+	device_printf(devinfo->dev, "\n");
+	device_printf(devinfo->dev, "Default Parameter\n");
+	device_printf(devinfo->dev, "-----------------\n");
+	hdaa_dump_audio_formats(devinfo->dev,
+	    devinfo->supp_stream_formats,
+	    devinfo->supp_pcm_size_rate);
+	device_printf(devinfo->dev, "         IN amp: 0x%08x\n",
+	    devinfo->inamp_cap);
+	device_printf(devinfo->dev, "        OUT amp: 0x%08x\n",
+	    devinfo->outamp_cap);
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL) {
+			device_printf(devinfo->dev, "Ghost widget nid=%d\n", i);
+			continue;
+		}
+		device_printf(devinfo->dev, "\n");
+		device_printf(devinfo->dev, "            nid: %d%s\n", w->nid,
+		    (w->enable == 0) ? " [DISABLED]" : "");
+		device_printf(devinfo->dev, "           Name: %s\n", w->name);
+		device_printf(devinfo->dev, "     Widget cap: 0x%08x\n",
+		    w->param.widget_cap);
+		if (w->param.widget_cap & 0x0ee1) {
+			device_printf(devinfo->dev, "                ");
+			if (HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP(w->param.widget_cap))
+			    printf(" LRSWAP");
+			if (HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL(w->param.widget_cap))
+			    printf(" PWR");
+			if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap))
+			    printf(" DIGITAL");
+			if (HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP(w->param.widget_cap))
+			    printf(" UNSOL");
+			if (HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET(w->param.widget_cap))
+			    printf(" PROC");
+			if (HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE(w->param.widget_cap))
+			    printf(" STRIPE");
+			j = HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap);
+			if (j == 1)
+			    printf(" STEREO");
+			else if (j > 1)
+			    printf(" %dCH", j + 1);
+			printf("\n");
+		}
+		if (w->bindas != -1) {
+			device_printf(devinfo->dev, "    Association: %d (0x%08x)\n",
+			    w->bindas, w->bindseqmask);
+		}
+		if (w->ossmask != 0 || w->ossdev >= 0) {
+			device_printf(devinfo->dev, "            OSS: %s",
+			    hdaa_audio_ctl_ossmixer_mask2allname(w->ossmask, buf, sizeof(buf)));
+			if (w->ossdev >= 0)
+			    printf(" (%s)", ossname[w->ossdev]);
+			printf("\n");
+		}
+		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT ||
+		    w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) {
+			hdaa_dump_audio_formats(devinfo->dev,
+			    w->param.supp_stream_formats,
+			    w->param.supp_pcm_size_rate);
+		} else if (w->type ==
+		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX || w->waspin)
+			hdaa_dump_pin(w);
+		if (w->param.eapdbtl != HDA_INVALID)
+			device_printf(devinfo->dev, "           EAPD: 0x%08x\n",
+			    w->param.eapdbtl);
+		if (HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP(w->param.widget_cap) &&
+		    w->param.outamp_cap != 0)
+			hdaa_dump_amp(devinfo->dev, w->param.outamp_cap, "Output");
+		if (HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP(w->param.widget_cap) &&
+		    w->param.inamp_cap != 0)
+			hdaa_dump_amp(devinfo->dev, w->param.inamp_cap, " Input");
+		if (w->nconns > 0) {
+			device_printf(devinfo->dev, "    connections: %d\n", w->nconns);
+			device_printf(devinfo->dev, "          |\n");
+		}
+		for (j = 0; j < w->nconns; j++) {
+			cw = hdaa_widget_get(devinfo, w->conns[j]);
+			device_printf(devinfo->dev, "          + %s<- nid=%d [%s]",
+			    (w->connsenable[j] == 0)?"[DISABLED] ":"",
+			    w->conns[j], (cw == NULL) ? "GHOST!" : cw->name);
+			if (cw == NULL)
+				printf(" [UNKNOWN]");
+			else if (cw->enable == 0)
+				printf(" [DISABLED]");
+			if (w->nconns > 1 && w->selconn == j && w->type !=
+			    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
+				printf(" (selected)");
+			printf("\n");
+		}
+	}
+
+}
+
+static void
+hdaa_dump_dst_nid(struct hdaa_pcm_devinfo *pdevinfo, nid_t nid, int depth)
+{
+	struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
+	struct hdaa_widget *w, *cw;
+	char buf[64];
+	int i, printed = 0;
+
+	if (depth > HDA_PARSE_MAXDEPTH)
+		return;
+
+	w = hdaa_widget_get(devinfo, nid);
+	if (w == NULL || w->enable == 0)
+		return;
+
+	if (depth == 0)
+		device_printf(pdevinfo->dev, "%*s", 4, "");
+	else
+		device_printf(pdevinfo->dev, "%*s  + <- ", 4 + (depth - 1) * 7, "");
+	printf("nid=%d [%s]", w->nid, w->name);
+
+	if (depth > 0) {
+		if (w->ossmask == 0) {
+			printf("\n");
+			return;
+		}
+		printf(" [src: %s]", 
+		    hdaa_audio_ctl_ossmixer_mask2allname(
+			w->ossmask, buf, sizeof(buf)));
+		if (w->ossdev >= 0) {
+			printf("\n");
+			return;
+		}
+	}
+	printf("\n");
+
+	for (i = 0; i < w->nconns; i++) {
+		if (w->connsenable[i] == 0)
+			continue;
+		cw = hdaa_widget_get(devinfo, w->conns[i]);
+		if (cw == NULL || cw->enable == 0 || cw->bindas == -1)
+			continue;
+		if (printed == 0) {
+			device_printf(pdevinfo->dev, "%*s  |\n", 4 + (depth) * 7, "");
+			printed = 1;
+		}
+		hdaa_dump_dst_nid(pdevinfo, w->conns[i], depth + 1);
+	}
+
+}
+
+static void
+hdaa_dump_dac(struct hdaa_pcm_devinfo *pdevinfo)
+{
+	struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
+	struct hdaa_audio_as *as;
+	struct hdaa_widget *w;
+	int i, printed = 0;
+
+	if (pdevinfo->playas < 0)
+		return;
+
+	as = &devinfo->as[pdevinfo->playas];
+	for (i = 0; i < 16; i++) {
+		if (as->pins[i] <= 0)
+			continue;
+		w = hdaa_widget_get(devinfo, as->pins[i]);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (printed == 0) {
+			printed = 1;
+			device_printf(pdevinfo->dev, "\n");
+			device_printf(pdevinfo->dev, "Playback:\n");
+		}
+		device_printf(pdevinfo->dev, "\n");
+		hdaa_dump_dst_nid(pdevinfo, as->pins[i], 0);
+	}
+}
+
+static void
+hdaa_dump_adc(struct hdaa_pcm_devinfo *pdevinfo)
+{
+	struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
+	struct hdaa_widget *w;
+	int i;
+	int printed = 0;
+
+	if (pdevinfo->recas < 0)
+		return;
+
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT)
+			continue;
+		if (w->bindas != pdevinfo->recas)
+			continue;
+		if (printed == 0) {
+			printed = 1;
+			device_printf(pdevinfo->dev, "\n");
+			device_printf(pdevinfo->dev, "Record:\n");
+		}
+		device_printf(pdevinfo->dev, "\n");
+		hdaa_dump_dst_nid(pdevinfo, i, 0);
+	}
+}
+
+static void
+hdaa_dump_mix(struct hdaa_pcm_devinfo *pdevinfo)
+{
+	struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
+	struct hdaa_widget *w;
+	int i;
+	int printed = 0;
+
+	if (pdevinfo->index != 0)
+		return;
+
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->enable == 0)
+			continue;
+		if (w->ossdev != SOUND_MIXER_IMIX)
+			continue;
+		if (printed == 0) {
+			printed = 1;
+			device_printf(pdevinfo->dev, "\n");
+			device_printf(pdevinfo->dev, "Input Mix:\n");
+		}
+		device_printf(pdevinfo->dev, "\n");
+		hdaa_dump_dst_nid(pdevinfo, i, 0);
+	}
+}
+
+static void
+hdaa_dump_pcmchannels(struct hdaa_pcm_devinfo *pdevinfo)
+{
+	struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
+	nid_t *nids;
+	int chid, i;
+
+	if (pdevinfo->playas >= 0) {
+		device_printf(pdevinfo->dev, "\n");
+		device_printf(pdevinfo->dev, "Playback:\n");
+		device_printf(pdevinfo->dev, "\n");
+		chid = devinfo->as[pdevinfo->playas].chans[0];
+		hdaa_dump_audio_formats(pdevinfo->dev,
+		    devinfo->chans[chid].supp_stream_formats,
+		    devinfo->chans[chid].supp_pcm_size_rate);
+		for (i = 0; i < devinfo->as[pdevinfo->playas].num_chans; i++) {
+			chid = devinfo->as[pdevinfo->playas].chans[i];
+			device_printf(pdevinfo->dev, "            DAC:");
+			for (nids = devinfo->chans[chid].io; *nids != -1; nids++)
+				printf(" %d", *nids);
+			printf("\n");
+		}
+	}
+	if (pdevinfo->recas >= 0) {
+		device_printf(pdevinfo->dev, "\n");
+		device_printf(pdevinfo->dev, "Record:\n");
+		device_printf(pdevinfo->dev, "\n");
+		chid = devinfo->as[pdevinfo->recas].chans[0];
+		hdaa_dump_audio_formats(pdevinfo->dev,
+		    devinfo->chans[chid].supp_stream_formats,
+		    devinfo->chans[chid].supp_pcm_size_rate);
+		for (i = 0; i < devinfo->as[pdevinfo->recas].num_chans; i++) {
+			chid = devinfo->as[pdevinfo->recas].chans[i];
+			device_printf(pdevinfo->dev, "            DAC:");
+			for (nids = devinfo->chans[chid].io; *nids != -1; nids++)
+				printf(" %d", *nids);
+			printf("\n");
+		}
+	}
+}
+
+static void
+hdaa_pindump(device_t dev)
+{
+	struct hdaa_devinfo *devinfo = device_get_softc(dev);
+	struct hdaa_widget *w;
+	uint32_t res, pincap, delay;
+	int i;
+
+	device_printf(dev, "Dumping AFG pins:\n");
+	device_printf(dev, "nid   0x    as seq "
+	    "device       conn  jack    loc        color   misc\n");
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL || w->type !=
+		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+			continue;
+		hdaa_dump_pin_config(w, w->wclass.pin.config);
+		pincap = w->wclass.pin.cap;
+		device_printf(dev, "    Caps: %2s %3s %2s %4s %4s",
+		    HDA_PARAM_PIN_CAP_INPUT_CAP(pincap)?"IN":"",
+		    HDA_PARAM_PIN_CAP_OUTPUT_CAP(pincap)?"OUT":"",
+		    HDA_PARAM_PIN_CAP_HEADPHONE_CAP(pincap)?"HP":"",
+		    HDA_PARAM_PIN_CAP_EAPD_CAP(pincap)?"EAPD":"",
+		    HDA_PARAM_PIN_CAP_VREF_CTRL(pincap)?"VREF":"");
+		if (HDA_PARAM_PIN_CAP_IMP_SENSE_CAP(pincap) ||
+		    HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(pincap)) {
+			if (HDA_PARAM_PIN_CAP_TRIGGER_REQD(pincap)) {
+				delay = 0;
+				hda_command(dev,
+				    HDA_CMD_SET_PIN_SENSE(0, w->nid, 0));
+				do {
+					res = hda_command(dev,
+					    HDA_CMD_GET_PIN_SENSE(0, w->nid));
+					if (res != 0x7fffffff && res != 0xffffffff)
+						break;
+					DELAY(10);
+				} while (++delay < 10000);
+			} else {
+				delay = 0;
+				res = hda_command(dev, HDA_CMD_GET_PIN_SENSE(0,
+				    w->nid));
+			}
+			printf(" Sense: 0x%08x (%sconnected)", res,
+			    (res & HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT) ?
+			     "" : "dis");
+			if (delay > 0)
+				printf(" delay %dus", delay * 10);
+		}
+		printf("\n");
+	}
+	device_printf(dev,
+	    "NumGPIO=%d NumGPO=%d NumGPI=%d GPIWake=%d GPIUnsol=%d\n",
+	    HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap),
+	    HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap),
+	    HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->gpio_cap),
+	    HDA_PARAM_GPIO_COUNT_GPI_WAKE(devinfo->gpio_cap),
+	    HDA_PARAM_GPIO_COUNT_GPI_UNSOL(devinfo->gpio_cap));
+	hdaa_dump_gpi(devinfo);
+	hdaa_dump_gpio(devinfo);
+	hdaa_dump_gpo(devinfo);
+}
+
+static void
+hdaa_configure(device_t dev)
+{
+	struct hdaa_devinfo *devinfo = device_get_softc(dev);
+	struct hdaa_audio_ctl *ctl;
+	int i;
+
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Applying built-in patches...\n");
+	);
+	hdaa_patch(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Applying local patches...\n");
+	);
+	hdaa_local_patch(devinfo);
+	hdaa_audio_postprocess(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Parsing Ctls...\n");
+	);
+	hdaa_audio_ctl_parse(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Disabling nonaudio...\n");
+	);
+	hdaa_audio_disable_nonaudio(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Disabling useless...\n");
+	);
+	hdaa_audio_disable_useless(devinfo);
+	HDA_BOOTVERBOSE(
+		device_printf(dev, "Patched pins configuration:\n");
+		hdaa_dump_pin_configs(devinfo);
+	);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Parsing pin associations...\n");
+	);
+	hdaa_audio_as_parse(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Building AFG tree...\n");
+	);
+	hdaa_audio_build_tree(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Disabling unassociated "
+		    "widgets...\n");
+	);
+	hdaa_audio_disable_unas(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Disabling nonselected "
+		    "inputs...\n");
+	);
+	hdaa_audio_disable_notselected(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Disabling useless...\n");
+	);
+	hdaa_audio_disable_useless(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Disabling "
+		    "crossassociatement connections...\n");
+	);
+	hdaa_audio_disable_crossas(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Disabling useless...\n");
+	);
+	hdaa_audio_disable_useless(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Binding associations to channels...\n");
+	);
+	hdaa_audio_bind_as(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Assigning names to signal sources...\n");
+	);
+	hdaa_audio_assign_names(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Assigning mixers to the tree...\n");
+	);
+	hdaa_audio_assign_mixers(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Preparing pin controls...\n");
+	);
+	hdaa_audio_prepare_pin_ctrl(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "AFG commit...\n");
+	);
+	hdaa_audio_commit(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Applying direct built-in patches...\n");
+	);
+	hdaa_patch_direct(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "HP switch init...\n");
+	);
+	hdaa_hp_switch_init(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Creating PCM devices...\n");
+	);
+	hdaa_create_pcms(devinfo);
+
+	HDA_BOOTVERBOSE(
+		if (devinfo->quirks != 0) {
+			device_printf(dev, "FG config/quirks:");
+			for (i = 0; i < HDAA_QUIRKS_TAB_LEN; i++) {
+				if ((devinfo->quirks &
+				    hdaa_quirks_tab[i].value) ==
+				    hdaa_quirks_tab[i].value)
+					printf(" %s", hdaa_quirks_tab[i].key);
+			}
+			printf("\n");
+		}
+
+		device_printf(dev, "\n");
+		device_printf(dev, "+-------------------+\n");
+		device_printf(dev, "| DUMPING HDA NODES |\n");
+		device_printf(dev, "+-------------------+\n");
+		hdaa_dump_nodes(devinfo);
+	);
+
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "\n");
+		device_printf(dev, "+------------------------+\n");
+		device_printf(dev, "| DUMPING HDA AMPLIFIERS |\n");
+		device_printf(dev, "+------------------------+\n");
+		device_printf(dev, "\n");
+		i = 0;
+		while ((ctl = hdaa_audio_ctl_each(devinfo, &i)) != NULL) {
+			device_printf(dev, "%3d: nid %3d %s (%s) index %d", i,
+			    (ctl->widget != NULL) ? ctl->widget->nid : -1,
+			    (ctl->ndir == HDAA_CTL_IN)?"in ":"out",
+			    (ctl->dir == HDAA_CTL_IN)?"in ":"out",
+			    ctl->index);
+			if (ctl->childwidget != NULL)
+				printf(" cnid %3d", ctl->childwidget->nid);
+			else
+				printf("         ");
+			printf(" ossmask=0x%08x\n",
+			    ctl->ossmask);
+			device_printf(dev, 
+			    "       mute: %d step: %3d size: %3d off: %3d%s\n",
+			    ctl->mute, ctl->step, ctl->size, ctl->offset,
+			    (ctl->enable == 0) ? " [DISABLED]" : 
+			    ((ctl->ossmask == 0) ? " [UNUSED]" : ""));
+		}
+	);
+
+	HDA_BOOTVERBOSE(
+		device_printf(dev, "\n");
+	);
+}
+
+static void
+hdaa_unconfigure(device_t dev)
+{
+	struct hdaa_devinfo *devinfo = device_get_softc(dev);
+	struct hdaa_widget *w;
+	int i, j;
+
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "HP switch deinit...\n");
+	);
+	hdaa_hp_switch_deinit(devinfo);
+	free(devinfo->ctl, M_HDAA);
+	devinfo->ctl = NULL;
+	devinfo->ctlcnt = 0;
+	free(devinfo->as, M_HDAA);
+	devinfo->as = NULL;
+	devinfo->ascnt = 0;
+	free(devinfo->devs, M_HDAA);
+	devinfo->devs = NULL;
+	devinfo->num_devs = 0;
+	free(devinfo->chans, M_HDAA);
+	devinfo->chans = NULL;
+	devinfo->num_chans = 0;
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL)
+			continue;
+		w->enable = 1;
+		w->selconn = -1;
+		w->pflags = 0;
+		w->bindas = -1;
+		w->bindseqmask = 0;
+		w->ossdev = -1;
+		w->ossmask = 0;
+		for (j = 0; j < w->nconns; j++)
+			w->connsenable[j] = 1;
+		w->wclass.pin.config = w->wclass.pin.newconf;
+	}
+}
+
+static int
+hdaa_sysctl_gpi_state(SYSCTL_HANDLER_ARGS)
+{
+	struct hdaa_devinfo *devinfo = oidp->oid_arg1;
+	device_t dev = devinfo->dev;
+	char buf[256];
+	int n = 0, i, numgpi;
+	uint32_t data = 0;
+
+	buf[0] = 0;
+	hdaa_lock(devinfo);
+	numgpi = HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->gpio_cap);
+	if (numgpi > 0) {
+		data = hda_command(dev,
+		    HDA_CMD_GET_GPI_DATA(0, devinfo->nid));
+	}
+	hdaa_unlock(devinfo);
+	for (i = 0; i < numgpi; i++) {
+		n += snprintf(buf + n, sizeof(buf) - n, "%s%d=%d",
+		    n != 0 ? " " : "", i, ((data >> i) & 1));
+	}
+	return (sysctl_handle_string(oidp, buf, sizeof(buf), req));
+}
+
+static int
+hdaa_sysctl_gpio_state(SYSCTL_HANDLER_ARGS)
+{
+	struct hdaa_devinfo *devinfo = oidp->oid_arg1;
+	device_t dev = devinfo->dev;
+	char buf[256];
+	int n = 0, i, numgpio;
+	uint32_t data = 0, enable = 0, dir = 0;
+
+	buf[0] = 0;
+	hdaa_lock(devinfo);
+	numgpio = HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap);
+	if (numgpio > 0) {
+		data = hda_command(dev,
+		    HDA_CMD_GET_GPIO_DATA(0, devinfo->nid));
+		enable = hda_command(dev,
+		    HDA_CMD_GET_GPIO_ENABLE_MASK(0, devinfo->nid));
+		dir = hda_command(dev,
+		    HDA_CMD_GET_GPIO_DIRECTION(0, devinfo->nid));
+	}
+	hdaa_unlock(devinfo);
+	for (i = 0; i < numgpio; i++) {
+		n += snprintf(buf + n, sizeof(buf) - n, "%s%d=",
+		    n != 0 ? " " : "", i);
+		if ((enable & (1 << i)) == 0) {
+			n += snprintf(buf + n, sizeof(buf) - n, "disabled");
+			continue;
+		}
+		n += snprintf(buf + n, sizeof(buf) - n, "%sput(%d)",
+		    ((dir >> i) & 1) ? "out" : "in", ((data >> i) & 1));
+	}
+	return (sysctl_handle_string(oidp, buf, sizeof(buf), req));
+}
+
+static int
+hdaa_sysctl_gpio_config(SYSCTL_HANDLER_ARGS)
+{
+	struct hdaa_devinfo *devinfo = oidp->oid_arg1;
+	char buf[256];
+	int error, n = 0, i, numgpio;
+	uint32_t gpio, x;
+
+	gpio = devinfo->newgpio;
+	numgpio = HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->gpio_cap);
+	buf[0] = 0;
+	for (i = 0; i < numgpio; i++) {
+		x = (gpio & HDAA_GPIO_MASK(i)) >> HDAA_GPIO_SHIFT(i);
+		n += snprintf(buf + n, sizeof(buf) - n, "%s%d=%s",
+		    n != 0 ? " " : "", i, HDA_GPIO_ACTIONS[x]);
+	}
+	error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+	if (strncmp(buf, "0x", 2) == 0)
+		gpio = strtol(buf + 2, NULL, 16);
+	else
+		gpio = hdaa_gpio_patch(gpio, buf);
+	hdaa_lock(devinfo);
+	devinfo->newgpio = devinfo->gpio = gpio;
+	hdaa_gpio_commit(devinfo);
+	hdaa_unlock(devinfo);
+	return (0);
+}
+
+static int
+hdaa_sysctl_gpo_state(SYSCTL_HANDLER_ARGS)
+{
+	struct hdaa_devinfo *devinfo = oidp->oid_arg1;
+	device_t dev = devinfo->dev;
+	char buf[256];
+	int n = 0, i, numgpo;
+	uint32_t data = 0;
+
+	buf[0] = 0;
+	hdaa_lock(devinfo);
+	numgpo = HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap);
+	if (numgpo > 0) {
+		data = hda_command(dev,
+		    HDA_CMD_GET_GPO_DATA(0, devinfo->nid));
+	}
+	hdaa_unlock(devinfo);
+	for (i = 0; i < numgpo; i++) {
+		n += snprintf(buf + n, sizeof(buf) - n, "%s%d=%d",
+		    n != 0 ? " " : "", i, ((data >> i) & 1));
+	}
+	return (sysctl_handle_string(oidp, buf, sizeof(buf), req));
+}
+
+static int
+hdaa_sysctl_gpo_config(SYSCTL_HANDLER_ARGS)
+{
+	struct hdaa_devinfo *devinfo = oidp->oid_arg1;
+	char buf[256];
+	int error, n = 0, i, numgpo;
+	uint32_t gpo, x;
+
+	gpo = devinfo->newgpo;
+	numgpo = HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->gpio_cap);
+	buf[0] = 0;
+	for (i = 0; i < numgpo; i++) {
+		x = (gpo & HDAA_GPIO_MASK(i)) >> HDAA_GPIO_SHIFT(i);
+		n += snprintf(buf + n, sizeof(buf) - n, "%s%d=%s",
+		    n != 0 ? " " : "", i, HDA_GPIO_ACTIONS[x]);
+	}
+	error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+	if (strncmp(buf, "0x", 2) == 0)
+		gpo = strtol(buf + 2, NULL, 16);
+	else
+		gpo = hdaa_gpio_patch(gpo, buf);
+	hdaa_lock(devinfo);
+	devinfo->newgpo = devinfo->gpo = gpo;
+	hdaa_gpo_commit(devinfo);
+	hdaa_unlock(devinfo);
+	return (0);
+}
+
+static int
+hdaa_sysctl_reconfig(SYSCTL_HANDLER_ARGS)
+{
+	device_t dev;
+	struct hdaa_devinfo *devinfo;
+	int error, val;
+
+	dev = oidp->oid_arg1;
+	devinfo = device_get_softc(dev);
+	if (devinfo == NULL)
+		return (EINVAL);
+	val = 0;
+	error = sysctl_handle_int(oidp, &val, 0, req);
+	if (error != 0 || req->newptr == NULL || val == 0)
+		return (error);
+
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Reconfiguration...\n");
+	);
+	if ((error = device_delete_children(dev)) != 0)
+		return (error);
+	hdaa_lock(devinfo);
+	hdaa_unconfigure(dev);
+	hdaa_configure(dev);
+	hdaa_unlock(devinfo);
+	bus_generic_attach(dev);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Reconfiguration done\n");
+	);
+	return (0);
+}
+
+static int
+hdaa_suspend(device_t dev)
+{
+	struct hdaa_devinfo *devinfo = device_get_softc(dev);
+	int i;
+
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Suspend...\n");
+	);
+	hdaa_lock(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Stop streams...\n");
+	);
+	for (i = 0; i < devinfo->num_chans; i++) {
+		if (devinfo->chans[i].flags & HDAA_CHN_RUNNING) {
+			devinfo->chans[i].flags |= HDAA_CHN_SUSPEND;
+			hdaa_channel_stop(&devinfo->chans[i]);
+		}
+	}
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "HP switch deinit...\n");
+	);
+	hdaa_hp_switch_deinit(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Power down FG"
+		    " nid=%d to the D3 state...\n",
+		    devinfo->nid);
+	);
+	hda_command(devinfo->dev,
+	    HDA_CMD_SET_POWER_STATE(0,
+	    devinfo->nid, HDA_CMD_POWER_STATE_D3));
+	callout_stop(&devinfo->poll_jack);
+	hdaa_unlock(devinfo);
+	callout_drain(&devinfo->poll_jack);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Suspend done\n");
+	);
+	return (0);
+}
+
+static int
+hdaa_resume(device_t dev)
+{
+	struct hdaa_devinfo *devinfo = device_get_softc(dev);
+	int i;
+
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Resume...\n");
+	);
+	hdaa_lock(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Power up audio FG nid=%d...\n",
+		    devinfo->nid);
+	);
+	hdaa_powerup(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "AFG commit...\n");
+	);
+	hdaa_audio_commit(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Applying direct built-in patches...\n");
+	);
+	hdaa_patch_direct(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "HP switch init...\n");
+	);
+	hdaa_hp_switch_init(devinfo);
+
+	hdaa_unlock(devinfo);
+	for (i = 0; i < devinfo->num_devs; i++) {
+		struct hdaa_pcm_devinfo *pdevinfo = &devinfo->devs[i];
+		HDA_BOOTHVERBOSE(
+			device_printf(pdevinfo->dev,
+			    "OSS mixer reinitialization...\n");
+		);
+		if (mixer_reinit(pdevinfo->dev) == -1)
+			device_printf(pdevinfo->dev,
+			    "unable to reinitialize the mixer\n");
+	}
+	hdaa_lock(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Start streams...\n");
+	);
+	for (i = 0; i < devinfo->num_chans; i++) {
+		if (devinfo->chans[i].flags & HDAA_CHN_SUSPEND) {
+			devinfo->chans[i].flags &= ~HDAA_CHN_SUSPEND;
+			hdaa_channel_start(&devinfo->chans[i]);
+		}
+	}
+	hdaa_unlock(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Resume done\n");
+	);
+	return (0);
+}
+
+static int
+hdaa_probe(device_t dev)
+{
+	char buf[128];
+
+	if (hda_get_node_type(dev) != HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO)
+		return (ENXIO);
+	snprintf(buf, sizeof(buf), "%s Audio Function Group",
+	    device_get_desc(device_get_parent(dev)));
+	device_set_desc_copy(dev, buf);
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+hdaa_attach(device_t dev)
+{
+	struct hdaa_devinfo *devinfo = device_get_softc(dev);
+	uint32_t res;
+	nid_t nid = hda_get_node_id(dev);
+
+	devinfo->dev = dev;
+	devinfo->lock = HDAC_GET_MTX(device_get_parent(dev), dev);
+	devinfo->nid = nid;
+	devinfo->newquirks = -1;
+	devinfo->newgpio = -1;
+	devinfo->newgpo = -1;
+	callout_init(&devinfo->poll_jack, CALLOUT_MPSAFE);
+	devinfo->poll_ival = hz;
+
+	hdaa_lock(devinfo);
+	res = hda_command(dev,
+	    HDA_CMD_GET_PARAMETER(0 , nid, HDA_PARAM_SUB_NODE_COUNT));
+	hdaa_unlock(devinfo);
+
+	devinfo->nodecnt = HDA_PARAM_SUB_NODE_COUNT_TOTAL(res);
+	devinfo->startnode = HDA_PARAM_SUB_NODE_COUNT_START(res);
+	devinfo->endnode = devinfo->startnode + devinfo->nodecnt;
+
+	HDA_BOOTVERBOSE(
+		device_printf(dev,
+		    "Audio Function Group at nid=%d: %d subnodes %d-%d\n",
+		    nid, devinfo->nodecnt,
+		    devinfo->startnode, devinfo->endnode - 1);
+	);
+
+	if (devinfo->nodecnt > 0)
+		devinfo->widget = (struct hdaa_widget *)malloc(
+		    sizeof(*(devinfo->widget)) * devinfo->nodecnt, M_HDAA,
+		    M_WAITOK | M_ZERO);
+	else
+		devinfo->widget = NULL;
+
+	hdaa_lock(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Powering up...\n");
+	);
+	hdaa_powerup(devinfo);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Parsing audio FG...\n");
+	);
+	hdaa_audio_parse(devinfo);
+	HDA_BOOTVERBOSE(
+		device_printf(dev, "Original pins configuration:\n");
+		hdaa_dump_pin_configs(devinfo);
+	);
+	hdaa_configure(dev);
+	hdaa_unlock(devinfo);
+
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+	    "config", CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE,
+	    &devinfo->newquirks, sizeof(&devinfo->newquirks),
+	    hdaa_sysctl_quirks, "A", "Configuration options");
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+	    "gpi_state", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+	    devinfo, sizeof(devinfo),
+	    hdaa_sysctl_gpi_state, "A", "GPI state");
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+	    "gpio_state", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+	    devinfo, sizeof(devinfo),
+	    hdaa_sysctl_gpio_state, "A", "GPIO state");
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+	    "gpio_config", CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE,
+	    devinfo, sizeof(devinfo),
+	    hdaa_sysctl_gpio_config, "A", "GPIO configuration");
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+	    "gpo_state", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+	    devinfo, sizeof(devinfo),
+	    hdaa_sysctl_gpo_state, "A", "GPO state");
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+	    "gpo_config", CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE,
+	    devinfo, sizeof(devinfo),
+	    hdaa_sysctl_gpo_config, "A", "GPO configuration");
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+	    "reconfig", CTLTYPE_INT | CTLFLAG_RW,
+	    dev, sizeof(dev),
+	    hdaa_sysctl_reconfig, "I", "Reprocess configuration");
+	bus_generic_attach(dev);
+	return (0);
+}
+
+static int
+hdaa_detach(device_t dev)
+{
+	struct hdaa_devinfo *devinfo = device_get_softc(dev);
+	int error;
+
+	if ((error = device_delete_children(dev)) != 0)
+		return (error);
+
+	hdaa_lock(devinfo);
+	hdaa_unconfigure(dev);
+	devinfo->poll_ival = 0;
+	callout_stop(&devinfo->poll_jack);
+	hdaa_unlock(devinfo);
+	callout_drain(&devinfo->poll_jack);
+
+	free(devinfo->widget, M_HDAA);
+	return (0);
+}
+
+static int
+hdaa_print_child(device_t dev, device_t child)
+{
+	struct hdaa_devinfo *devinfo = device_get_softc(dev);
+	struct hdaa_pcm_devinfo *pdevinfo =
+	    (struct hdaa_pcm_devinfo *)device_get_ivars(child);
+	struct hdaa_audio_as *as;
+	int retval, first = 1, i;
+
+	retval = bus_print_child_header(dev, child);
+	retval += printf(" at nid ");
+	if (pdevinfo->playas >= 0) {
+		as = &devinfo->as[pdevinfo->playas];
+		for (i = 0; i < 16; i++) {
+			if (as->pins[i] <= 0)
+				continue;
+			retval += printf("%s%d", first ? "" : ",", as->pins[i]);
+			first = 0;
+		}
+	}
+	if (pdevinfo->recas >= 0) {
+		if (pdevinfo->playas >= 0) {
+			retval += printf(" and ");
+			first = 1;
+		}
+		as = &devinfo->as[pdevinfo->recas];
+		for (i = 0; i < 16; i++) {
+			if (as->pins[i] <= 0)
+				continue;
+			retval += printf("%s%d", first ? "" : ",", as->pins[i]);
+			first = 0;
+		}
+	}
+	retval += bus_print_child_footer(dev, child);
+
+	return (retval);
+}
+
+static int
+hdaa_child_location_str(device_t dev, device_t child, char *buf,
+    size_t buflen)
+{
+	struct hdaa_devinfo *devinfo = device_get_softc(dev);
+	struct hdaa_pcm_devinfo *pdevinfo =
+	    (struct hdaa_pcm_devinfo *)device_get_ivars(child);
+	struct hdaa_audio_as *as;
+	int first = 1, i, len = 0;
+
+	len += snprintf(buf + len, buflen - len, "nid=");
+	if (pdevinfo->playas >= 0) {
+		as = &devinfo->as[pdevinfo->playas];
+		for (i = 0; i < 16; i++) {
+			if (as->pins[i] <= 0)
+				continue;
+			len += snprintf(buf + len, buflen - len,
+			    "%s%d", first ? "" : ",", as->pins[i]);
+			first = 0;
+		}
+	}
+	if (pdevinfo->recas >= 0) {
+		as = &devinfo->as[pdevinfo->recas];
+		for (i = 0; i < 16; i++) {
+			if (as->pins[i] <= 0)
+				continue;
+			len += snprintf(buf + len, buflen - len,
+			    "%s%d", first ? "" : ",", as->pins[i]);
+			first = 0;
+		}
+	}
+	return (0);
+}
+
+static void
+hdaa_stream_intr(device_t dev, int dir, int stream)
+{
+	struct hdaa_devinfo *devinfo = device_get_softc(dev);
+	struct hdaa_chan *ch;
+	int i;
+
+	for (i = 0; i < devinfo->num_chans; i++) {
+		ch = &devinfo->chans[i];
+		if (!(ch->flags & HDAA_CHN_RUNNING))
+			continue;
+		if (ch->dir == ((dir == 1) ? PCMDIR_PLAY : PCMDIR_REC) &&
+		    ch->sid == stream) {
+			hdaa_unlock(devinfo);
+			chn_intr(ch->c);
+			hdaa_lock(devinfo);
+		}
+	}
+}
+
+static void
+hdaa_unsol_intr(device_t dev, uint32_t resp)
+{
+	struct hdaa_devinfo *devinfo = device_get_softc(dev);
+	int i, tag;
+
+	tag = resp >> 26;
+	for (i = 0; i < devinfo->ascnt; i++) {
+		if (devinfo->as[i].unsol == tag)
+			hdaa_hp_switch_handler(devinfo, i);
+	}
+}
+
+static device_method_t hdaa_methods[] = {
+	/* device interface */
+	DEVMETHOD(device_probe,		hdaa_probe),
+	DEVMETHOD(device_attach,	hdaa_attach),
+	DEVMETHOD(device_detach,	hdaa_detach),
+	DEVMETHOD(device_suspend,	hdaa_suspend),
+	DEVMETHOD(device_resume,	hdaa_resume),
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	hdaa_print_child),
+	DEVMETHOD(bus_child_location_str, hdaa_child_location_str),
+	DEVMETHOD(hdac_stream_intr,	hdaa_stream_intr),
+	DEVMETHOD(hdac_unsol_intr,	hdaa_unsol_intr),
+	DEVMETHOD(hdac_pindump,		hdaa_pindump),
+	{ 0, 0 }
+};
+
+static driver_t hdaa_driver = {
+	"hdaa",
+	hdaa_methods,
+	sizeof(struct hdaa_devinfo),
+};
+
+static devclass_t hdaa_devclass;
+
+DRIVER_MODULE(snd_hda, hdacc, hdaa_driver, hdaa_devclass, 0, 0);
+
+static void
+hdaa_chan_formula(struct hdaa_devinfo *devinfo, int asid,
+    char *buf, int buflen)
+{
+	struct hdaa_audio_as *as;
+	int c;
+
+	as = &devinfo->as[asid];
+	c = devinfo->chans[as->chans[0]].channels;
+	if (c == 1)
+		snprintf(buf, buflen, "mono");
+	else if (c == 2)
+		buf[0] = 0;
+	else if (as->pinset == 0x0003)
+		snprintf(buf, buflen, "3.1");
+	else if (as->pinset == 0x0005 || as->pinset == 0x0011)
+		snprintf(buf, buflen, "4.0");
+	else if (as->pinset == 0x0007 || as->pinset == 0x0013)
+		snprintf(buf, buflen, "5.1");
+	else if (as->pinset == 0x0017)
+		snprintf(buf, buflen, "7.1");
+	else
+		snprintf(buf, buflen, "%dch", c);
+}
+
+static int
+hdaa_pcm_probe(device_t dev)
+{
+	struct hdaa_pcm_devinfo *pdevinfo =
+	    (struct hdaa_pcm_devinfo *)device_get_ivars(dev);
+	struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
+	char chans1[8], chans2[8];
+	char buf[128];
+	int loc1, loc2;
+
+	if (pdevinfo->playas >= 0)
+		loc1 = devinfo->as[pdevinfo->playas].location;
+	else
+		loc1 = devinfo->as[pdevinfo->recas].location;
+	if (pdevinfo->recas >= 0)
+		loc2 = devinfo->as[pdevinfo->recas].location;
+	else
+		loc2 = loc1;
+	if (loc1 != loc2)
+		loc1 = -2;
+	if (loc1 >= 0 && HDA_LOCS[loc1][0] == '0')
+		loc1 = -2;
+	chans1[0] = 0;
+	chans2[0] = 0;
+	if (pdevinfo->playas >= 0)
+		hdaa_chan_formula(devinfo, pdevinfo->playas,
+		    chans1, sizeof(chans1));
+	if (pdevinfo->recas >= 0)
+		hdaa_chan_formula(devinfo, pdevinfo->recas,
+		    chans2, sizeof(chans2));
+	if (chans1[0] != 0 || chans2[0] != 0) {
+		if (chans1[0] == 0 && pdevinfo->playas >= 0)
+			snprintf(chans1, sizeof(chans1), "2.0");
+		else if (chans2[0] == 0 && pdevinfo->recas >= 0)
+			snprintf(chans2, sizeof(chans2), "2.0");
+		if (strcmp(chans1, chans2) == 0)
+			chans2[0] = 0;
+	}
+	snprintf(buf, sizeof(buf), "%s PCM (%s%s%s%s%s%s%s)",
+	    device_get_desc(device_get_parent(device_get_parent(dev))),
+	    loc1 >= 0 ? HDA_LOCS[loc1] : "", loc1 >= 0 ? " " : "",
+	    (pdevinfo->digital == 3)?"DisplayPort":
+	    ((pdevinfo->digital == 2)?"HDMI":
+	    ((pdevinfo->digital)?"Digital":"Analog")),
+	    chans1[0] ? " " : "", chans1,
+	    chans2[0] ? "/" : "", chans2);
+	device_set_desc_copy(dev, buf);
+	return (BUS_PROBE_SPECIFIC);
+}
+
+static int
+hdaa_pcm_attach(device_t dev)
+{
+	struct hdaa_pcm_devinfo *pdevinfo =
+	    (struct hdaa_pcm_devinfo *)device_get_ivars(dev);
+	struct hdaa_devinfo *devinfo = pdevinfo->devinfo;
+	struct hdaa_audio_as *as;
+	char status[SND_STATUSLEN];
+	int i;
+
+	pdevinfo->chan_size = pcm_getbuffersize(dev,
+	    HDA_BUFSZ_MIN, HDA_BUFSZ_DEFAULT, HDA_BUFSZ_MAX);
+
+	HDA_BOOTVERBOSE(
+		device_printf(dev, "+--------------------------------------+\n");
+		device_printf(dev, "| DUMPING PCM Playback/Record Channels |\n");
+		device_printf(dev, "+--------------------------------------+\n");
+		hdaa_dump_pcmchannels(pdevinfo);
+		device_printf(dev, "\n");
+		device_printf(dev, "+-------------------------------+\n");
+		device_printf(dev, "| DUMPING Playback/Record Paths |\n");
+		device_printf(dev, "+-------------------------------+\n");
+		hdaa_dump_dac(pdevinfo);
+		hdaa_dump_adc(pdevinfo);
+		hdaa_dump_mix(pdevinfo);
+		device_printf(dev, "\n");
+		device_printf(dev, "+-------------------------+\n");
+		device_printf(dev, "| DUMPING Volume Controls |\n");
+		device_printf(dev, "+-------------------------+\n");
+		hdaa_dump_ctls(pdevinfo, "Master Volume", SOUND_MASK_VOLUME);
+		hdaa_dump_ctls(pdevinfo, "PCM Volume", SOUND_MASK_PCM);
+		hdaa_dump_ctls(pdevinfo, "CD Volume", SOUND_MASK_CD);
+		hdaa_dump_ctls(pdevinfo, "Microphone Volume", SOUND_MASK_MIC);
+		hdaa_dump_ctls(pdevinfo, "Microphone2 Volume", SOUND_MASK_MONITOR);
+		hdaa_dump_ctls(pdevinfo, "Line-in Volume", SOUND_MASK_LINE);
+		hdaa_dump_ctls(pdevinfo, "Speaker/Beep Volume", SOUND_MASK_SPEAKER);
+		hdaa_dump_ctls(pdevinfo, "Recording Level", SOUND_MASK_RECLEV);
+		hdaa_dump_ctls(pdevinfo, "Input Mix Level", SOUND_MASK_IMIX);
+		hdaa_dump_ctls(pdevinfo, "Input Monitoring Level", SOUND_MASK_IGAIN);
+		hdaa_dump_ctls(pdevinfo, NULL, 0);
+		device_printf(dev, "\n");
+	);
+
+	if (resource_int_value(device_get_name(dev),
+	    device_get_unit(dev), "blocksize", &i) == 0 && i > 0) {
+		i &= HDA_BLK_ALIGN;
+		if (i < HDA_BLK_MIN)
+			i = HDA_BLK_MIN;
+		pdevinfo->chan_blkcnt = pdevinfo->chan_size / i;
+		i = 0;
+		while (pdevinfo->chan_blkcnt >> i)
+			i++;
+		pdevinfo->chan_blkcnt = 1 << (i - 1);
+		if (pdevinfo->chan_blkcnt < HDA_BDL_MIN)
+			pdevinfo->chan_blkcnt = HDA_BDL_MIN;
+		else if (pdevinfo->chan_blkcnt > HDA_BDL_MAX)
+			pdevinfo->chan_blkcnt = HDA_BDL_MAX;
+	} else
+		pdevinfo->chan_blkcnt = HDA_BDL_DEFAULT;
+
+	/* 
+	 * We don't register interrupt handler with snd_setup_intr
+	 * in pcm device. Mark pcm device as MPSAFE manually.
+	 */
+	pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
+
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "OSS mixer initialization...\n");
+	);
+	if (mixer_init(dev, &hdaa_audio_ctl_ossmixer_class, pdevinfo) != 0)
+		device_printf(dev, "Can't register mixer\n");
+
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Registering PCM channels...\n");
+	);
+	if (pcm_register(dev, pdevinfo, (pdevinfo->playas >= 0)?1:0,
+	    (pdevinfo->recas >= 0)?1:0) != 0)
+		device_printf(dev, "Can't register PCM\n");
+
+	pdevinfo->registered++;
+
+	if (pdevinfo->playas >= 0) {
+		as = &devinfo->as[pdevinfo->playas];
+		for (i = 0; i < as->num_chans; i++)
+			pcm_addchan(dev, PCMDIR_PLAY, &hdaa_channel_class,
+			    &devinfo->chans[as->chans[i]]);
+	}
+	if (pdevinfo->recas >= 0) {
+		as = &devinfo->as[pdevinfo->recas];
+		for (i = 0; i < as->num_chans; i++)
+			pcm_addchan(dev, PCMDIR_REC, &hdaa_channel_class,
+			    &devinfo->chans[as->chans[i]]);
+	}
+
+	snprintf(status, SND_STATUSLEN, "on %s %s",
+	    device_get_nameunit(device_get_parent(dev)),
+	    PCM_KLDSTRING(snd_hda));
+	pcm_setstatus(dev, status);
+
+	return (0);
+}
+
+static int
+hdaa_pcm_detach(device_t dev)
+{
+	struct hdaa_pcm_devinfo *pdevinfo =
+	    (struct hdaa_pcm_devinfo *)device_get_ivars(dev);
+	int err;
+
+	if (pdevinfo->registered > 0) {
+		err = pcm_unregister(dev);
+		if (err != 0)
+			return (err);
+	}
+
+	return (0);
+}
+
+static device_method_t hdaa_pcm_methods[] = {
+	/* device interface */
+	DEVMETHOD(device_probe,		hdaa_pcm_probe),
+	DEVMETHOD(device_attach,	hdaa_pcm_attach),
+	DEVMETHOD(device_detach,	hdaa_pcm_detach),
+	{ 0, 0 }
+};
+
+static driver_t hdaa_pcm_driver = {
+	"pcm",
+	hdaa_pcm_methods,
+	PCM_SOFTC_SIZE,
+};
+
+DRIVER_MODULE(snd_hda_pcm, hdaa, hdaa_pcm_driver, pcm_devclass, 0, 0);
+MODULE_DEPEND(snd_hda, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
+MODULE_VERSION(snd_hda, 1);
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/sound/pci/hda/hdaa.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/sound/pci/hda/hdaa.h	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,230 @@
+/*-7
+ * Copyright (c) 2006 Stephane E. Potvin <sepotvin at videotron.ca>
+ * Copyright (c) 2006 Ariff Abdullah <ariff at FreeBSD.org>
+ * Copyright (c) 2008-2012 Alexander Motin <mav at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: head/sys/dev/sound/pci/hda/hdaa.h 230130 2012-01-15 13:21:36Z mav $
+ */
+
+/*
+ * Intel High Definition Audio (Audio function quirks) driver for FreeBSD.
+ */
+
+#ifndef _HDAA_QUIRKS_H_
+#define _HDAA_QUIRKS_H_
+
+#define HDAA_GPIO_SHIFT(n)	(n * 3)
+#define HDAA_GPIO_MASK(n)	(0x7 << (n * 3))
+#define HDAA_GPIO_KEEP(n)	(0x0 << (n * 3))
+#define HDAA_GPIO_SET(n)	(0x1 << (n * 3))
+#define HDAA_GPIO_CLEAR(n)	(0x2 << (n * 3))
+#define HDAA_GPIO_DISABLE(n)	(0x3 << (n * 3))
+#define HDAA_GPIO_INPUT(n)	(0x4 << (n * 3))
+
+/* 9 - 25 = anything else */
+#define HDAA_QUIRK_SOFTPCMVOL	(1 << 9)
+#define HDAA_QUIRK_FIXEDRATE	(1 << 10)
+#define HDAA_QUIRK_FORCESTEREO	(1 << 11)
+#define HDAA_QUIRK_EAPDINV	(1 << 12)
+#define HDAA_QUIRK_SENSEINV	(1 << 14)
+
+/* 26 - 31 = vrefs */
+#define HDAA_QUIRK_IVREF50	(1 << 26)
+#define HDAA_QUIRK_IVREF80	(1 << 27)
+#define HDAA_QUIRK_IVREF100	(1 << 28)
+#define HDAA_QUIRK_OVREF50	(1 << 29)
+#define HDAA_QUIRK_OVREF80	(1 << 30)
+#define HDAA_QUIRK_OVREF100	(1 << 31)
+
+#define HDAA_QUIRK_IVREF	(HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF80 | \
+						HDAA_QUIRK_IVREF100)
+#define HDAA_QUIRK_OVREF	(HDAA_QUIRK_OVREF50 | HDAA_QUIRK_OVREF80 | \
+						HDAA_QUIRK_OVREF100)
+#define HDAA_QUIRK_VREF		(HDAA_QUIRK_IVREF | HDAA_QUIRK_OVREF)
+
+#define HDAA_AMP_VOL_DEFAULT	(-1)
+#define HDAA_AMP_MUTE_DEFAULT	(0xffffffff)
+#define HDAA_AMP_MUTE_NONE	(0)
+#define HDAA_AMP_MUTE_LEFT	(1 << 0)
+#define HDAA_AMP_MUTE_RIGHT	(1 << 1)
+#define HDAA_AMP_MUTE_ALL	(HDAA_AMP_MUTE_LEFT | HDAA_AMP_MUTE_RIGHT)
+
+#define HDAA_AMP_LEFT_MUTED(v)	((v) & (HDAA_AMP_MUTE_LEFT))
+#define HDAA_AMP_RIGHT_MUTED(v)	(((v) & HDAA_AMP_MUTE_RIGHT) >> 1)
+
+#define HDAA_ADC_MONITOR		(1 << 0)
+
+#define HDAA_CTL_OUT		1
+#define HDAA_CTL_IN		2
+
+#define HDA_MAX_CONNS	32
+#define HDA_MAX_NAMELEN	32
+
+struct hdaa_widget {
+	nid_t nid;
+	int type;
+	int enable;
+	int nconns, selconn;
+	int waspin;
+	uint32_t pflags;
+	int bindas;
+	int bindseqmask;
+	int ossdev;
+	uint32_t ossmask;
+	nid_t conns[HDA_MAX_CONNS];
+	u_char connsenable[HDA_MAX_CONNS];
+	char name[HDA_MAX_NAMELEN];
+	struct hdaa_devinfo *devinfo;
+	struct {
+		uint32_t widget_cap;
+		uint32_t outamp_cap;
+		uint32_t inamp_cap;
+		uint32_t supp_stream_formats;
+		uint32_t supp_pcm_size_rate;
+		uint32_t eapdbtl;
+	} param;
+	union {
+		struct {
+			uint32_t config;
+			uint32_t original;
+			uint32_t newconf;
+			uint32_t cap;
+			uint32_t ctrl;
+		} pin;
+	} wclass;
+};
+
+struct hdaa_audio_ctl {
+	struct hdaa_widget *widget, *childwidget;
+	int enable;
+	int index, dir, ndir;
+	int mute, step, size, offset;
+	int left, right, forcemute;
+	uint32_t muted;
+	uint32_t ossmask, possmask;
+};
+
+/* Association is a group of pins bound for some special function. */
+struct hdaa_audio_as {
+	u_char enable;
+	u_char index;
+	u_char dir;
+	u_char pincnt;
+	u_char fakeredir;
+	u_char digital;
+	uint16_t pinset;
+	nid_t hpredir;
+	nid_t pins[16];
+	nid_t dacs[2][16];
+	int num_chans;
+	int chans[2];
+	int unsol;
+	int location;	/* Pins location, if all have the same */
+	int mixed;	/* Mixed/multiplexed recording, not multichannel. */
+};
+
+struct hdaa_pcm_devinfo {
+	device_t dev;
+	struct hdaa_devinfo *devinfo;
+	int	index;
+	int	registered;
+	int	playas, recas;
+	u_char	left[SOUND_MIXER_NRDEVICES];
+	u_char	right[SOUND_MIXER_NRDEVICES];
+	int	chan_size;
+	int	chan_blkcnt;
+	u_char	digital;
+};
+
+struct hdaa_devinfo {
+	device_t		dev;
+	struct mtx		*lock;
+	nid_t			nid;
+	nid_t			startnode, endnode;
+	uint32_t		outamp_cap;
+	uint32_t		inamp_cap;
+	uint32_t		supp_stream_formats;
+	uint32_t		supp_pcm_size_rate;
+	uint32_t		gpio_cap;
+	uint32_t		quirks;
+	uint32_t		newquirks;
+	uint32_t		gpio;
+	uint32_t		newgpio;
+	uint32_t		gpo;
+	uint32_t		newgpo;
+	int			nodecnt;
+	int			ctlcnt;
+	int			ascnt;
+	int			num_devs;
+	int			num_chans;
+	struct hdaa_widget	*widget;
+	struct hdaa_audio_ctl	*ctl;
+	struct hdaa_audio_as	*as;
+	struct hdaa_pcm_devinfo	*devs;
+	struct hdaa_chan	*chans;
+	struct callout		poll_jack;
+	int			poll_ival;
+};
+
+#define HDAA_CHN_RUNNING	0x00000001
+#define HDAA_CHN_SUSPEND	0x00000002
+
+struct hdaa_chan {
+	struct snd_dbuf *b;
+	struct pcm_channel *c;
+	struct pcmchan_caps caps;
+	struct hdaa_devinfo *devinfo;
+	struct hdaa_pcm_devinfo *pdevinfo;
+	uint32_t spd, fmt, fmtlist[16], pcmrates[16];
+	uint32_t supp_stream_formats, supp_pcm_size_rate;
+	uint32_t ptr, prevptr, blkcnt, blksz;
+	uint32_t *dmapos;
+	uint32_t flags;
+	int dir;
+	int off;
+	int sid;
+	int bit16, bit32;
+	int channels;	/* Number of audio channels. */
+	int as;		/* Number of association. */
+	int asindex;	/* Index within association. */
+	nid_t io[16];
+};
+
+#define hdaa_codec_id(devinfo)						\
+		(((uint32_t)hda_get_vendor_id(devinfo->dev) << 16) +	\
+		hda_get_device_id(devinfo->dev))
+
+#define hdaa_subvendor_id(devinfo)					\
+		(((uint32_t)hda_get_subvendor_id(devinfo->dev) << 16) +	\
+		hda_get_subdevice_id(devinfo->dev))
+
+struct hdaa_widget	*hdaa_widget_get(struct hdaa_devinfo *, nid_t);
+uint32_t		hdaa_widget_pin_patch(uint32_t config, const char *str);
+uint32_t		hdaa_gpio_patch(uint32_t gpio, const char *str);
+
+void			hdaa_patch(struct hdaa_devinfo *devinfo);
+void			hdaa_patch_direct(struct hdaa_devinfo *devinfo);
+
+#endif
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/sound/pci/hda/hdaa_patches.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/sound/pci/hda/hdaa_patches.c	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,638 @@
+/*-
+ * Copyright (c) 2006 Stephane E. Potvin <sepotvin at videotron.ca>
+ * Copyright (c) 2006 Ariff Abdullah <ariff at FreeBSD.org>
+ * Copyright (c) 2008-2012 Alexander Motin <mav at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Intel High Definition Audio (Audio function quirks) driver for FreeBSD.
+ */
+
+#ifdef HAVE_KERNEL_OPTION_HEADERS
+#include "opt_snd.h"
+#endif
+
+#include <dev/sound/pcm/sound.h>
+
+#include <sys/ctype.h>
+
+#include <dev/sound/pci/hda/hdac.h>
+#include <dev/sound/pci/hda/hdaa.h>
+#include <dev/sound/pci/hda/hda_reg.h>
+
+SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hda/hdaa_patches.c 230130 2012-01-15 13:21:36Z mav $");
+
+static const struct {
+	uint32_t model;
+	uint32_t id;
+	uint32_t set, unset;
+	uint32_t gpio;
+} hdac_quirks[] = {
+	/*
+	 * XXX Force stereo quirk. Monoural recording / playback
+	 *     on few codecs (especially ALC880) seems broken or
+	 *     perhaps unsupported.
+	 */
+	{ HDA_MATCH_ALL, HDA_MATCH_ALL,
+	    HDAA_QUIRK_FORCESTEREO | HDAA_QUIRK_IVREF, 0,
+	    0 },
+	{ ACER_ALL_SUBVENDOR, HDA_MATCH_ALL,
+	    0, 0,
+	    HDAA_GPIO_SET(0) },
+	{ ASUS_G2K_SUBVENDOR, HDA_CODEC_ALC660,
+	    0, 0,
+	    HDAA_GPIO_SET(0) },
+	{ ASUS_M5200_SUBVENDOR, HDA_CODEC_ALC880,
+	    0, 0,
+	    HDAA_GPIO_SET(0) },
+	{ ASUS_A7M_SUBVENDOR, HDA_CODEC_ALC880,
+	    0, 0,
+	    HDAA_GPIO_SET(0) },
+	{ ASUS_A7T_SUBVENDOR, HDA_CODEC_ALC882,
+	    0, 0,
+	    HDAA_GPIO_SET(0) },
+	{ ASUS_W2J_SUBVENDOR, HDA_CODEC_ALC882,
+	    0, 0,
+	    HDAA_GPIO_SET(0) },
+	{ ASUS_U5F_SUBVENDOR, HDA_CODEC_AD1986A,
+	    HDAA_QUIRK_EAPDINV, 0,
+	    0 },
+	{ ASUS_A8X_SUBVENDOR, HDA_CODEC_AD1986A,
+	    HDAA_QUIRK_EAPDINV, 0,
+	    0 },
+	{ ASUS_F3JC_SUBVENDOR, HDA_CODEC_ALC861,
+	    HDAA_QUIRK_OVREF, 0,
+	    0 },
+	{ UNIWILL_9075_SUBVENDOR, HDA_CODEC_ALC861,
+	    HDAA_QUIRK_OVREF, 0,
+	    0 },
+	/*{ ASUS_M2N_SUBVENDOR, HDA_CODEC_AD1988,
+	    HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
+	    0 },*/
+	{ MEDION_MD95257_SUBVENDOR, HDA_CODEC_ALC880,
+	    0, 0,
+	    HDAA_GPIO_SET(1) },
+	{ LENOVO_3KN100_SUBVENDOR, HDA_CODEC_AD1986A,
+	    HDAA_QUIRK_EAPDINV | HDAA_QUIRK_SENSEINV, 0,
+	    0 },
+	{ SAMSUNG_Q1_SUBVENDOR, HDA_CODEC_AD1986A,
+	    HDAA_QUIRK_EAPDINV, 0,
+	    0 },
+	{ APPLE_MB3_SUBVENDOR, HDA_CODEC_ALC885,
+	    HDAA_QUIRK_OVREF50, 0,
+	    HDAA_GPIO_SET(0) },
+	{ APPLE_INTEL_MAC, HDA_CODEC_STAC9221,
+	    0, 0,
+	    HDAA_GPIO_SET(0) | HDAA_GPIO_SET(1) },
+	{ APPLE_MACBOOKPRO55, HDA_CODEC_CS4206,
+	    0, 0,
+	    HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
+	{ DELL_D630_SUBVENDOR, HDA_CODEC_STAC9205X,
+	    0, 0,
+	    HDAA_GPIO_SET(0) },
+	{ DELL_V1400_SUBVENDOR, HDA_CODEC_STAC9228X,
+	    0, 0,
+	    HDAA_GPIO_SET(2) },
+	{ DELL_V1500_SUBVENDOR, HDA_CODEC_STAC9205X,
+	    0, 0,
+	    HDAA_GPIO_SET(0) },
+	{ HDA_MATCH_ALL, HDA_CODEC_AD1988,
+	    HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
+	    0 },
+	{ HDA_MATCH_ALL, HDA_CODEC_AD1988B,
+	    HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
+	    0 },
+	{ HDA_MATCH_ALL, HDA_CODEC_CX20549,
+	    0, HDAA_QUIRK_FORCESTEREO,
+	    0 }
+};
+#define HDAC_QUIRKS_LEN (sizeof(hdac_quirks) / sizeof(hdac_quirks[0]))
+
+static void
+hdac_pin_patch(struct hdaa_widget *w)
+{
+	const char *patch = NULL;
+	uint32_t config, orig, id, subid;
+	nid_t nid = w->nid;
+
+	config = orig = w->wclass.pin.config;
+	id = hdaa_codec_id(w->devinfo);
+	subid = hdaa_subvendor_id(w->devinfo);
+
+	/* XXX: Old patches require complete review.
+	 * Now they may create more problem then solve due to
+	 * incorrect associations.
+	 */
+	if (id == HDA_CODEC_ALC880 && subid == LG_LW20_SUBVENDOR) {
+		switch (nid) {
+		case 26:
+			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
+			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
+			break;
+		case 27:
+			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
+			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT;
+			break;
+		default:
+			break;
+		}
+	} else if (id == HDA_CODEC_ALC880 &&
+	    (subid == CLEVO_D900T_SUBVENDOR ||
+	    subid == ASUS_M5200_SUBVENDOR)) {
+		/*
+		 * Super broken BIOS
+		 */
+		switch (nid) {
+		case 24:	/* MIC1 */
+			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
+			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
+			break;
+		case 25:	/* XXX MIC2 */
+			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
+			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
+			break;
+		case 26:	/* LINE1 */
+			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
+			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
+			break;
+		case 27:	/* XXX LINE2 */
+			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
+			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
+			break;
+		case 28:	/* CD */
+			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
+			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_CD;
+			break;
+		}
+	} else if (id == HDA_CODEC_ALC883 &&
+	    (subid == MSI_MS034A_SUBVENDOR ||
+	    HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, subid))) {
+		switch (nid) {
+		case 25:
+			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
+			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
+			break;
+		case 28:
+			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
+			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
+			break;
+		}
+	} else if (id == HDA_CODEC_CX20549 && subid ==
+	    HP_V3000_SUBVENDOR) {
+		switch (nid) {
+		case 18:
+			config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
+			config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
+			break;
+		case 20:
+			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
+			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
+			break;
+		case 21:
+			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
+			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
+			break;
+		}
+	} else if (id == HDA_CODEC_CX20551 && subid ==
+	    HP_DV5000_SUBVENDOR) {
+		switch (nid) {
+		case 20:
+		case 21:
+			config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
+			config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
+			break;
+		}
+	} else if (id == HDA_CODEC_ALC861 && subid ==
+	    ASUS_W6F_SUBVENDOR) {
+		switch (nid) {
+		case 11:
+			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
+			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
+			break;
+		case 12:
+		case 14:
+		case 16:
+		case 31:
+		case 32:
+			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
+			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
+			break;
+		case 15:
+			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
+			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK);
+			break;
+		}
+	} else if (id == HDA_CODEC_ALC861 && subid ==
+	    UNIWILL_9075_SUBVENDOR) {
+		switch (nid) {
+		case 15:
+			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
+			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT |
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK);
+			break;
+		}
+	}
+
+	/* New patches */
+	if (id == HDA_CODEC_AD1986A &&
+	    (subid == ASUS_M2NPVMX_SUBVENDOR ||
+	    subid == ASUS_A8NVMCSM_SUBVENDOR ||
+	    subid == ASUS_P5PL2_SUBVENDOR)) {
+		switch (nid) {
+		case 26: /* Headphones with redirection */
+			patch = "as=1 seq=15";
+			break;
+		case 28: /* 5.1 out => 2.0 out + 1 input */
+			patch = "device=Line-in as=8 seq=1";
+			break;
+		case 29: /* Can't use this as input, as the only available mic
+			  * preamplifier is busy by front panel mic (nid 31).
+			  * If you want to use this rear connector as mic input,
+			  * you have to disable the front panel one. */
+			patch = "as=0";
+			break;
+		case 31: /* Lot of inputs configured with as=15 and unusable */
+			patch = "as=8 seq=3";
+			break;
+		case 32:
+			patch = "as=8 seq=4";
+			break;
+		case 34:
+			patch = "as=8 seq=5";
+			break;
+		case 36:
+			patch = "as=8 seq=6";
+			break;
+		}
+	} else if (id == HDA_CODEC_ALC260 &&
+	    HDA_DEV_MATCH(SONY_S5_SUBVENDOR, subid)) {
+		switch (nid) {
+		case 16:
+			patch = "seq=15 device=Headphones";
+			break;
+		}
+	} else if (id == HDA_CODEC_ALC268) {
+	    if (subid == ACER_T5320_SUBVENDOR) {
+		switch (nid) {
+		case 20: /* Headphones Jack */
+			patch = "as=1 seq=15";
+			break;
+		}
+	    }
+	} else if (id == HDA_CODEC_CX20561 &&
+	    subid == LENOVO_B450_SUBVENDOR) {
+		switch (nid) {
+		case 22:
+			patch = "as=1 seq=15";
+			break;
+		}
+	}
+
+	if (patch != NULL)
+		config = hdaa_widget_pin_patch(config, patch);
+	HDA_BOOTVERBOSE(
+		if (config != orig)
+			device_printf(w->devinfo->dev,
+			    "Patching pin config nid=%u 0x%08x -> 0x%08x\n",
+			    nid, orig, config);
+	);
+	w->wclass.pin.config = config;
+}
+
+static void
+hdaa_widget_patch(struct hdaa_widget *w)
+{
+	struct hdaa_devinfo *devinfo = w->devinfo;
+	uint32_t orig;
+	nid_t beeper = -1;
+
+	orig = w->param.widget_cap;
+	/* On some codecs beeper is an input pin, but it is not recordable
+	   alone. Also most of BIOSes does not declare beeper pin.
+	   Change beeper pin node type to beeper to help parser. */
+	switch (hdaa_codec_id(devinfo)) {
+	case HDA_CODEC_AD1882:
+	case HDA_CODEC_AD1883:
+	case HDA_CODEC_AD1984:
+	case HDA_CODEC_AD1984A:
+	case HDA_CODEC_AD1984B:
+	case HDA_CODEC_AD1987:
+	case HDA_CODEC_AD1988:
+	case HDA_CODEC_AD1988B:
+	case HDA_CODEC_AD1989B:
+		beeper = 26;
+		break;
+	case HDA_CODEC_ALC260:
+		beeper = 23;
+		break;
+	}
+	if (hda_get_vendor_id(devinfo->dev) == REALTEK_VENDORID &&
+	    hdaa_codec_id(devinfo) != HDA_CODEC_ALC260)
+		beeper = 29;
+	if (w->nid == beeper) {
+		w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK;
+		w->param.widget_cap |= HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET <<
+		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT;
+		w->waspin = 1;
+	}
+	HDA_BOOTVERBOSE(
+		if (w->param.widget_cap != orig) {
+			device_printf(w->devinfo->dev,
+			    "Patching widget caps nid=%u 0x%08x -> 0x%08x\n",
+			    w->nid, orig, w->param.widget_cap);
+		}
+	);
+
+	if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+		hdac_pin_patch(w);
+}
+
+void
+hdaa_patch(struct hdaa_devinfo *devinfo)
+{
+	struct hdaa_widget *w;
+	uint32_t id, subid;
+	int i;
+
+	id = hdaa_codec_id(devinfo);
+	subid = hdaa_subvendor_id(devinfo);
+
+	/*
+	 * Quirks
+	 */
+	for (i = 0; i < HDAC_QUIRKS_LEN; i++) {
+		if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subid) &&
+		    HDA_DEV_MATCH(hdac_quirks[i].id, id)))
+			continue;
+		if (hdac_quirks[i].set != 0)
+			devinfo->quirks |=
+			    hdac_quirks[i].set;
+		if (hdac_quirks[i].unset != 0)
+			devinfo->quirks &=
+			    ~(hdac_quirks[i].unset);
+	}
+
+	/* Apply per-widget patch. */
+	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
+		w = hdaa_widget_get(devinfo, i);
+		if (w == NULL)
+			continue;
+		hdaa_widget_patch(w);
+	}
+
+	switch (id) {
+	case HDA_CODEC_AD1983:
+		/*
+		 * This CODEC has several possible usages, but none
+		 * fit the parser best. Help parser to choose better.
+		 */
+		/* Disable direct unmixed playback to get pcm volume. */
+		w = hdaa_widget_get(devinfo, 5);
+		if (w != NULL)
+			w->connsenable[0] = 0;
+		w = hdaa_widget_get(devinfo, 6);
+		if (w != NULL)
+			w->connsenable[0] = 0;
+		w = hdaa_widget_get(devinfo, 11);
+		if (w != NULL)
+			w->connsenable[0] = 0;
+		/* Disable mic and line selectors. */
+		w = hdaa_widget_get(devinfo, 12);
+		if (w != NULL)
+			w->connsenable[1] = 0;
+		w = hdaa_widget_get(devinfo, 13);
+		if (w != NULL)
+			w->connsenable[1] = 0;
+		/* Disable recording from mono playback mix. */
+		w = hdaa_widget_get(devinfo, 20);
+		if (w != NULL)
+			w->connsenable[3] = 0;
+		break;
+	case HDA_CODEC_AD1986A:
+		/*
+		 * This CODEC has overcomplicated input mixing.
+		 * Make some cleaning there.
+		 */
+		/* Disable input mono mixer. Not needed and not supported. */
+		w = hdaa_widget_get(devinfo, 43);
+		if (w != NULL)
+			w->enable = 0;
+		/* Disable any with any input mixing mesh. Use separately. */
+		w = hdaa_widget_get(devinfo, 39);
+		if (w != NULL)
+			w->enable = 0;
+		w = hdaa_widget_get(devinfo, 40);
+		if (w != NULL)
+			w->enable = 0;
+		w = hdaa_widget_get(devinfo, 41);
+		if (w != NULL)
+			w->enable = 0;
+		w = hdaa_widget_get(devinfo, 42);
+		if (w != NULL)
+			w->enable = 0;
+		/* Disable duplicate mixer node connector. */
+		w = hdaa_widget_get(devinfo, 15);
+		if (w != NULL)
+			w->connsenable[3] = 0;
+		/* There is only one mic preamplifier, use it effectively. */
+		w = hdaa_widget_get(devinfo, 31);
+		if (w != NULL) {
+			if ((w->wclass.pin.config &
+			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
+			    HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
+				w = hdaa_widget_get(devinfo, 16);
+				if (w != NULL)
+				    w->connsenable[2] = 0;
+			} else {
+				w = hdaa_widget_get(devinfo, 15);
+				if (w != NULL)
+				    w->connsenable[0] = 0;
+			}
+		}
+		w = hdaa_widget_get(devinfo, 32);
+		if (w != NULL) {
+			if ((w->wclass.pin.config &
+			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
+			    HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
+				w = hdaa_widget_get(devinfo, 16);
+				if (w != NULL)
+				    w->connsenable[0] = 0;
+			} else {
+				w = hdaa_widget_get(devinfo, 15);
+				if (w != NULL)
+				    w->connsenable[1] = 0;
+			}
+		}
+
+		if (subid == ASUS_A8X_SUBVENDOR) {
+			/*
+			 * This is just plain ridiculous.. There
+			 * are several A8 series that share the same
+			 * pci id but works differently (EAPD).
+			 */
+			w = hdaa_widget_get(devinfo, 26);
+			if (w != NULL && w->type ==
+			    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
+			    (w->wclass.pin.config &
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) !=
+			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE)
+				devinfo->quirks &=
+				    ~HDAA_QUIRK_EAPDINV;
+		}
+		break;
+	case HDA_CODEC_AD1981HD:
+		/*
+		 * This CODEC has very unusual design with several
+		 * points inappropriate for the present parser.
+		 */
+		/* Disable recording from mono playback mix. */
+		w = hdaa_widget_get(devinfo, 21);
+		if (w != NULL)
+			w->connsenable[3] = 0;
+		/* Disable rear to front mic mixer, use separately. */
+		w = hdaa_widget_get(devinfo, 31);
+		if (w != NULL)
+			w->enable = 0;
+		/* Disable direct playback, use mixer. */
+		w = hdaa_widget_get(devinfo, 5);
+		if (w != NULL)
+			w->connsenable[0] = 0;
+		w = hdaa_widget_get(devinfo, 6);
+		if (w != NULL)
+			w->connsenable[0] = 0;
+		w = hdaa_widget_get(devinfo, 9);
+		if (w != NULL)
+			w->connsenable[0] = 0;
+		w = hdaa_widget_get(devinfo, 24);
+		if (w != NULL)
+			w->connsenable[0] = 0;
+		break;
+	case HDA_CODEC_CX20582:
+	case HDA_CODEC_CX20583:
+	case HDA_CODEC_CX20584:
+	case HDA_CODEC_CX20585:
+	case HDA_CODEC_CX20590:
+		/*
+		 * These codecs have extra connectivity on record side
+		 * too reach for the present parser.
+		 */
+		w = hdaa_widget_get(devinfo, 20);
+		if (w != NULL)
+			w->connsenable[1] = 0;
+		w = hdaa_widget_get(devinfo, 21);
+		if (w != NULL)
+			w->connsenable[1] = 0;
+		w = hdaa_widget_get(devinfo, 22);
+		if (w != NULL)
+			w->connsenable[0] = 0;
+		break;
+	case HDA_CODEC_VT1708S_0:
+	case HDA_CODEC_VT1708S_1:
+	case HDA_CODEC_VT1708S_2:
+	case HDA_CODEC_VT1708S_3:
+	case HDA_CODEC_VT1708S_4:
+	case HDA_CODEC_VT1708S_5:
+	case HDA_CODEC_VT1708S_6:
+	case HDA_CODEC_VT1708S_7:
+		/*
+		 * These codecs have hidden mic boost controls.
+		 */
+		w = hdaa_widget_get(devinfo, 26);
+		if (w != NULL)
+			w->param.inamp_cap =
+			    (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
+			    (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
+			    (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
+		w = hdaa_widget_get(devinfo, 30);
+		if (w != NULL)
+			w->param.inamp_cap =
+			    (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
+			    (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
+			    (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
+		break;
+	}
+}
+
+void
+hdaa_patch_direct(struct hdaa_devinfo *devinfo)
+{
+	device_t dev = devinfo->dev;
+	uint32_t id, subid, val;
+
+	id = hdaa_codec_id(devinfo);
+	subid = hdaa_subvendor_id(devinfo);
+
+	switch (id) {
+	case HDA_CODEC_VT1708S_0:
+	case HDA_CODEC_VT1708S_1:
+	case HDA_CODEC_VT1708S_2:
+	case HDA_CODEC_VT1708S_3:
+	case HDA_CODEC_VT1708S_4:
+	case HDA_CODEC_VT1708S_5:
+	case HDA_CODEC_VT1708S_6:
+	case HDA_CODEC_VT1708S_7:
+		/* Enable Mic Boost Volume controls. */
+		hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
+		    0xf98, 0x01));
+		/* Don't bypass mixer. */
+		hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
+		    0xf88, 0xc0));
+		break;
+	}
+	if (subid == APPLE_INTEL_MAC)
+		hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
+		    0x7e7, 0));
+	if (id == HDA_CODEC_ALC269) {
+		if (subid == 0x104316e3 || subid == 0x1043831a ||
+		    subid == 0x1043834a || subid == 0x10438398 ||
+		    subid == 0x104383ce) {
+			/*
+			 * The ditital mics on some Asus laptops produce
+			 * differential signals instead of expected stereo.
+			 * That results in silence if downmix it to mono.
+			 * To workaround, make codec to handle signal as mono.
+			 */
+			hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07));
+			val = hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, 0x20));
+			hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07));
+			hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, 0x20, val|0x80));
+		}
+	}
+}
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/sound/pci/hda/hdac.c
--- a/head/sys/dev/sound/pci/hda/hdac.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/sound/pci/hda/hdac.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,7 +1,7 @@
 /*-
  * Copyright (c) 2006 Stephane E. Potvin <sepotvin at videotron.ca>
  * Copyright (c) 2006 Ariff Abdullah <ariff at FreeBSD.org>
- * Copyright (c) 2008 Alexander Motin <mav at FreeBSD.org>
+ * Copyright (c) 2008-2012 Alexander Motin <mav at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,45 +27,7 @@
  */
 
 /*
- * Intel High Definition Audio (Controller) driver for FreeBSD. Be advised
- * that this driver still in its early stage, and possible of rewrite are
- * pretty much guaranteed. There are supposedly several distinct parent/child
- * busses to make this "perfect", but as for now and for the sake of
- * simplicity, everything is gobble up within single source.
- *
- * List of subsys:
- *     1) HDA Controller support
- *     2) HDA Codecs support, which may include
- *        - HDA
- *        - Modem
- *     3) Widget parser - the real magic of why this driver works on so
- *        many hardwares with minimal vendor specific quirk. The original
- *        parser was written using Ruby and can be found at
- *        http://people.freebsd.org/~ariff/HDA/parser.rb . This crude
- *        ruby parser take the verbose dmesg dump as its input. Refer to
- *        http://www.microsoft.com/whdc/device/audio/default.mspx for various
- *        interesting documents, especially UAA (Universal Audio Architecture).
- *     4) Possible vendor specific support.
- *        (snd_hda_intel, snd_hda_ati, etc..)
- *
- * Thanks to Ahmad Ubaidah Omar @ Defenxis Sdn. Bhd. for the
- * Compaq V3000 with Conexant HDA.
- *
- *    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- *    *                                                                 *
- *    *        This driver is a collaborative effort made by:           *
- *    *                                                                 *
- *    *          Stephane E. Potvin <sepotvin at videotron.ca>             *
- *    *               Andrea Bittau <a.bittau at cs.ucl.ac.uk>             *
- *    *               Wesley Morgan <morganw at chemikals.org>             *
- *    *              Daniel Eischen <deischen at FreeBSD.org>              *
- *    *             Maxime Guillaud <bsd-ports at mguillaud.net>           *
- *    *              Ariff Abdullah <ariff at FreeBSD.org>                 *
- *    *             Alexander Motin <mav at FreeBSD.org>                   *
- *    *                                                                 *
- *    *   ....and various people from freebsd-multimedia at FreeBSD.org    *
- *    *                                                                 *
- *    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Intel High Definition Audio (Controller) driver for FreeBSD.
  */
 
 #ifdef HAVE_KERNEL_OPTION_HEADERS
@@ -84,370 +46,26 @@
 #include <dev/sound/pci/hda/hda_reg.h>
 #include <dev/sound/pci/hda/hdac.h>
 
-#include "mixer_if.h"
+#define HDA_DRV_TEST_REV	"20120111_0001"
 
-#define HDA_DRV_TEST_REV	"20100226_0142"
-
-SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hda/hdac.c 228727 2011-12-20 02:42:53Z mav $");
-
-#define HDA_BOOTVERBOSE(stmt)	do {			\
-	if (bootverbose != 0 || snd_verbose > 3) {	\
-		stmt					\
-	}						\
-} while (0)
-
-#define HDA_BOOTHVERBOSE(stmt)	do {			\
-	if (snd_verbose > 3) {				\
-		stmt					\
-	}						\
-} while (0)
-
-#if 1
-#undef HDAC_INTR_EXTRA
-#define HDAC_INTR_EXTRA		1
-#endif
+SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hda/hdac.c 230130 2012-01-15 13:21:36Z mav $");
 
 #define hdac_lock(sc)		snd_mtxlock((sc)->lock)
 #define hdac_unlock(sc)		snd_mtxunlock((sc)->lock)
 #define hdac_lockassert(sc)	snd_mtxassert((sc)->lock)
 #define hdac_lockowned(sc)	mtx_owned((sc)->lock)
 
-#define HDA_FLAG_MATCH(fl, v)	(((fl) & (v)) == (v))
-#define HDA_DEV_MATCH(fl, v)	((fl) == (v) || \
-				(fl) == 0xffffffff || \
-				(((fl) & 0xffff0000) == 0xffff0000 && \
-				((fl) & 0x0000ffff) == ((v) & 0x0000ffff)) || \
-				(((fl) & 0x0000ffff) == 0x0000ffff && \
-				((fl) & 0xffff0000) == ((v) & 0xffff0000)))
-#define HDA_MATCH_ALL		0xffffffff
-#define HDAC_INVALID		0xffffffff
-
-/* Default controller / jack sense poll: 250ms */
-#define HDAC_POLL_INTERVAL	max(hz >> 2, 1)
-
-/*
- * Make room for possible 4096 playback/record channels, in 100 years to come.
- */
-#define HDAC_TRIGGER_NONE	0x00000000
-#define HDAC_TRIGGER_PLAY	0x00000fff
-#define HDAC_TRIGGER_REC	0x00fff000
-#define HDAC_TRIGGER_UNSOL	0x80000000
-
-#define HDA_MODEL_CONSTRUCT(vendor, model)	\
-		(((uint32_t)(model) << 16) | ((vendor##_VENDORID) & 0xffff))
-
-/* Controller models */
-
-/* Intel */
-#define INTEL_VENDORID		0x8086
-#define HDA_INTEL_CPT		HDA_MODEL_CONSTRUCT(INTEL, 0x1c20)
-#define HDA_INTEL_PATSBURG	HDA_MODEL_CONSTRUCT(INTEL, 0x1d20)
-#define HDA_INTEL_PPT1		HDA_MODEL_CONSTRUCT(INTEL, 0x1e20)
-#define HDA_INTEL_82801F	HDA_MODEL_CONSTRUCT(INTEL, 0x2668)
-#define HDA_INTEL_63XXESB	HDA_MODEL_CONSTRUCT(INTEL, 0x269a)
-#define HDA_INTEL_82801G	HDA_MODEL_CONSTRUCT(INTEL, 0x27d8)
-#define HDA_INTEL_82801H	HDA_MODEL_CONSTRUCT(INTEL, 0x284b)
-#define HDA_INTEL_82801I	HDA_MODEL_CONSTRUCT(INTEL, 0x293e)
-#define HDA_INTEL_82801JI	HDA_MODEL_CONSTRUCT(INTEL, 0x3a3e)
-#define HDA_INTEL_82801JD	HDA_MODEL_CONSTRUCT(INTEL, 0x3a6e)
-#define HDA_INTEL_PCH		HDA_MODEL_CONSTRUCT(INTEL, 0x3b56)
-#define HDA_INTEL_PCH2		HDA_MODEL_CONSTRUCT(INTEL, 0x3b57)
-#define HDA_INTEL_SCH		HDA_MODEL_CONSTRUCT(INTEL, 0x811b)
-#define HDA_INTEL_ALL		HDA_MODEL_CONSTRUCT(INTEL, 0xffff)
-
-/* Nvidia */
-#define NVIDIA_VENDORID		0x10de
-#define HDA_NVIDIA_MCP51	HDA_MODEL_CONSTRUCT(NVIDIA, 0x026c)
-#define HDA_NVIDIA_MCP55	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0371)
-#define HDA_NVIDIA_MCP61_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x03e4)
-#define HDA_NVIDIA_MCP61_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x03f0)
-#define HDA_NVIDIA_MCP65_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x044a)
-#define HDA_NVIDIA_MCP65_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x044b)
-#define HDA_NVIDIA_MCP67_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x055c)
-#define HDA_NVIDIA_MCP67_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x055d)
-#define HDA_NVIDIA_MCP78_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0774)
-#define HDA_NVIDIA_MCP78_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0775)
-#define HDA_NVIDIA_MCP78_3	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0776)
-#define HDA_NVIDIA_MCP78_4	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0777)
-#define HDA_NVIDIA_MCP73_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x07fc)
-#define HDA_NVIDIA_MCP73_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x07fd)
-#define HDA_NVIDIA_MCP79_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac0)
-#define HDA_NVIDIA_MCP79_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac1)
-#define HDA_NVIDIA_MCP79_3	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac2)
-#define HDA_NVIDIA_MCP79_4	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac3)
-#define HDA_NVIDIA_MCP89_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d94)
-#define HDA_NVIDIA_MCP89_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d95)
-#define HDA_NVIDIA_MCP89_3	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d96)
-#define HDA_NVIDIA_MCP89_4	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d97)
-#define HDA_NVIDIA_ALL		HDA_MODEL_CONSTRUCT(NVIDIA, 0xffff)
-
-/* ATI */
-#define ATI_VENDORID		0x1002
-#define HDA_ATI_SB450		HDA_MODEL_CONSTRUCT(ATI, 0x437b)
-#define HDA_ATI_SB600		HDA_MODEL_CONSTRUCT(ATI, 0x4383)
-#define HDA_ATI_RS600		HDA_MODEL_CONSTRUCT(ATI, 0x793b)
-#define HDA_ATI_RS690		HDA_MODEL_CONSTRUCT(ATI, 0x7919)
-#define HDA_ATI_RS780		HDA_MODEL_CONSTRUCT(ATI, 0x960f)
-#define HDA_ATI_R600		HDA_MODEL_CONSTRUCT(ATI, 0xaa00)
-#define HDA_ATI_RV630		HDA_MODEL_CONSTRUCT(ATI, 0xaa08)
-#define HDA_ATI_RV610		HDA_MODEL_CONSTRUCT(ATI, 0xaa10)
-#define HDA_ATI_RV670		HDA_MODEL_CONSTRUCT(ATI, 0xaa18)
-#define HDA_ATI_RV635		HDA_MODEL_CONSTRUCT(ATI, 0xaa20)
-#define HDA_ATI_RV620		HDA_MODEL_CONSTRUCT(ATI, 0xaa28)
-#define HDA_ATI_RV770		HDA_MODEL_CONSTRUCT(ATI, 0xaa30)
-#define HDA_ATI_RV730		HDA_MODEL_CONSTRUCT(ATI, 0xaa38)
-#define HDA_ATI_RV710		HDA_MODEL_CONSTRUCT(ATI, 0xaa40)
-#define HDA_ATI_RV740		HDA_MODEL_CONSTRUCT(ATI, 0xaa48)
-#define HDA_ATI_ALL		HDA_MODEL_CONSTRUCT(ATI, 0xffff)
-
-/* RDC */
-#define RDC_VENDORID		0x17f3
-#define HDA_RDC_M3010		HDA_MODEL_CONSTRUCT(RDC, 0x3010)
-
-/* VIA */
-#define VIA_VENDORID		0x1106
-#define HDA_VIA_VT82XX		HDA_MODEL_CONSTRUCT(VIA, 0x3288)
-#define HDA_VIA_ALL		HDA_MODEL_CONSTRUCT(VIA, 0xffff)
-
-/* SiS */
-#define SIS_VENDORID		0x1039
-#define HDA_SIS_966		HDA_MODEL_CONSTRUCT(SIS, 0x7502)
-#define HDA_SIS_ALL		HDA_MODEL_CONSTRUCT(SIS, 0xffff)
-
-/* ULI */
-#define ULI_VENDORID		0x10b9
-#define HDA_ULI_M5461		HDA_MODEL_CONSTRUCT(ULI, 0x5461)
-#define HDA_ULI_ALL		HDA_MODEL_CONSTRUCT(ULI, 0xffff)
-
-/* OEM/subvendors */
-
-/* Intel */
-#define INTEL_D101GGC_SUBVENDOR	HDA_MODEL_CONSTRUCT(INTEL, 0xd600)
-
-/* HP/Compaq */
-#define HP_VENDORID		0x103c
-#define HP_V3000_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x30b5)
-#define HP_NX7400_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x30a2)
-#define HP_NX6310_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x30aa)
-#define HP_NX6325_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x30b0)
-#define HP_XW4300_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x3013)
-#define HP_3010_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x3010)
-#define HP_DV5000_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x30a5)
-#define HP_DC7700S_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x2801)
-#define HP_DC7700_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x2802)
-#define HP_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0xffff)
-/* What is wrong with XN 2563 anyway? (Got the picture ?) */
-#define HP_NX6325_SUBVENDORX	0x103c30b0
-
-/* Dell */
-#define DELL_VENDORID		0x1028
-#define DELL_D630_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x01f9)
-#define DELL_D820_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x01cc)
-#define DELL_V1400_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x0227)
-#define DELL_V1500_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x0228)
-#define DELL_I1300_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x01c9)
-#define DELL_XPSM1210_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x01d7)
-#define DELL_OPLX745_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x01da)
-#define DELL_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0xffff)
-
-/* Clevo */
-#define CLEVO_VENDORID		0x1558
-#define CLEVO_D900T_SUBVENDOR	HDA_MODEL_CONSTRUCT(CLEVO, 0x0900)
-#define CLEVO_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(CLEVO, 0xffff)
-
-/* Acer */
-#define ACER_VENDORID		0x1025
-#define ACER_A5050_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x010f)
-#define ACER_A4520_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x0127)
-#define ACER_A4710_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x012f)
-#define ACER_A4715_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x0133)
-#define ACER_3681WXM_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x0110)
-#define ACER_T6292_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x011b)
-#define ACER_T5320_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x011f)
-#define ACER_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0xffff)
-
-/* Asus */
-#define ASUS_VENDORID		0x1043
-#define ASUS_A8X_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1153)
-#define ASUS_U5F_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1263)
-#define ASUS_W6F_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1263)
-#define ASUS_A7M_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1323)
-#define ASUS_F3JC_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1338)
-#define ASUS_G2K_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1339)
-#define ASUS_A7T_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x13c2)
-#define ASUS_W2J_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1971)
-#define ASUS_M5200_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1993)
-#define ASUS_P5PL2_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x817f)
-#define ASUS_P1AH2_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x81cb)
-#define ASUS_M2NPVMX_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x81cb)
-#define ASUS_M2V_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x81e7)
-#define ASUS_P5BWD_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x81ec)
-#define ASUS_M2N_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x8234)
-#define ASUS_A8NVMCSM_SUBVENDOR	HDA_MODEL_CONSTRUCT(NVIDIA, 0xcb84)
-#define ASUS_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0xffff)
-
-/* IBM / Lenovo */
-#define IBM_VENDORID		0x1014
-#define IBM_M52_SUBVENDOR	HDA_MODEL_CONSTRUCT(IBM, 0x02f6)
-#define IBM_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(IBM, 0xffff)
-
-/* Lenovo */
-#define LENOVO_VENDORID		0x17aa
-#define LENOVO_3KN100_SUBVENDOR	HDA_MODEL_CONSTRUCT(LENOVO, 0x2066)
-#define LENOVO_3KN200_SUBVENDOR	HDA_MODEL_CONSTRUCT(LENOVO, 0x384e)
-#define LENOVO_B450_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x3a0d)
-#define LENOVO_TCA55_SUBVENDOR	HDA_MODEL_CONSTRUCT(LENOVO, 0x1015)
-#define LENOVO_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(LENOVO, 0xffff)
-
-/* Samsung */
-#define SAMSUNG_VENDORID	0x144d
-#define SAMSUNG_Q1_SUBVENDOR	HDA_MODEL_CONSTRUCT(SAMSUNG, 0xc027)
-#define SAMSUNG_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(SAMSUNG, 0xffff)
-
-/* Medion ? */
-#define MEDION_VENDORID			0x161f
-#define MEDION_MD95257_SUBVENDOR	HDA_MODEL_CONSTRUCT(MEDION, 0x203d)
-#define MEDION_ALL_SUBVENDOR		HDA_MODEL_CONSTRUCT(MEDION, 0xffff)
-
-/* Apple Computer Inc. */
-#define APPLE_VENDORID		0x106b
-#define APPLE_MB3_SUBVENDOR	HDA_MODEL_CONSTRUCT(APPLE, 0x00a1)
-
-/* Sony */
-#define SONY_VENDORID		0x104d
-#define SONY_S5_SUBVENDOR	HDA_MODEL_CONSTRUCT(SONY, 0x81cc)
-#define SONY_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(SONY, 0xffff)
-
-/*
- * Apple Intel MacXXXX seems using Sigmatel codec/vendor id
- * instead of their own, which is beyond my comprehension
- * (see HDA_CODEC_STAC9221 below).
- */
-#define APPLE_INTEL_MAC		0x76808384
-#define APPLE_MACBOOKPRO55	0xcb7910de
-
-/* LG Electronics */
-#define LG_VENDORID		0x1854
-#define LG_LW20_SUBVENDOR	HDA_MODEL_CONSTRUCT(LG, 0x0018)
-#define LG_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(LG, 0xffff)
-
-/* Fujitsu Siemens */
-#define FS_VENDORID		0x1734
-#define FS_PA1510_SUBVENDOR	HDA_MODEL_CONSTRUCT(FS, 0x10b8)
-#define FS_SI1848_SUBVENDOR	HDA_MODEL_CONSTRUCT(FS, 0x10cd)
-#define FS_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(FS, 0xffff)
-
-/* Fujitsu Limited */
-#define FL_VENDORID		0x10cf
-#define FL_S7020D_SUBVENDOR	HDA_MODEL_CONSTRUCT(FL, 0x1326)
-#define FL_U1010_SUBVENDOR	HDA_MODEL_CONSTRUCT(FL, 0x142d)
-#define FL_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(FL, 0xffff)
-
-/* Toshiba */
-#define TOSHIBA_VENDORID	0x1179
-#define TOSHIBA_U200_SUBVENDOR	HDA_MODEL_CONSTRUCT(TOSHIBA, 0x0001)
-#define TOSHIBA_A135_SUBVENDOR	HDA_MODEL_CONSTRUCT(TOSHIBA, 0xff01)
-#define TOSHIBA_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(TOSHIBA, 0xffff)
-
-/* Micro-Star International (MSI) */
-#define MSI_VENDORID		0x1462
-#define MSI_MS1034_SUBVENDOR	HDA_MODEL_CONSTRUCT(MSI, 0x0349)
-#define MSI_MS034A_SUBVENDOR	HDA_MODEL_CONSTRUCT(MSI, 0x034a)
-#define MSI_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(MSI, 0xffff)
-
-/* Giga-Byte Technology */
-#define GB_VENDORID		0x1458
-#define GB_G33S2H_SUBVENDOR	HDA_MODEL_CONSTRUCT(GB, 0xa022)
-#define GP_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(GB, 0xffff)
-
-/* Uniwill ? */
-#define UNIWILL_VENDORID	0x1584
-#define UNIWILL_9075_SUBVENDOR	HDA_MODEL_CONSTRUCT(UNIWILL, 0x9075)
-#define UNIWILL_9080_SUBVENDOR	HDA_MODEL_CONSTRUCT(UNIWILL, 0x9080)
-
-
-/* Misc constants.. */
-#define HDA_AMP_VOL_DEFAULT	(-1)
-#define HDA_AMP_MUTE_DEFAULT	(0xffffffff)
-#define HDA_AMP_MUTE_NONE	(0)
-#define HDA_AMP_MUTE_LEFT	(1 << 0)
-#define HDA_AMP_MUTE_RIGHT	(1 << 1)
-#define HDA_AMP_MUTE_ALL	(HDA_AMP_MUTE_LEFT | HDA_AMP_MUTE_RIGHT)
-
-#define HDA_AMP_LEFT_MUTED(v)	((v) & (HDA_AMP_MUTE_LEFT))
-#define HDA_AMP_RIGHT_MUTED(v)	(((v) & HDA_AMP_MUTE_RIGHT) >> 1)
-
-#define HDA_ADC_MONITOR		(1 << 0)
-
-#define HDA_CTL_OUT		1
-#define HDA_CTL_IN		2
-
-#define HDA_GPIO_MAX		8
-/* 0 - 7 = GPIO , 8 = Flush */
-#define HDA_QUIRK_GPIO0		(1 << 0)
-#define HDA_QUIRK_GPIO1		(1 << 1)
-#define HDA_QUIRK_GPIO2		(1 << 2)
-#define HDA_QUIRK_GPIO3		(1 << 3)
-#define HDA_QUIRK_GPIO4		(1 << 4)
-#define HDA_QUIRK_GPIO5		(1 << 5)
-#define HDA_QUIRK_GPIO6		(1 << 6)
-#define HDA_QUIRK_GPIO7		(1 << 7)
-#define HDA_QUIRK_GPIOFLUSH	(1 << 8)
-
-/* 9 - 25 = anything else */
-#define HDA_QUIRK_SOFTPCMVOL	(1 << 9)
-#define HDA_QUIRK_FIXEDRATE	(1 << 10)
-#define HDA_QUIRK_FORCESTEREO	(1 << 11)
-#define HDA_QUIRK_EAPDINV	(1 << 12)
-#define HDA_QUIRK_DMAPOS	(1 << 13)
-#define HDA_QUIRK_SENSEINV	(1 << 14)
-
-/* 26 - 31 = vrefs */
-#define HDA_QUIRK_IVREF50	(1 << 26)
-#define HDA_QUIRK_IVREF80	(1 << 27)
-#define HDA_QUIRK_IVREF100	(1 << 28)
-#define HDA_QUIRK_OVREF50	(1 << 29)
-#define HDA_QUIRK_OVREF80	(1 << 30)
-#define HDA_QUIRK_OVREF100	(1 << 31)
-
-#define HDA_QUIRK_IVREF		(HDA_QUIRK_IVREF50 | HDA_QUIRK_IVREF80 | \
-							HDA_QUIRK_IVREF100)
-#define HDA_QUIRK_OVREF		(HDA_QUIRK_OVREF50 | HDA_QUIRK_OVREF80 | \
-							HDA_QUIRK_OVREF100)
-#define HDA_QUIRK_VREF		(HDA_QUIRK_IVREF | HDA_QUIRK_OVREF)
-
-#if __FreeBSD_version < 600000
-#define taskqueue_drain(...)
-#endif
+#define HDAC_QUIRK_64BIT	(1 << 0)
+#define HDAC_QUIRK_DMAPOS	(1 << 1)
+#define HDAC_QUIRK_MSI		(1 << 2)
 
 static const struct {
 	char *key;
 	uint32_t value;
 } hdac_quirks_tab[] = {
-	{ "gpio0", HDA_QUIRK_GPIO0 },
-	{ "gpio1", HDA_QUIRK_GPIO1 },
-	{ "gpio2", HDA_QUIRK_GPIO2 },
-	{ "gpio3", HDA_QUIRK_GPIO3 },
-	{ "gpio4", HDA_QUIRK_GPIO4 },
-	{ "gpio5", HDA_QUIRK_GPIO5 },
-	{ "gpio6", HDA_QUIRK_GPIO6 },
-	{ "gpio7", HDA_QUIRK_GPIO7 },
-	{ "gpioflush", HDA_QUIRK_GPIOFLUSH },
-	{ "softpcmvol", HDA_QUIRK_SOFTPCMVOL },
-	{ "fixedrate", HDA_QUIRK_FIXEDRATE },
-	{ "forcestereo", HDA_QUIRK_FORCESTEREO },
-	{ "eapdinv", HDA_QUIRK_EAPDINV },
-	{ "dmapos", HDA_QUIRK_DMAPOS },
-	{ "senseinv", HDA_QUIRK_SENSEINV },
-	{ "ivref50", HDA_QUIRK_IVREF50 },
-	{ "ivref80", HDA_QUIRK_IVREF80 },
-	{ "ivref100", HDA_QUIRK_IVREF100 },
-	{ "ovref50", HDA_QUIRK_OVREF50 },
-	{ "ovref80", HDA_QUIRK_OVREF80 },
-	{ "ovref100", HDA_QUIRK_OVREF100 },
-	{ "ivref", HDA_QUIRK_IVREF },
-	{ "ovref", HDA_QUIRK_OVREF },
-	{ "vref", HDA_QUIRK_VREF },
+	{ "64bit", HDAC_QUIRK_DMAPOS },
+	{ "dmapos", HDAC_QUIRK_DMAPOS },
+	{ "msi", HDAC_QUIRK_MSI },
 };
 #define HDAC_QUIRKS_TAB_LEN	\
 		(sizeof(hdac_quirks_tab) / sizeof(hdac_quirks_tab[0]))
@@ -456,105 +74,81 @@
 #define HDA_BDL_MAX	256
 #define HDA_BDL_DEFAULT	HDA_BDL_MIN
 
-#define HDA_BLK_MIN	HDAC_DMA_ALIGNMENT
+#define HDA_BLK_MIN	HDA_DMA_ALIGNMENT
 #define HDA_BLK_ALIGN	(~(HDA_BLK_MIN - 1))
 
 #define HDA_BUFSZ_MIN		4096
 #define HDA_BUFSZ_MAX		65536
 #define HDA_BUFSZ_DEFAULT	16384
 
-#define HDA_PARSE_MAXDEPTH	10
-
-#define HDAC_UNSOLTAG_EVENT_HP		0x00
-
-MALLOC_DEFINE(M_HDAC, "hdac", "High Definition Audio Controller");
-
-const char *HDA_COLORS[16] = {"Unknown", "Black", "Grey", "Blue", "Green", "Red",
-    "Orange", "Yellow", "Purple", "Pink", "Res.A", "Res.B", "Res.C", "Res.D",
-    "White", "Other"};
-
-const char *HDA_DEVS[16] = {"Line-out", "Speaker", "Headphones", "CD",
-    "SPDIF-out", "Digital-out", "Modem-line", "Modem-handset", "Line-in",
-    "AUX", "Mic", "Telephony", "SPDIF-in", "Digital-in", "Res.E", "Other"};
-
-const char *HDA_CONNS[4] = {"Jack", "None", "Fixed", "Both"};
-
-/* Default */
-static uint32_t hdac_fmt[] = {
-	SND_FORMAT(AFMT_S16_LE, 2, 0),
-	0
-};
-
-static struct pcmchan_caps hdac_caps = {48000, 48000, hdac_fmt, 0};
-
-#define HDAC_NO_MSI	1
-#define HDAC_NO_64BIT	2
+MALLOC_DEFINE(M_HDAC, "hdac", "HDA Controller");
 
 static const struct {
 	uint32_t	model;
 	char		*desc;
-	char		flags;
+	char		quirks_on;
+	char		quirks_off;
 } hdac_devices[] = {
-	{ HDA_INTEL_CPT,     "Intel Cougar Point",	0 },
-	{ HDA_INTEL_PATSBURG,"Intel Patsburg",  0 },
-	{ HDA_INTEL_PPT1,    "Intel Panther Point",	0 },
-	{ HDA_INTEL_82801F,  "Intel 82801F",	0 },
-	{ HDA_INTEL_63XXESB, "Intel 631x/632xESB",	0 },
-	{ HDA_INTEL_82801G,  "Intel 82801G",	0 },
-	{ HDA_INTEL_82801H,  "Intel 82801H",	0 },
-	{ HDA_INTEL_82801I,  "Intel 82801I",	0 },
-	{ HDA_INTEL_82801JI, "Intel 82801JI",	0 },
-	{ HDA_INTEL_82801JD, "Intel 82801JD",	0 },
-	{ HDA_INTEL_PCH,     "Intel 5 Series/3400 Series",	0 },
-	{ HDA_INTEL_PCH2,    "Intel 5 Series/3400 Series",	0 },
-	{ HDA_INTEL_SCH,     "Intel SCH",	0 },
-	{ HDA_NVIDIA_MCP51,  "NVidia MCP51",	HDAC_NO_MSI },
-	{ HDA_NVIDIA_MCP55,  "NVidia MCP55",	HDAC_NO_MSI },
-	{ HDA_NVIDIA_MCP61_1, "NVidia MCP61",	0 },
-	{ HDA_NVIDIA_MCP61_2, "NVidia MCP61",	0 },
-	{ HDA_NVIDIA_MCP65_1, "NVidia MCP65",	0 },
-	{ HDA_NVIDIA_MCP65_2, "NVidia MCP65",	0 },
-	{ HDA_NVIDIA_MCP67_1, "NVidia MCP67",	0 },
-	{ HDA_NVIDIA_MCP67_2, "NVidia MCP67",	0 },
-	{ HDA_NVIDIA_MCP73_1, "NVidia MCP73",	0 },
-	{ HDA_NVIDIA_MCP73_2, "NVidia MCP73",	0 },
-	{ HDA_NVIDIA_MCP78_1, "NVidia MCP78",	HDAC_NO_64BIT },
-	{ HDA_NVIDIA_MCP78_2, "NVidia MCP78",	HDAC_NO_64BIT },
-	{ HDA_NVIDIA_MCP78_3, "NVidia MCP78",	HDAC_NO_64BIT },
-	{ HDA_NVIDIA_MCP78_4, "NVidia MCP78",	HDAC_NO_64BIT },
-	{ HDA_NVIDIA_MCP79_1, "NVidia MCP79",	0 },
-	{ HDA_NVIDIA_MCP79_2, "NVidia MCP79",	0 },
-	{ HDA_NVIDIA_MCP79_3, "NVidia MCP79",	0 },
-	{ HDA_NVIDIA_MCP79_4, "NVidia MCP79",	0 },
-	{ HDA_NVIDIA_MCP89_1, "NVidia MCP89",	0 },
-	{ HDA_NVIDIA_MCP89_2, "NVidia MCP89",	0 },
-	{ HDA_NVIDIA_MCP89_3, "NVidia MCP89",	0 },
-	{ HDA_NVIDIA_MCP89_4, "NVidia MCP89",	0 },
-	{ HDA_ATI_SB450,     "ATI SB450",	0 },
-	{ HDA_ATI_SB600,     "ATI SB600",	0 },
-	{ HDA_ATI_RS600,     "ATI RS600",	0 },
-	{ HDA_ATI_RS690,     "ATI RS690",	0 },
-	{ HDA_ATI_RS780,     "ATI RS780",	0 },
-	{ HDA_ATI_R600,      "ATI R600",	0 },
-	{ HDA_ATI_RV610,     "ATI RV610",	0 },
-	{ HDA_ATI_RV620,     "ATI RV620",	0 },
-	{ HDA_ATI_RV630,     "ATI RV630",	0 },
-	{ HDA_ATI_RV635,     "ATI RV635",	0 },
-	{ HDA_ATI_RV710,     "ATI RV710",	0 },
-	{ HDA_ATI_RV730,     "ATI RV730",	0 },
-	{ HDA_ATI_RV740,     "ATI RV740",	0 },
-	{ HDA_ATI_RV770,     "ATI RV770",	0 },
-	{ HDA_RDC_M3010,     "RDC M3010",	0 },
-	{ HDA_VIA_VT82XX,    "VIA VT8251/8237A",0 },
-	{ HDA_SIS_966,       "SiS 966",		0 },
-	{ HDA_ULI_M5461,     "ULI M5461",	0 },
+	{ HDA_INTEL_CPT,     "Intel Cougar Point",	0, 0 },
+	{ HDA_INTEL_PATSBURG,"Intel Patsburg",  0, 0 },
+	{ HDA_INTEL_PPT1,    "Intel Panther Point",	0, 0 },
+	{ HDA_INTEL_82801F,  "Intel 82801F",	0, 0 },
+	{ HDA_INTEL_63XXESB, "Intel 631x/632xESB",	0, 0 },
+	{ HDA_INTEL_82801G,  "Intel 82801G",	0, 0 },
+	{ HDA_INTEL_82801H,  "Intel 82801H",	0, 0 },
+	{ HDA_INTEL_82801I,  "Intel 82801I",	0, 0 },
+	{ HDA_INTEL_82801JI, "Intel 82801JI",	0, 0 },
+	{ HDA_INTEL_82801JD, "Intel 82801JD",	0, 0 },
+	{ HDA_INTEL_PCH,     "Intel 5 Series/3400 Series",	0, 0 },
+	{ HDA_INTEL_PCH2,    "Intel 5 Series/3400 Series",	0, 0 },
+	{ HDA_INTEL_SCH,     "Intel SCH",	0, 0 },
+	{ HDA_NVIDIA_MCP51,  "NVIDIA MCP51",	0, HDAC_QUIRK_MSI },
+	{ HDA_NVIDIA_MCP55,  "NVIDIA MCP55",	0, HDAC_QUIRK_MSI },
+	{ HDA_NVIDIA_MCP61_1, "NVIDIA MCP61",	0, 0 },
+	{ HDA_NVIDIA_MCP61_2, "NVIDIA MCP61",	0, 0 },
+	{ HDA_NVIDIA_MCP65_1, "NVIDIA MCP65",	0, 0 },
+	{ HDA_NVIDIA_MCP65_2, "NVIDIA MCP65",	0, 0 },
+	{ HDA_NVIDIA_MCP67_1, "NVIDIA MCP67",	0, 0 },
+	{ HDA_NVIDIA_MCP67_2, "NVIDIA MCP67",	0, 0 },
+	{ HDA_NVIDIA_MCP73_1, "NVIDIA MCP73",	0, 0 },
+	{ HDA_NVIDIA_MCP73_2, "NVIDIA MCP73",	0, 0 },
+	{ HDA_NVIDIA_MCP78_1, "NVIDIA MCP78",	0, HDAC_QUIRK_64BIT },
+	{ HDA_NVIDIA_MCP78_2, "NVIDIA MCP78",	0, HDAC_QUIRK_64BIT },
+	{ HDA_NVIDIA_MCP78_3, "NVIDIA MCP78",	0, HDAC_QUIRK_64BIT },
+	{ HDA_NVIDIA_MCP78_4, "NVIDIA MCP78",	0, HDAC_QUIRK_64BIT },
+	{ HDA_NVIDIA_MCP79_1, "NVIDIA MCP79",	0, 0 },
+	{ HDA_NVIDIA_MCP79_2, "NVIDIA MCP79",	0, 0 },
+	{ HDA_NVIDIA_MCP79_3, "NVIDIA MCP79",	0, 0 },
+	{ HDA_NVIDIA_MCP79_4, "NVIDIA MCP79",	0, 0 },
+	{ HDA_NVIDIA_MCP89_1, "NVIDIA MCP89",	0, 0 },
+	{ HDA_NVIDIA_MCP89_2, "NVIDIA MCP89",	0, 0 },
+	{ HDA_NVIDIA_MCP89_3, "NVIDIA MCP89",	0, 0 },
+	{ HDA_NVIDIA_MCP89_4, "NVIDIA MCP89",	0, 0 },
+	{ HDA_ATI_SB450,     "ATI SB450",	0, 0 },
+	{ HDA_ATI_SB600,     "ATI SB600",	0, 0 },
+	{ HDA_ATI_RS600,     "ATI RS600",	0, 0 },
+	{ HDA_ATI_RS690,     "ATI RS690",	0, 0 },
+	{ HDA_ATI_RS780,     "ATI RS780",	0, 0 },
+	{ HDA_ATI_R600,      "ATI R600",	0, 0 },
+	{ HDA_ATI_RV610,     "ATI RV610",	0, 0 },
+	{ HDA_ATI_RV620,     "ATI RV620",	0, 0 },
+	{ HDA_ATI_RV630,     "ATI RV630",	0, 0 },
+	{ HDA_ATI_RV635,     "ATI RV635",	0, 0 },
+	{ HDA_ATI_RV710,     "ATI RV710",	0, 0 },
+	{ HDA_ATI_RV730,     "ATI RV730",	0, 0 },
+	{ HDA_ATI_RV740,     "ATI RV740",	0, 0 },
+	{ HDA_ATI_RV770,     "ATI RV770",	0, 0 },
+	{ HDA_RDC_M3010,     "RDC M3010",	0, 0 },
+	{ HDA_VIA_VT82XX,    "VIA VT8251/8237A",0, 0 },
+	{ HDA_SIS_966,       "SiS 966",		0, 0 },
+	{ HDA_ULI_M5461,     "ULI M5461",	0, 0 },
 	/* Unknown */
-	{ HDA_INTEL_ALL,  "Intel (Unknown)"  },
-	{ HDA_NVIDIA_ALL, "NVidia (Unknown)" },
-	{ HDA_ATI_ALL,    "ATI (Unknown)"    },
-	{ HDA_VIA_ALL,    "VIA (Unknown)"    },
-	{ HDA_SIS_ALL,    "SiS (Unknown)"    },
-	{ HDA_ULI_ALL,    "ULI (Unknown)"    },
+	{ HDA_INTEL_ALL,  "Intel (Unknown)",	0, 0 },
+	{ HDA_NVIDIA_ALL, "NVIDIA (Unknown)",	0, 0 },
+	{ HDA_ATI_ALL,    "ATI (Unknown)",	0, 0 },
+	{ HDA_VIA_ALL,    "VIA (Unknown)",	0, 0 },
+	{ HDA_SIS_ALL,    "SiS (Unknown)",	0, 0 },
+	{ HDA_ULI_ALL,    "ULI (Unknown)",	0, 0 },
 };
 #define HDAC_DEVICES_LEN (sizeof(hdac_devices) / sizeof(hdac_devices[0]))
 
@@ -571,482 +165,6 @@
 #define HDAC_PCIESNOOP_LEN	\
 			(sizeof(hdac_pcie_snoop) / sizeof(hdac_pcie_snoop[0]))
 
-static const struct {
-	uint32_t	rate;
-	int		valid;
-	uint16_t	base;
-	uint16_t	mul;
-	uint16_t	div;
-} hda_rate_tab[] = {
-	{   8000, 1, 0x0000, 0x0000, 0x0500 },	/* (48000 * 1) / 6 */
-	{   9600, 0, 0x0000, 0x0000, 0x0400 },	/* (48000 * 1) / 5 */
-	{  12000, 0, 0x0000, 0x0000, 0x0300 },	/* (48000 * 1) / 4 */
-	{  16000, 1, 0x0000, 0x0000, 0x0200 },	/* (48000 * 1) / 3 */
-	{  18000, 0, 0x0000, 0x1000, 0x0700 },	/* (48000 * 3) / 8 */
-	{  19200, 0, 0x0000, 0x0800, 0x0400 },	/* (48000 * 2) / 5 */
-	{  24000, 0, 0x0000, 0x0000, 0x0100 },	/* (48000 * 1) / 2 */
-	{  28800, 0, 0x0000, 0x1000, 0x0400 },	/* (48000 * 3) / 5 */
-	{  32000, 1, 0x0000, 0x0800, 0x0200 },	/* (48000 * 2) / 3 */
-	{  36000, 0, 0x0000, 0x1000, 0x0300 },	/* (48000 * 3) / 4 */
-	{  38400, 0, 0x0000, 0x1800, 0x0400 },	/* (48000 * 4) / 5 */
-	{  48000, 1, 0x0000, 0x0000, 0x0000 },	/* (48000 * 1) / 1 */
-	{  64000, 0, 0x0000, 0x1800, 0x0200 },	/* (48000 * 4) / 3 */
-	{  72000, 0, 0x0000, 0x1000, 0x0100 },	/* (48000 * 3) / 2 */
-	{  96000, 1, 0x0000, 0x0800, 0x0000 },	/* (48000 * 2) / 1 */
-	{ 144000, 0, 0x0000, 0x1000, 0x0000 },	/* (48000 * 3) / 1 */
-	{ 192000, 1, 0x0000, 0x1800, 0x0000 },	/* (48000 * 4) / 1 */
-	{   8820, 0, 0x4000, 0x0000, 0x0400 },	/* (44100 * 1) / 5 */
-	{  11025, 1, 0x4000, 0x0000, 0x0300 },	/* (44100 * 1) / 4 */
-	{  12600, 0, 0x4000, 0x0800, 0x0600 },	/* (44100 * 2) / 7 */
-	{  14700, 0, 0x4000, 0x0000, 0x0200 },	/* (44100 * 1) / 3 */
-	{  17640, 0, 0x4000, 0x0800, 0x0400 },	/* (44100 * 2) / 5 */
-	{  18900, 0, 0x4000, 0x1000, 0x0600 },	/* (44100 * 3) / 7 */
-	{  22050, 1, 0x4000, 0x0000, 0x0100 },	/* (44100 * 1) / 2 */
-	{  25200, 0, 0x4000, 0x1800, 0x0600 },	/* (44100 * 4) / 7 */
-	{  26460, 0, 0x4000, 0x1000, 0x0400 },	/* (44100 * 3) / 5 */
-	{  29400, 0, 0x4000, 0x0800, 0x0200 },	/* (44100 * 2) / 3 */
-	{  33075, 0, 0x4000, 0x1000, 0x0300 },	/* (44100 * 3) / 4 */
-	{  35280, 0, 0x4000, 0x1800, 0x0400 },	/* (44100 * 4) / 5 */
-	{  44100, 1, 0x4000, 0x0000, 0x0000 },	/* (44100 * 1) / 1 */
-	{  58800, 0, 0x4000, 0x1800, 0x0200 },	/* (44100 * 4) / 3 */
-	{  66150, 0, 0x4000, 0x1000, 0x0100 },	/* (44100 * 3) / 2 */
-	{  88200, 1, 0x4000, 0x0800, 0x0000 },	/* (44100 * 2) / 1 */
-	{ 132300, 0, 0x4000, 0x1000, 0x0000 },	/* (44100 * 3) / 1 */
-	{ 176400, 1, 0x4000, 0x1800, 0x0000 },	/* (44100 * 4) / 1 */
-};
-#define HDA_RATE_TAB_LEN (sizeof(hda_rate_tab) / sizeof(hda_rate_tab[0]))
-
-/* All codecs you can eat... */
-#define HDA_CODEC_CONSTRUCT(vendor, id) \
-		(((uint32_t)(vendor##_VENDORID) << 16) | ((id) & 0xffff))
-
-/* Cirrus Logic */
-#define CIRRUSLOGIC_VENDORID	0x1013
-#define HDA_CODEC_CS4206	HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0x4206)
-#define HDA_CODEC_CS4207	HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0x4207)
-#define HDA_CODEC_CSXXXX	HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0xffff)
-
-/* Realtek */
-#define REALTEK_VENDORID	0x10ec
-#define HDA_CODEC_ALC260	HDA_CODEC_CONSTRUCT(REALTEK, 0x0260)
-#define HDA_CODEC_ALC262	HDA_CODEC_CONSTRUCT(REALTEK, 0x0262)
-#define HDA_CODEC_ALC267	HDA_CODEC_CONSTRUCT(REALTEK, 0x0267)
-#define HDA_CODEC_ALC268	HDA_CODEC_CONSTRUCT(REALTEK, 0x0268)
-#define HDA_CODEC_ALC269	HDA_CODEC_CONSTRUCT(REALTEK, 0x0269)
-#define HDA_CODEC_ALC270	HDA_CODEC_CONSTRUCT(REALTEK, 0x0270)
-#define HDA_CODEC_ALC272	HDA_CODEC_CONSTRUCT(REALTEK, 0x0272)
-#define HDA_CODEC_ALC273	HDA_CODEC_CONSTRUCT(REALTEK, 0x0273)
-#define HDA_CODEC_ALC275	HDA_CODEC_CONSTRUCT(REALTEK, 0x0275)
-#define HDA_CODEC_ALC660	HDA_CODEC_CONSTRUCT(REALTEK, 0x0660)
-#define HDA_CODEC_ALC662	HDA_CODEC_CONSTRUCT(REALTEK, 0x0662)
-#define HDA_CODEC_ALC663	HDA_CODEC_CONSTRUCT(REALTEK, 0x0663)
-#define HDA_CODEC_ALC665	HDA_CODEC_CONSTRUCT(REALTEK, 0x0665)
-#define HDA_CODEC_ALC861	HDA_CODEC_CONSTRUCT(REALTEK, 0x0861)
-#define HDA_CODEC_ALC861VD	HDA_CODEC_CONSTRUCT(REALTEK, 0x0862)
-#define HDA_CODEC_ALC880	HDA_CODEC_CONSTRUCT(REALTEK, 0x0880)
-#define HDA_CODEC_ALC882	HDA_CODEC_CONSTRUCT(REALTEK, 0x0882)
-#define HDA_CODEC_ALC883	HDA_CODEC_CONSTRUCT(REALTEK, 0x0883)
-#define HDA_CODEC_ALC885	HDA_CODEC_CONSTRUCT(REALTEK, 0x0885)
-#define HDA_CODEC_ALC887	HDA_CODEC_CONSTRUCT(REALTEK, 0x0887)
-#define HDA_CODEC_ALC888	HDA_CODEC_CONSTRUCT(REALTEK, 0x0888)
-#define HDA_CODEC_ALC889	HDA_CODEC_CONSTRUCT(REALTEK, 0x0889)
-#define HDA_CODEC_ALC892	HDA_CODEC_CONSTRUCT(REALTEK, 0x0892)
-#define HDA_CODEC_ALCXXXX	HDA_CODEC_CONSTRUCT(REALTEK, 0xffff)
-
-/* Analog Devices */
-#define ANALOGDEVICES_VENDORID	0x11d4
-#define HDA_CODEC_AD1884A	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x184a)
-#define HDA_CODEC_AD1882	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1882)
-#define HDA_CODEC_AD1883	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1883)
-#define HDA_CODEC_AD1884	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1884)
-#define HDA_CODEC_AD1984A	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x194a)
-#define HDA_CODEC_AD1984B	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x194b)
-#define HDA_CODEC_AD1981HD	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1981)
-#define HDA_CODEC_AD1983	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1983)
-#define HDA_CODEC_AD1984	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1984)
-#define HDA_CODEC_AD1986A	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1986)
-#define HDA_CODEC_AD1987	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1987)
-#define HDA_CODEC_AD1988	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1988)
-#define HDA_CODEC_AD1988B	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x198b)
-#define HDA_CODEC_AD1882A	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x882a)
-#define HDA_CODEC_AD1989B	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x989b)
-#define HDA_CODEC_ADXXXX	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0xffff)
-
-/* CMedia */
-#define CMEDIA_VENDORID		0x434d
-#define HDA_CODEC_CMI9880	HDA_CODEC_CONSTRUCT(CMEDIA, 0x4980)
-#define HDA_CODEC_CMIXXXX	HDA_CODEC_CONSTRUCT(CMEDIA, 0xffff)
-
-/* Sigmatel */
-#define SIGMATEL_VENDORID	0x8384
-#define HDA_CODEC_STAC9230X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7612)
-#define HDA_CODEC_STAC9230D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7613)
-#define HDA_CODEC_STAC9229X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7614)
-#define HDA_CODEC_STAC9229D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7615)
-#define HDA_CODEC_STAC9228X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7616)
-#define HDA_CODEC_STAC9228D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7617)
-#define HDA_CODEC_STAC9227X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7618)
-#define HDA_CODEC_STAC9227D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7619)
-#define HDA_CODEC_STAC9274	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7620)
-#define HDA_CODEC_STAC9274D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7621)
-#define HDA_CODEC_STAC9273X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7622)
-#define HDA_CODEC_STAC9273D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7623)
-#define HDA_CODEC_STAC9272X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7624)
-#define HDA_CODEC_STAC9272D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7625)
-#define HDA_CODEC_STAC9271X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7626)
-#define HDA_CODEC_STAC9271D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7627)
-#define HDA_CODEC_STAC9274X5NH	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7628)
-#define HDA_CODEC_STAC9274D5NH	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7629)
-#define HDA_CODEC_STAC9250	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7634)
-#define HDA_CODEC_STAC9251	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7636)
-#define HDA_CODEC_IDT92HD700X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7638)
-#define HDA_CODEC_IDT92HD700D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7639)
-#define HDA_CODEC_IDT92HD206X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7645)
-#define HDA_CODEC_IDT92HD206D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7646)
-#define HDA_CODEC_CXD9872RDK	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7661)
-#define HDA_CODEC_STAC9872AK	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7662)
-#define HDA_CODEC_CXD9872AKD	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7664)
-#define HDA_CODEC_STAC9221	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7680)
-#define HDA_CODEC_STAC922XD	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7681)
-#define HDA_CODEC_STAC9221_A2	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7682)
-#define HDA_CODEC_STAC9221D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7683)
-#define HDA_CODEC_STAC9220	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7690)
-#define HDA_CODEC_STAC9200D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7691)
-#define HDA_CODEC_IDT92HD005	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7698)
-#define HDA_CODEC_IDT92HD005D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7699)
-#define HDA_CODEC_STAC9205X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x76a0)
-#define HDA_CODEC_STAC9205D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x76a1)
-#define HDA_CODEC_STAC9204X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x76a2)
-#define HDA_CODEC_STAC9204D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x76a3)
-#define HDA_CODEC_STAC9220_A2	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7880)
-#define HDA_CODEC_STAC9220_A1	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7882)
-#define HDA_CODEC_STACXXXX	HDA_CODEC_CONSTRUCT(SIGMATEL, 0xffff)
-
-/* IDT */
-#define IDT_VENDORID		0x111d
-#define HDA_CODEC_IDT92HD75BX	HDA_CODEC_CONSTRUCT(IDT, 0x7603)
-#define HDA_CODEC_IDT92HD83C1X	HDA_CODEC_CONSTRUCT(IDT, 0x7604)
-#define HDA_CODEC_IDT92HD81B1X	HDA_CODEC_CONSTRUCT(IDT, 0x7605)
-#define HDA_CODEC_IDT92HD75B3	HDA_CODEC_CONSTRUCT(IDT, 0x7608)
-#define HDA_CODEC_IDT92HD73D1	HDA_CODEC_CONSTRUCT(IDT, 0x7674)
-#define HDA_CODEC_IDT92HD73C1	HDA_CODEC_CONSTRUCT(IDT, 0x7675)
-#define HDA_CODEC_IDT92HD73E1	HDA_CODEC_CONSTRUCT(IDT, 0x7676)
-#define HDA_CODEC_IDT92HD71B8	HDA_CODEC_CONSTRUCT(IDT, 0x76b0)
-#define HDA_CODEC_IDT92HD71B7	HDA_CODEC_CONSTRUCT(IDT, 0x76b2)
-#define HDA_CODEC_IDT92HD71B5	HDA_CODEC_CONSTRUCT(IDT, 0x76b6)
-#define HDA_CODEC_IDT92HD83C1C	HDA_CODEC_CONSTRUCT(IDT, 0x76d4)
-#define HDA_CODEC_IDT92HD81B1C	HDA_CODEC_CONSTRUCT(IDT, 0x76d5)
-#define HDA_CODEC_IDTXXXX	HDA_CODEC_CONSTRUCT(IDT, 0xffff)
-
-/* Silicon Image */
-#define SII_VENDORID	0x1095
-#define HDA_CODEC_SII1390	HDA_CODEC_CONSTRUCT(SII, 0x1390)
-#define HDA_CODEC_SII1392	HDA_CODEC_CONSTRUCT(SII, 0x1392)
-#define HDA_CODEC_SIIXXXX	HDA_CODEC_CONSTRUCT(SII, 0xffff)
-
-/* Lucent/Agere */
-#define AGERE_VENDORID	0x11c1
-#define HDA_CODEC_AGEREXXXX	HDA_CODEC_CONSTRUCT(AGERE, 0xffff)
-
-/* Conexant */
-#define CONEXANT_VENDORID	0x14f1
-#define HDA_CODEC_CX20549	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5045)
-#define HDA_CODEC_CX20551	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5047)
-#define HDA_CODEC_CX20561	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5051)
-#define HDA_CODEC_CX20582	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5066)
-#define HDA_CODEC_CX20583	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5067)
-#define HDA_CODEC_CX20584	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5068)
-#define HDA_CODEC_CX20585	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5069)
-#define HDA_CODEC_CX20590	HDA_CODEC_CONSTRUCT(CONEXANT, 0x506e)
-#define HDA_CODEC_CX20631	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5097)
-#define HDA_CODEC_CX20632	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5098)
-#define HDA_CODEC_CX20641	HDA_CODEC_CONSTRUCT(CONEXANT, 0x50a1)
-#define HDA_CODEC_CX20642	HDA_CODEC_CONSTRUCT(CONEXANT, 0x50a2)
-#define HDA_CODEC_CX20651	HDA_CODEC_CONSTRUCT(CONEXANT, 0x50ab)
-#define HDA_CODEC_CX20652	HDA_CODEC_CONSTRUCT(CONEXANT, 0x50ac)
-#define HDA_CODEC_CX20664	HDA_CODEC_CONSTRUCT(CONEXANT, 0x50b8)
-#define HDA_CODEC_CX20665	HDA_CODEC_CONSTRUCT(CONEXANT, 0x50b9)
-#define HDA_CODEC_CXXXXX	HDA_CODEC_CONSTRUCT(CONEXANT, 0xffff)
-
-/* VIA */
-#define HDA_CODEC_VT1708_8	HDA_CODEC_CONSTRUCT(VIA, 0x1708)
-#define HDA_CODEC_VT1708_9	HDA_CODEC_CONSTRUCT(VIA, 0x1709)
-#define HDA_CODEC_VT1708_A	HDA_CODEC_CONSTRUCT(VIA, 0x170a)
-#define HDA_CODEC_VT1708_B	HDA_CODEC_CONSTRUCT(VIA, 0x170b)
-#define HDA_CODEC_VT1709_0	HDA_CODEC_CONSTRUCT(VIA, 0xe710)
-#define HDA_CODEC_VT1709_1	HDA_CODEC_CONSTRUCT(VIA, 0xe711)
-#define HDA_CODEC_VT1709_2	HDA_CODEC_CONSTRUCT(VIA, 0xe712)
-#define HDA_CODEC_VT1709_3	HDA_CODEC_CONSTRUCT(VIA, 0xe713)
-#define HDA_CODEC_VT1709_4	HDA_CODEC_CONSTRUCT(VIA, 0xe714)
-#define HDA_CODEC_VT1709_5	HDA_CODEC_CONSTRUCT(VIA, 0xe715)
-#define HDA_CODEC_VT1709_6	HDA_CODEC_CONSTRUCT(VIA, 0xe716)
-#define HDA_CODEC_VT1709_7	HDA_CODEC_CONSTRUCT(VIA, 0xe717)
-#define HDA_CODEC_VT1708B_0	HDA_CODEC_CONSTRUCT(VIA, 0xe720)
-#define HDA_CODEC_VT1708B_1	HDA_CODEC_CONSTRUCT(VIA, 0xe721)
-#define HDA_CODEC_VT1708B_2	HDA_CODEC_CONSTRUCT(VIA, 0xe722)
-#define HDA_CODEC_VT1708B_3	HDA_CODEC_CONSTRUCT(VIA, 0xe723)
-#define HDA_CODEC_VT1708B_4	HDA_CODEC_CONSTRUCT(VIA, 0xe724)
-#define HDA_CODEC_VT1708B_5	HDA_CODEC_CONSTRUCT(VIA, 0xe725)
-#define HDA_CODEC_VT1708B_6	HDA_CODEC_CONSTRUCT(VIA, 0xe726)
-#define HDA_CODEC_VT1708B_7	HDA_CODEC_CONSTRUCT(VIA, 0xe727)
-#define HDA_CODEC_VT1708S_0	HDA_CODEC_CONSTRUCT(VIA, 0x0397)
-#define HDA_CODEC_VT1708S_1	HDA_CODEC_CONSTRUCT(VIA, 0x1397)
-#define HDA_CODEC_VT1708S_2	HDA_CODEC_CONSTRUCT(VIA, 0x2397)
-#define HDA_CODEC_VT1708S_3	HDA_CODEC_CONSTRUCT(VIA, 0x3397)
-#define HDA_CODEC_VT1708S_4	HDA_CODEC_CONSTRUCT(VIA, 0x4397)
-#define HDA_CODEC_VT1708S_5	HDA_CODEC_CONSTRUCT(VIA, 0x5397)
-#define HDA_CODEC_VT1708S_6	HDA_CODEC_CONSTRUCT(VIA, 0x6397)
-#define HDA_CODEC_VT1708S_7	HDA_CODEC_CONSTRUCT(VIA, 0x7397)
-#define HDA_CODEC_VT1702_0	HDA_CODEC_CONSTRUCT(VIA, 0x0398)
-#define HDA_CODEC_VT1702_1	HDA_CODEC_CONSTRUCT(VIA, 0x1398)
-#define HDA_CODEC_VT1702_2	HDA_CODEC_CONSTRUCT(VIA, 0x2398)
-#define HDA_CODEC_VT1702_3	HDA_CODEC_CONSTRUCT(VIA, 0x3398)
-#define HDA_CODEC_VT1702_4	HDA_CODEC_CONSTRUCT(VIA, 0x4398)
-#define HDA_CODEC_VT1702_5	HDA_CODEC_CONSTRUCT(VIA, 0x5398)
-#define HDA_CODEC_VT1702_6	HDA_CODEC_CONSTRUCT(VIA, 0x6398)
-#define HDA_CODEC_VT1702_7	HDA_CODEC_CONSTRUCT(VIA, 0x7398)
-#define HDA_CODEC_VT1716S_0	HDA_CODEC_CONSTRUCT(VIA, 0x0433)
-#define HDA_CODEC_VT1716S_1	HDA_CODEC_CONSTRUCT(VIA, 0xa721)
-#define HDA_CODEC_VT1718S_0	HDA_CODEC_CONSTRUCT(VIA, 0x0428)
-#define HDA_CODEC_VT1718S_1	HDA_CODEC_CONSTRUCT(VIA, 0x4428)
-#define HDA_CODEC_VT1812	HDA_CODEC_CONSTRUCT(VIA, 0x0448)
-#define HDA_CODEC_VT1818S	HDA_CODEC_CONSTRUCT(VIA, 0x0440)
-#define HDA_CODEC_VT1828S	HDA_CODEC_CONSTRUCT(VIA, 0x4441)
-#define HDA_CODEC_VT2002P_0	HDA_CODEC_CONSTRUCT(VIA, 0x0438)
-#define HDA_CODEC_VT2002P_1	HDA_CODEC_CONSTRUCT(VIA, 0x4438)
-#define HDA_CODEC_VT2020	HDA_CODEC_CONSTRUCT(VIA, 0x0441)
-#define HDA_CODEC_VTXXXX	HDA_CODEC_CONSTRUCT(VIA, 0xffff)
-
-/* ATI */
-#define HDA_CODEC_ATIRS600_1	HDA_CODEC_CONSTRUCT(ATI, 0x793c)
-#define HDA_CODEC_ATIRS600_2	HDA_CODEC_CONSTRUCT(ATI, 0x7919)
-#define HDA_CODEC_ATIRS690	HDA_CODEC_CONSTRUCT(ATI, 0x791a)
-#define HDA_CODEC_ATIR6XX	HDA_CODEC_CONSTRUCT(ATI, 0xaa01)
-#define HDA_CODEC_ATIXXXX	HDA_CODEC_CONSTRUCT(ATI, 0xffff)
-
-/* NVIDIA */
-#define HDA_CODEC_NVIDIAMCP78	HDA_CODEC_CONSTRUCT(NVIDIA, 0x0002)
-#define HDA_CODEC_NVIDIAMCP78_2	HDA_CODEC_CONSTRUCT(NVIDIA, 0x0006)
-#define HDA_CODEC_NVIDIAMCP7A	HDA_CODEC_CONSTRUCT(NVIDIA, 0x0007)
-#define HDA_CODEC_NVIDIAGT220	HDA_CODEC_CONSTRUCT(NVIDIA, 0x000a)
-#define HDA_CODEC_NVIDIAGT21X	HDA_CODEC_CONSTRUCT(NVIDIA, 0x000b)
-#define HDA_CODEC_NVIDIAMCP89	HDA_CODEC_CONSTRUCT(NVIDIA, 0x000c)
-#define HDA_CODEC_NVIDIAGT240	HDA_CODEC_CONSTRUCT(NVIDIA, 0x000d)
-#define HDA_CODEC_NVIDIAMCP67	HDA_CODEC_CONSTRUCT(NVIDIA, 0x0067)
-#define HDA_CODEC_NVIDIAMCP73	HDA_CODEC_CONSTRUCT(NVIDIA, 0x8001)
-#define HDA_CODEC_NVIDIAXXXX	HDA_CODEC_CONSTRUCT(NVIDIA, 0xffff)
-
-/* INTEL */
-#define HDA_CODEC_INTELIP	HDA_CODEC_CONSTRUCT(INTEL, 0x0054)
-#define HDA_CODEC_INTELBL	HDA_CODEC_CONSTRUCT(INTEL, 0x2801)
-#define HDA_CODEC_INTELCA	HDA_CODEC_CONSTRUCT(INTEL, 0x2802)
-#define HDA_CODEC_INTELEL	HDA_CODEC_CONSTRUCT(INTEL, 0x2803)
-#define HDA_CODEC_INTELIP2	HDA_CODEC_CONSTRUCT(INTEL, 0x2804)
-#define HDA_CODEC_INTELCPT	HDA_CODEC_CONSTRUCT(INTEL, 0x2805)
-#define HDA_CODEC_INTELCL	HDA_CODEC_CONSTRUCT(INTEL, 0x29fb)
-#define HDA_CODEC_INTELXXXX	HDA_CODEC_CONSTRUCT(INTEL, 0xffff)
-
-/* Codecs */
-static const struct {
-	uint32_t id;
-	char *name;
-} hdac_codecs[] = {
-	{ HDA_CODEC_CS4206,    "Cirrus Logic CS4206" },
-	{ HDA_CODEC_CS4207,    "Cirrus Logic CS4207" },
-	{ HDA_CODEC_ALC260,    "Realtek ALC260" },
-	{ HDA_CODEC_ALC262,    "Realtek ALC262" },
-	{ HDA_CODEC_ALC267,    "Realtek ALC267" },
-	{ HDA_CODEC_ALC268,    "Realtek ALC268" },
-	{ HDA_CODEC_ALC269,    "Realtek ALC269" },
-	{ HDA_CODEC_ALC270,    "Realtek ALC270" },
-	{ HDA_CODEC_ALC272,    "Realtek ALC272" },
-	{ HDA_CODEC_ALC273,    "Realtek ALC273" },
-	{ HDA_CODEC_ALC275,    "Realtek ALC275" },
-	{ HDA_CODEC_ALC660,    "Realtek ALC660" },
-	{ HDA_CODEC_ALC662,    "Realtek ALC662" },
-	{ HDA_CODEC_ALC663,    "Realtek ALC663" },
-	{ HDA_CODEC_ALC665,    "Realtek ALC665" },
-	{ HDA_CODEC_ALC861,    "Realtek ALC861" },
-	{ HDA_CODEC_ALC861VD,  "Realtek ALC861-VD" },
-	{ HDA_CODEC_ALC880,    "Realtek ALC880" },
-	{ HDA_CODEC_ALC882,    "Realtek ALC882" },
-	{ HDA_CODEC_ALC883,    "Realtek ALC883" },
-	{ HDA_CODEC_ALC885,    "Realtek ALC885" },
-	{ HDA_CODEC_ALC887,    "Realtek ALC887" },
-	{ HDA_CODEC_ALC888,    "Realtek ALC888" },
-	{ HDA_CODEC_ALC889,    "Realtek ALC889" },
-	{ HDA_CODEC_ALC892,    "Realtek ALC892" },
-	{ HDA_CODEC_AD1882,    "Analog Devices AD1882" },
-	{ HDA_CODEC_AD1882A,   "Analog Devices AD1882A" },
-	{ HDA_CODEC_AD1883,    "Analog Devices AD1883" },
-	{ HDA_CODEC_AD1884,    "Analog Devices AD1884" },
-	{ HDA_CODEC_AD1884A,   "Analog Devices AD1884A" },
-	{ HDA_CODEC_AD1981HD,  "Analog Devices AD1981HD" },
-	{ HDA_CODEC_AD1983,    "Analog Devices AD1983" },
-	{ HDA_CODEC_AD1984,    "Analog Devices AD1984" },
-	{ HDA_CODEC_AD1984A,   "Analog Devices AD1984A" },
-	{ HDA_CODEC_AD1984B,   "Analog Devices AD1984B" },
-	{ HDA_CODEC_AD1986A,   "Analog Devices AD1986A" },
-	{ HDA_CODEC_AD1987,    "Analog Devices AD1987" },
-	{ HDA_CODEC_AD1988,    "Analog Devices AD1988A" },
-	{ HDA_CODEC_AD1988B,   "Analog Devices AD1988B" },
-	{ HDA_CODEC_AD1989B,   "Analog Devices AD1989B" },
-	{ HDA_CODEC_CMI9880,   "CMedia CMI9880" },
-	{ HDA_CODEC_CXD9872RDK, "Sigmatel CXD9872RD/K" },
-	{ HDA_CODEC_CXD9872AKD, "Sigmatel CXD9872AKD" },
-	{ HDA_CODEC_STAC9200D, "Sigmatel STAC9200D" },
-	{ HDA_CODEC_STAC9204X, "Sigmatel STAC9204X" },
-	{ HDA_CODEC_STAC9204D, "Sigmatel STAC9204D" },
-	{ HDA_CODEC_STAC9205X, "Sigmatel STAC9205X" },
-	{ HDA_CODEC_STAC9205D, "Sigmatel STAC9205D" },
-	{ HDA_CODEC_STAC9220,  "Sigmatel STAC9220" },
-	{ HDA_CODEC_STAC9220_A1, "Sigmatel STAC9220_A1" },
-	{ HDA_CODEC_STAC9220_A2, "Sigmatel STAC9220_A2" },
-	{ HDA_CODEC_STAC9221,  "Sigmatel STAC9221" },
-	{ HDA_CODEC_STAC9221_A2, "Sigmatel STAC9221_A2" },
-	{ HDA_CODEC_STAC9221D, "Sigmatel STAC9221D" },
-	{ HDA_CODEC_STAC922XD, "Sigmatel STAC9220D/9223D" },
-	{ HDA_CODEC_STAC9227X, "Sigmatel STAC9227X" },
-	{ HDA_CODEC_STAC9227D, "Sigmatel STAC9227D" },
-	{ HDA_CODEC_STAC9228X, "Sigmatel STAC9228X" },
-	{ HDA_CODEC_STAC9228D, "Sigmatel STAC9228D" },
-	{ HDA_CODEC_STAC9229X, "Sigmatel STAC9229X" },
-	{ HDA_CODEC_STAC9229D, "Sigmatel STAC9229D" },
-	{ HDA_CODEC_STAC9230X, "Sigmatel STAC9230X" },
-	{ HDA_CODEC_STAC9230D, "Sigmatel STAC9230D" },
-	{ HDA_CODEC_STAC9250,  "Sigmatel STAC9250" },
-	{ HDA_CODEC_STAC9251,  "Sigmatel STAC9251" },
-	{ HDA_CODEC_STAC9271X, "Sigmatel STAC9271X" },
-	{ HDA_CODEC_STAC9271D, "Sigmatel STAC9271D" },
-	{ HDA_CODEC_STAC9272X, "Sigmatel STAC9272X" },
-	{ HDA_CODEC_STAC9272D, "Sigmatel STAC9272D" },
-	{ HDA_CODEC_STAC9273X, "Sigmatel STAC9273X" },
-	{ HDA_CODEC_STAC9273D, "Sigmatel STAC9273D" },
-	{ HDA_CODEC_STAC9274,  "Sigmatel STAC9274" },
-	{ HDA_CODEC_STAC9274D, "Sigmatel STAC9274D" },
-	{ HDA_CODEC_STAC9274X5NH, "Sigmatel STAC9274X5NH" },
-	{ HDA_CODEC_STAC9274D5NH, "Sigmatel STAC9274D5NH" },
-	{ HDA_CODEC_STAC9872AK, "Sigmatel STAC9872AK" },
-	{ HDA_CODEC_IDT92HD005, "IDT 92HD005" },
-	{ HDA_CODEC_IDT92HD005D, "IDT 92HD005D" },
-	{ HDA_CODEC_IDT92HD206X, "IDT 92HD206X" },
-	{ HDA_CODEC_IDT92HD206D, "IDT 92HD206D" },
-	{ HDA_CODEC_IDT92HD700X, "IDT 92HD700X" },
-	{ HDA_CODEC_IDT92HD700D, "IDT 92HD700D" },
-	{ HDA_CODEC_IDT92HD71B5, "IDT 92HD71B5" },
-	{ HDA_CODEC_IDT92HD71B7, "IDT 92HD71B7" },
-	{ HDA_CODEC_IDT92HD71B8, "IDT 92HD71B8" },
-	{ HDA_CODEC_IDT92HD73C1, "IDT 92HD73C1" },
-	{ HDA_CODEC_IDT92HD73D1, "IDT 92HD73D1" },
-	{ HDA_CODEC_IDT92HD73E1, "IDT 92HD73E1" },
-	{ HDA_CODEC_IDT92HD75B3, "IDT 92HD75B3" },
-	{ HDA_CODEC_IDT92HD75BX, "IDT 92HD75BX" },
-	{ HDA_CODEC_IDT92HD81B1C, "IDT 92HD81B1C" },
-	{ HDA_CODEC_IDT92HD81B1X, "IDT 92HD81B1X" },
-	{ HDA_CODEC_IDT92HD83C1C, "IDT 92HD83C1C" },
-	{ HDA_CODEC_IDT92HD83C1X, "IDT 92HD83C1X" },
-	{ HDA_CODEC_CX20549,   "Conexant CX20549 (Venice)" },
-	{ HDA_CODEC_CX20551,   "Conexant CX20551 (Waikiki)" },
-	{ HDA_CODEC_CX20561,   "Conexant CX20561 (Hermosa)" },
-	{ HDA_CODEC_CX20582,   "Conexant CX20582 (Pebble)" },
-	{ HDA_CODEC_CX20583,   "Conexant CX20583 (Pebble HSF)" },
-	{ HDA_CODEC_CX20584,   "Conexant CX20584" },
-	{ HDA_CODEC_CX20585,   "Conexant CX20585" },
-	{ HDA_CODEC_CX20590,   "Conexant CX20590" },
-	{ HDA_CODEC_CX20631,   "Conexant CX20631" },
-	{ HDA_CODEC_CX20632,   "Conexant CX20632" },
-	{ HDA_CODEC_CX20641,   "Conexant CX20641" },
-	{ HDA_CODEC_CX20642,   "Conexant CX20642" },
-	{ HDA_CODEC_CX20651,   "Conexant CX20651" },
-	{ HDA_CODEC_CX20652,   "Conexant CX20652" },
-	{ HDA_CODEC_CX20664,   "Conexant CX20664" },
-	{ HDA_CODEC_CX20665,   "Conexant CX20665" },
-	{ HDA_CODEC_VT1708_8,  "VIA VT1708_8" },
-	{ HDA_CODEC_VT1708_9,  "VIA VT1708_9" },
-	{ HDA_CODEC_VT1708_A,  "VIA VT1708_A" },
-	{ HDA_CODEC_VT1708_B,  "VIA VT1708_B" },
-	{ HDA_CODEC_VT1709_0,  "VIA VT1709_0" },
-	{ HDA_CODEC_VT1709_1,  "VIA VT1709_1" },
-	{ HDA_CODEC_VT1709_2,  "VIA VT1709_2" },
-	{ HDA_CODEC_VT1709_3,  "VIA VT1709_3" },
-	{ HDA_CODEC_VT1709_4,  "VIA VT1709_4" },
-	{ HDA_CODEC_VT1709_5,  "VIA VT1709_5" },
-	{ HDA_CODEC_VT1709_6,  "VIA VT1709_6" },
-	{ HDA_CODEC_VT1709_7,  "VIA VT1709_7" },
-	{ HDA_CODEC_VT1708B_0, "VIA VT1708B_0" },
-	{ HDA_CODEC_VT1708B_1, "VIA VT1708B_1" },
-	{ HDA_CODEC_VT1708B_2, "VIA VT1708B_2" },
-	{ HDA_CODEC_VT1708B_3, "VIA VT1708B_3" },
-	{ HDA_CODEC_VT1708B_4, "VIA VT1708B_4" },
-	{ HDA_CODEC_VT1708B_5, "VIA VT1708B_5" },
-	{ HDA_CODEC_VT1708B_6, "VIA VT1708B_6" },
-	{ HDA_CODEC_VT1708B_7, "VIA VT1708B_7" },
-	{ HDA_CODEC_VT1708S_0, "VIA VT1708S_0" },
-	{ HDA_CODEC_VT1708S_1, "VIA VT1708S_1" },
-	{ HDA_CODEC_VT1708S_2, "VIA VT1708S_2" },
-	{ HDA_CODEC_VT1708S_3, "VIA VT1708S_3" },
-	{ HDA_CODEC_VT1708S_4, "VIA VT1708S_4" },
-	{ HDA_CODEC_VT1708S_5, "VIA VT1708S_5" },
-	{ HDA_CODEC_VT1708S_6, "VIA VT1708S_6" },
-	{ HDA_CODEC_VT1708S_7, "VIA VT1708S_7" },
-	{ HDA_CODEC_VT1702_0, "VIA VT1702_0" },
-	{ HDA_CODEC_VT1702_1, "VIA VT1702_1" },
-	{ HDA_CODEC_VT1702_2, "VIA VT1702_2" },
-	{ HDA_CODEC_VT1702_3, "VIA VT1702_3" },
-	{ HDA_CODEC_VT1702_4, "VIA VT1702_4" },
-	{ HDA_CODEC_VT1702_5, "VIA VT1702_5" },
-	{ HDA_CODEC_VT1702_6, "VIA VT1702_6" },
-	{ HDA_CODEC_VT1702_7, "VIA VT1702_7" },
-	{ HDA_CODEC_VT1716S_0, "VIA VT1716S_0" },
-	{ HDA_CODEC_VT1716S_1, "VIA VT1716S_1" },
-	{ HDA_CODEC_VT1718S_0, "VIA VT1718S_0" },
-	{ HDA_CODEC_VT1718S_1, "VIA VT1718S_1" },
-	{ HDA_CODEC_VT1812, "VIA VT1812" },
-	{ HDA_CODEC_VT1818S, "VIA VT1818S" },
-	{ HDA_CODEC_VT1828S, "VIA VT1828S" },
-	{ HDA_CODEC_VT2002P_0, "VIA VT2002P_0" },
-	{ HDA_CODEC_VT2002P_1, "VIA VT2002P_1" },
-	{ HDA_CODEC_VT2020, "VIA VT2020" },
-	{ HDA_CODEC_ATIRS600_1,"ATI RS600 HDMI" },
-	{ HDA_CODEC_ATIRS600_2,"ATI RS600 HDMI" },
-	{ HDA_CODEC_ATIRS690,  "ATI RS690/780 HDMI" },
-	{ HDA_CODEC_ATIR6XX,   "ATI R6xx HDMI" },
-	{ HDA_CODEC_NVIDIAMCP67, "NVidia MCP67 HDMI" },
-	{ HDA_CODEC_NVIDIAMCP73, "NVidia MCP73 HDMI" },
-	{ HDA_CODEC_NVIDIAMCP78, "NVidia MCP78 HDMI" },
-	{ HDA_CODEC_NVIDIAMCP78_2, "NVidia MCP78 HDMI" },
-	{ HDA_CODEC_NVIDIAMCP7A, "NVidia MCP7A HDMI" },
-	{ HDA_CODEC_NVIDIAGT220, "NVidia GT220 HDMI" },
-	{ HDA_CODEC_NVIDIAGT21X, "NVidia GT21x HDMI" },
-	{ HDA_CODEC_NVIDIAMCP89, "NVidia MCP89 HDMI" },
-	{ HDA_CODEC_NVIDIAGT240, "NVidia GT240 HDMI" },
-	{ HDA_CODEC_INTELIP,   "Intel Ibex Peak HDMI" },
-	{ HDA_CODEC_INTELBL,   "Intel Bearlake HDMI" },
-	{ HDA_CODEC_INTELCA,   "Intel Cantiga HDMI" },
-	{ HDA_CODEC_INTELEL,   "Intel Eaglelake HDMI" },
-	{ HDA_CODEC_INTELIP2,  "Intel Ibex Peak HDMI" },
-	{ HDA_CODEC_INTELCPT,  "Intel Cougar Point HDMI" },
-	{ HDA_CODEC_INTELCL,   "Intel Crestline HDMI" },
-	{ HDA_CODEC_SII1390,   "Silicon Image SiI1390 HDMI" },
-	{ HDA_CODEC_SII1392,   "Silicon Image SiI1392 HDMI" },
-	/* Unknown codec */
-	{ HDA_CODEC_ALCXXXX,   "Realtek (Unknown)" },
-	{ HDA_CODEC_ADXXXX,    "Analog Devices (Unknown)" },
-	{ HDA_CODEC_CSXXXX,    "Cirrus Logic (Unknown)" },
-	{ HDA_CODEC_CMIXXXX,   "CMedia (Unknown)" },
-	{ HDA_CODEC_STACXXXX,  "Sigmatel (Unknown)" },
-	{ HDA_CODEC_SIIXXXX,   "Silicon Image (Unknown)" },
-	{ HDA_CODEC_AGEREXXXX, "Lucent/Agere Systems (Unknown)" },
-	{ HDA_CODEC_CXXXXX,    "Conexant (Unknown)" },
-	{ HDA_CODEC_VTXXXX,    "VIA (Unknown)" },
-	{ HDA_CODEC_ATIXXXX,   "ATI (Unknown)" },
-	{ HDA_CODEC_NVIDIAXXXX,"NVidia (Unknown)" },
-	{ HDA_CODEC_INTELXXXX, "Intel (Unknown)" },
-	{ HDA_CODEC_IDTXXXX,   "IDT (Unknown)" },
-};
-#define HDAC_CODECS_LEN	(sizeof(hdac_codecs) / sizeof(hdac_codecs[0]))
-
-
 /****************************************************************************
  * Function prototypes
  ****************************************************************************/
@@ -1065,392 +183,78 @@
 static void	hdac_rirb_init(struct hdac_softc *);
 static void	hdac_corb_start(struct hdac_softc *);
 static void	hdac_rirb_start(struct hdac_softc *);
-static void	hdac_scan_codecs(struct hdac_softc *);
-static void	hdac_probe_codec(struct hdac_codec *);
-static void	hdac_probe_function(struct hdac_codec *, nid_t);
-static int	hdac_pcmchannel_setup(struct hdac_chan *);
 
 static void	hdac_attach2(void *);
 
-static uint32_t	hdac_command_sendone_internal(struct hdac_softc *,
-							uint32_t, int);
-static void	hdac_command_send_internal(struct hdac_softc *,
-					struct hdac_command_list *, int);
+static uint32_t	hdac_send_command(struct hdac_softc *, nid_t, uint32_t);
 
 static int	hdac_probe(device_t);
 static int	hdac_attach(device_t);
 static int	hdac_detach(device_t);
 static int	hdac_suspend(device_t);
 static int	hdac_resume(device_t);
-static void	hdac_widget_connection_select(struct hdac_widget *, uint8_t);
-static void	hdac_audio_ctl_amp_set(struct hdac_audio_ctl *,
-						uint32_t, int, int);
-static struct	hdac_audio_ctl *hdac_audio_ctl_amp_get(struct hdac_devinfo *,
-							nid_t, int, int, int);
-static void	hdac_audio_ctl_amp_set_internal(struct hdac_softc *,
-				nid_t, nid_t, int, int, int, int, int, int);
-static struct	hdac_widget *hdac_widget_get(struct hdac_devinfo *, nid_t);
 
 static int	hdac_rirb_flush(struct hdac_softc *sc);
 static int	hdac_unsolq_flush(struct hdac_softc *sc);
 
-static void	hdac_dump_pin_config(struct hdac_widget *w, uint32_t conf);
+#define hdac_command(a1, a2, a3)	\
+		hdac_send_command(a1, a3, a2)
 
-#define hdac_command(a1, a2, a3)	\
-		hdac_command_sendone_internal(a1, a2, a3)
+/* This function surely going to make its way into upper level someday. */
+static void
+hdac_config_fetch(struct hdac_softc *sc, uint32_t *on, uint32_t *off)
+{
+	const char *res = NULL;
+	int i = 0, j, k, len, inv;
 
-#define hdac_codec_id(c)							\
-		((uint32_t)((c == NULL) ? 0x00000000 :	\
-		((((uint32_t)(c)->vendor_id & 0x0000ffff) << 16) |	\
-		((uint32_t)(c)->device_id & 0x0000ffff))))
-
-static char *
-hdac_codec_name(struct hdac_codec *codec)
-{
-	uint32_t id;
-	int i;
-
-	id = hdac_codec_id(codec);
-
-	for (i = 0; i < HDAC_CODECS_LEN; i++) {
-		if (HDA_DEV_MATCH(hdac_codecs[i].id, id))
-			return (hdac_codecs[i].name);
-	}
-
-	return ((id == 0x00000000) ? "NULL Codec" : "Unknown Codec");
-}
-
-static char *
-hdac_audio_ctl_ossmixer_mask2allname(uint32_t mask, char *buf, size_t len)
-{
-	static char *ossname[] = SOUND_DEVICE_NAMES;
-	int i, first = 1;
-
-	bzero(buf, len);
-	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-		if (mask & (1 << i)) {
-			if (first == 0)
-				strlcat(buf, ", ", len);
-			strlcat(buf, ossname[i], len);
-			first = 0;
+	if (resource_string_value(device_get_name(sc->dev),
+	    device_get_unit(sc->dev), "config", &res) != 0)
+		return;
+	if (!(res != NULL && strlen(res) > 0))
+		return;
+	HDA_BOOTVERBOSE(
+		device_printf(sc->dev, "Config options:");
+	);
+	for (;;) {
+		while (res[i] != '\0' &&
+		    (res[i] == ',' || isspace(res[i]) != 0))
+			i++;
+		if (res[i] == '\0') {
+			HDA_BOOTVERBOSE(
+				printf("\n");
+			);
+			return;
 		}
-	}
-	return (buf);
-}
-
-static struct hdac_audio_ctl *
-hdac_audio_ctl_each(struct hdac_devinfo *devinfo, int *index)
-{
-	if (devinfo == NULL ||
-	    devinfo->node_type != HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO ||
-	    index == NULL || devinfo->function.audio.ctl == NULL ||
-	    devinfo->function.audio.ctlcnt < 1 ||
-	    *index < 0 || *index >= devinfo->function.audio.ctlcnt)
-		return (NULL);
-	return (&devinfo->function.audio.ctl[(*index)++]);
-}
-
-static struct hdac_audio_ctl *
-hdac_audio_ctl_amp_get(struct hdac_devinfo *devinfo, nid_t nid, int dir,
-						int index, int cnt)
-{
-	struct hdac_audio_ctl *ctl;
-	int i, found = 0;
-
-	if (devinfo == NULL || devinfo->function.audio.ctl == NULL)
-		return (NULL);
-
-	i = 0;
-	while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) {
-		if (ctl->enable == 0)
-			continue;
-		if (ctl->widget->nid != nid)
-			continue;
-		if (dir && ctl->ndir != dir)
-			continue;
-		if (index >= 0 && ctl->ndir == HDA_CTL_IN &&
-		    ctl->dir == ctl->ndir && ctl->index != index)
-			continue;
-		found++;
-		if (found == cnt || cnt <= 0)
-			return (ctl);
-	}
-
-	return (NULL);
-}
-
-/*
- * Jack detection (Speaker/HP redirection) event handler.
- */
-static void
-hdac_hp_switch_handler(struct hdac_devinfo *devinfo)
-{
-	struct hdac_audio_as *as;
-	struct hdac_softc *sc;
-	struct hdac_widget *w;
-	struct hdac_audio_ctl *ctl;
-	uint32_t val, res;
-	int i, j;
-	nid_t cad;
-
-	if (devinfo == NULL || devinfo->codec == NULL ||
-	    devinfo->codec->sc == NULL)
-		return;
-
-	sc = devinfo->codec->sc;
-	cad = devinfo->codec->cad;
-	as = devinfo->function.audio.as;
-	for (i = 0; i < devinfo->function.audio.ascnt; i++) {
-		if (as[i].hpredir < 0)
-			continue;
-	
-		w = hdac_widget_get(devinfo, as[i].pins[15]);
-		if (w == NULL || w->enable == 0 || w->type !=
-		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-			continue;
-
-		res = hdac_command(sc,
-		    HDA_CMD_GET_PIN_SENSE(cad, as[i].pins[15]), cad);
-
-		HDA_BOOTVERBOSE(
-			device_printf(sc->dev,
-			    "Pin sense: nid=%d res=0x%08x\n",
-			    as[i].pins[15], res);
-		);
-
-		res = HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT(res);
-		if (devinfo->function.audio.quirks & HDA_QUIRK_SENSEINV)
-			res ^= 1;
-
-		/* (Un)Mute headphone pin. */
-		ctl = hdac_audio_ctl_amp_get(devinfo,
-		    as[i].pins[15], HDA_CTL_IN, -1, 1);
-		if (ctl != NULL && ctl->mute) {
-			/* If pin has muter - use it. */
-			val = (res != 0) ? 0 : 1;
-			if (val != ctl->forcemute) {
-				ctl->forcemute = val;
-				hdac_audio_ctl_amp_set(ctl,
-				    HDA_AMP_MUTE_DEFAULT,
-				    HDA_AMP_VOL_DEFAULT, HDA_AMP_VOL_DEFAULT);
+		j = i;
+		while (res[j] != '\0' &&
+		    !(res[j] == ',' || isspace(res[j]) != 0))
+			j++;
+		len = j - i;
+		if (len > 2 && strncmp(res + i, "no", 2) == 0)
+			inv = 2;
+		else
+			inv = 0;
+		for (k = 0; len > inv && k < HDAC_QUIRKS_TAB_LEN; k++) {
+			if (strncmp(res + i + inv,
+			    hdac_quirks_tab[k].key, len - inv) != 0)
+				continue;
+			if (len - inv != strlen(hdac_quirks_tab[k].key))
+				continue;
+			HDA_BOOTVERBOSE(
+				printf(" %s%s", (inv != 0) ? "no" : "",
+				    hdac_quirks_tab[k].key);
+			);
+			if (inv == 0) {
+				*on |= hdac_quirks_tab[k].value;
+				*on &= ~hdac_quirks_tab[k].value;
+			} else if (inv != 0) {
+				*off |= hdac_quirks_tab[k].value;
+				*off &= ~hdac_quirks_tab[k].value;
 			}
-		} else {
-			/* If there is no muter - disable pin output. */
-			w = hdac_widget_get(devinfo, as[i].pins[15]);
-			if (w != NULL && w->type ==
-			    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
-				if (res != 0)
-					val = w->wclass.pin.ctrl |
-					    HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
-				else
-					val = w->wclass.pin.ctrl &
-					    ~HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
-				if (val != w->wclass.pin.ctrl) {
-					w->wclass.pin.ctrl = val;
-					hdac_command(sc,
-					    HDA_CMD_SET_PIN_WIDGET_CTRL(cad,
-					    w->nid, w->wclass.pin.ctrl), cad);
-				}
-			}
-		}
-		/* (Un)Mute other pins. */
-		for (j = 0; j < 15; j++) {
-			if (as[i].pins[j] <= 0)
-				continue;
-			ctl = hdac_audio_ctl_amp_get(devinfo,
-			    as[i].pins[j], HDA_CTL_IN, -1, 1);
-			if (ctl != NULL && ctl->mute) {
-				/* If pin has muter - use it. */
-				val = (res != 0) ? 1 : 0;
-				if (val == ctl->forcemute)
-					continue;
-				ctl->forcemute = val;
-				hdac_audio_ctl_amp_set(ctl,
-				    HDA_AMP_MUTE_DEFAULT,
-				    HDA_AMP_VOL_DEFAULT, HDA_AMP_VOL_DEFAULT);
-				continue;
-			}
-			/* If there is no muter - disable pin output. */
-			w = hdac_widget_get(devinfo, as[i].pins[j]);
-			if (w != NULL && w->type ==
-			    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
-				if (res != 0)
-					val = w->wclass.pin.ctrl &
-					    ~HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
-				else
-					val = w->wclass.pin.ctrl |
-					    HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
-				if (val != w->wclass.pin.ctrl) {
-					w->wclass.pin.ctrl = val;
-					hdac_command(sc,
-					    HDA_CMD_SET_PIN_WIDGET_CTRL(cad,
-					    w->nid, w->wclass.pin.ctrl), cad);
-				}
-			}
-		}
-	}
-}
-
-/*
- * Callback for poll based jack detection.
- */
-static void
-hdac_jack_poll_callback(void *arg)
-{
-	struct hdac_devinfo *devinfo = arg;
-	struct hdac_softc *sc;
-
-	if (devinfo == NULL || devinfo->codec == NULL ||
-	    devinfo->codec->sc == NULL)
-		return;
-	sc = devinfo->codec->sc;
-	hdac_lock(sc);
-	if (sc->poll_ival == 0) {
-		hdac_unlock(sc);
-		return;
-	}
-	hdac_hp_switch_handler(devinfo);
-	callout_reset(&sc->poll_jack, sc->poll_ival,
-	    hdac_jack_poll_callback, devinfo);
-	hdac_unlock(sc);
-}
-
-/*
- * Jack detection initializer.
- */
-static void
-hdac_hp_switch_init(struct hdac_devinfo *devinfo)
-{
-        struct hdac_softc *sc = devinfo->codec->sc;
-	struct hdac_audio_as *as = devinfo->function.audio.as;
-        struct hdac_widget *w;
-        uint32_t id;
-        int i, enable = 0, poll = 0;
-        nid_t cad;
-							
-	id = hdac_codec_id(devinfo->codec);
-	cad = devinfo->codec->cad;
-	for (i = 0; i < devinfo->function.audio.ascnt; i++) {
-		if (as[i].hpredir < 0)
-			continue;
-	
-		w = hdac_widget_get(devinfo, as[i].pins[15]);
-		if (w == NULL || w->enable == 0 || w->type !=
-		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-			continue;
-		if (HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(w->wclass.pin.cap) == 0 ||
-		    (HDA_CONFIG_DEFAULTCONF_MISC(w->wclass.pin.config) & 1) != 0) {
-			device_printf(sc->dev,
-			    "No jack detection support at pin %d\n",
-			    as[i].pins[15]);
-			continue;
-		}
-		enable = 1;
-		if (HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP(w->param.widget_cap)) {
-			hdac_command(sc,
-			    HDA_CMD_SET_UNSOLICITED_RESPONSE(cad, w->nid,
-			    HDA_CMD_SET_UNSOLICITED_RESPONSE_ENABLE |
-			    HDAC_UNSOLTAG_EVENT_HP), cad);
-		} else
-			poll = 1;
-		HDA_BOOTVERBOSE(
-			device_printf(sc->dev,
-			    "Enabling headphone/speaker "
-			    "audio routing switching:\n");
-			device_printf(sc->dev, "\tas=%d sense nid=%d [%s]\n",
-			    i, w->nid, (poll != 0) ? "POLL" : "UNSOL");
-		);
-	}
-	if (enable) {
-		hdac_hp_switch_handler(devinfo);
-		if (poll) {
-			callout_reset(&sc->poll_jack, 1,
-			    hdac_jack_poll_callback, devinfo);
-		}
-	}
-}
-
-/*
- * Unsolicited messages handler.
- */
-static void
-hdac_unsolicited_handler(struct hdac_codec *codec, uint32_t tag)
-{
-	struct hdac_softc *sc;
-	struct hdac_devinfo *devinfo = NULL;
-	int i;
-
-	if (codec == NULL || codec->sc == NULL)
-		return;
-
-	sc = codec->sc;
-
-	HDA_BOOTVERBOSE(
-		device_printf(sc->dev, "Unsol Tag: 0x%08x\n", tag);
-	);
-
-	for (i = 0; i < codec->num_fgs; i++) {
-		if (codec->fgs[i].node_type ==
-		    HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO) {
-			devinfo = &codec->fgs[i];
 			break;
 		}
+		i = j;
 	}
-
-	if (devinfo == NULL)
-		return;
-
-	switch (tag) {
-	case HDAC_UNSOLTAG_EVENT_HP:
-		hdac_hp_switch_handler(devinfo);
-		break;
-	default:
-		device_printf(sc->dev, "Unknown unsol tag: 0x%08x!\n", tag);
-		break;
-	}
-}
-
-static int
-hdac_stream_intr(struct hdac_softc *sc, struct hdac_chan *ch)
-{
-	/* XXX to be removed */
-#ifdef HDAC_INTR_EXTRA
-	uint32_t res;
-#endif
-
-	if (!(ch->flags & HDAC_CHN_RUNNING))
-		return (0);
-
-	/* XXX to be removed */
-#ifdef HDAC_INTR_EXTRA
-	res = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDSTS);
-#endif
-
-	/* XXX to be removed */
-#ifdef HDAC_INTR_EXTRA
-	HDA_BOOTVERBOSE(
-		if (res & (HDAC_SDSTS_DESE | HDAC_SDSTS_FIFOE))
-			device_printf(ch->pdevinfo->dev,
-			    "PCMDIR_%s intr triggered beyond stream boundary:"
-			    "%08x\n",
-			    (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC", res);
-	);
-#endif
-
-	HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDSTS,
-	    HDAC_SDSTS_DESE | HDAC_SDSTS_FIFOE | HDAC_SDSTS_BCIS );
-
-	/* XXX to be removed */
-#ifdef HDAC_INTR_EXTRA
-	if (res & HDAC_SDSTS_BCIS) {
-#endif
-		return (1);
-	/* XXX to be removed */
-#ifdef HDAC_INTR_EXTRA
-	}
-#endif
-
-	return (0);
 }
 
 /****************************************************************************
@@ -1462,69 +266,70 @@
 hdac_intr_handler(void *context)
 {
 	struct hdac_softc *sc;
+	device_t dev;
 	uint32_t intsts;
 	uint8_t rirbsts;
-	struct hdac_rirb *rirb_base;
-	uint32_t trigger;
 	int i;
 
 	sc = (struct hdac_softc *)context;
+	hdac_lock(sc);
 
-	hdac_lock(sc);
-	if (sc->polling != 0) {
+	/* Do we have anything to do? */
+	intsts = HDAC_READ_4(&sc->mem, HDAC_INTSTS);
+	if ((intsts & HDAC_INTSTS_GIS) == 0) {
 		hdac_unlock(sc);
 		return;
 	}
 
-	/* Do we have anything to do? */
-	intsts = HDAC_READ_4(&sc->mem, HDAC_INTSTS);
-	if (!HDA_FLAG_MATCH(intsts, HDAC_INTSTS_GIS)) {
+	/* Was this a controller interrupt? */
+	if (intsts & HDAC_INTSTS_CIS) {
+		rirbsts = HDAC_READ_1(&sc->mem, HDAC_RIRBSTS);
+		/* Get as many responses that we can */
+		while (rirbsts & HDAC_RIRBSTS_RINTFL) {
+			HDAC_WRITE_1(&sc->mem,
+			    HDAC_RIRBSTS, HDAC_RIRBSTS_RINTFL);
+			hdac_rirb_flush(sc);
+			rirbsts = HDAC_READ_1(&sc->mem, HDAC_RIRBSTS);
+		}
+		if (sc->unsolq_rp != sc->unsolq_wp)
+			taskqueue_enqueue(taskqueue_thread, &sc->unsolq_task);
+	}
+
+	if (intsts & HDAC_INTSTS_SIS_MASK) {
+		for (i = 0; i < sc->num_ss; i++) {
+			if ((intsts & (1 << i)) == 0)
+				continue;
+			HDAC_WRITE_1(&sc->mem, (i << 5) + HDAC_SDSTS,
+			    HDAC_SDSTS_DESE | HDAC_SDSTS_FIFOE | HDAC_SDSTS_BCIS );
+			if ((dev = sc->streams[i].dev) != NULL) {
+				HDAC_STREAM_INTR(dev,
+				    sc->streams[i].dir, sc->streams[i].stream);
+			}
+		}
+	}
+
+	HDAC_WRITE_4(&sc->mem, HDAC_INTSTS, intsts);
+	hdac_unlock(sc);
+}
+
+static void
+hdac_poll_callback(void *arg)
+{
+	struct hdac_softc *sc = arg;
+
+	if (sc == NULL)
+		return;
+
+	hdac_lock(sc);
+	if (sc->polling == 0) {
 		hdac_unlock(sc);
 		return;
 	}
-
-	trigger = 0;
-
-	/* Was this a controller interrupt? */
-	if (HDA_FLAG_MATCH(intsts, HDAC_INTSTS_CIS)) {
-		rirb_base = (struct hdac_rirb *)sc->rirb_dma.dma_vaddr;
-		rirbsts = HDAC_READ_1(&sc->mem, HDAC_RIRBSTS);
-		/* Get as many responses that we can */
-		while (HDA_FLAG_MATCH(rirbsts, HDAC_RIRBSTS_RINTFL)) {
-			HDAC_WRITE_1(&sc->mem,
-			    HDAC_RIRBSTS, HDAC_RIRBSTS_RINTFL);
-			if (hdac_rirb_flush(sc) != 0)
-				trigger |= HDAC_TRIGGER_UNSOL;
-			rirbsts = HDAC_READ_1(&sc->mem, HDAC_RIRBSTS);
-		}
-		/* XXX to be removed */
-		/* Clear interrupt and exit */
-#ifdef HDAC_INTR_EXTRA
-		HDAC_WRITE_4(&sc->mem, HDAC_INTSTS, HDAC_INTSTS_CIS);
-#endif
-	}
-
-	if (intsts & HDAC_INTSTS_SIS_MASK) {
-		for (i = 0; i < sc->num_chans; i++) {
-			if ((intsts & (1 << (sc->chans[i].off >> 5))) &&
-			    hdac_stream_intr(sc, &sc->chans[i]) != 0)
-				trigger |= (1 << i);
-		}
-		/* XXX to be removed */
-#ifdef HDAC_INTR_EXTRA
-		HDAC_WRITE_4(&sc->mem, HDAC_INTSTS, intsts &
-		    HDAC_INTSTS_SIS_MASK);
-#endif
-	}
-
+	callout_reset(&sc->poll_callout, sc->poll_ival,
+	    hdac_poll_callback, sc);
 	hdac_unlock(sc);
 
-	for (i = 0; i < sc->num_chans; i++) {
-		if (trigger & (1 << i))
-			chn_intr(sc->chans[i].c);
-	}
-	if (trigger & HDAC_TRIGGER_UNSOL)
-		taskqueue_enqueue(taskqueue_thread, &sc->unsolq_task);
+	hdac_intr_handler(sc);
 }
 
 /****************************************************************************
@@ -1577,11 +382,11 @@
 		device_printf(sc->dev, "Unable to put hdac in reset\n");
 		return (ENXIO);
 	}
-	
+
 	/* If wakeup is not requested - leave the controller in reset state. */
 	if (!wakeup)
 		return (0);
-	
+
 	DELAY(100);
 	gctl = HDAC_READ_4(&sc->mem, HDAC_GCTL);
 	HDAC_WRITE_4(&sc->mem, HDAC_GCTL, gctl | HDAC_GCTL_CRST);
@@ -1629,8 +434,13 @@
 	sc->num_iss = HDAC_GCAP_ISS(gcap);
 	sc->num_oss = HDAC_GCAP_OSS(gcap);
 	sc->num_bss = HDAC_GCAP_BSS(gcap);
+	sc->num_ss = sc->num_iss + sc->num_oss + sc->num_bss;
 	sc->num_sdo = HDAC_GCAP_NSDO(gcap);
-	sc->support_64bit = HDA_FLAG_MATCH(gcap, HDAC_GCAP_64OK);
+	sc->support_64bit = (gcap & HDAC_GCAP_64OK) != 0;
+	if (sc->quirks_on & HDAC_QUIRK_64BIT)
+		sc->support_64bit = 1;
+	else if (sc->quirks_off & HDAC_QUIRK_64BIT)
+		sc->support_64bit = 0;
 
 	corbsize = HDAC_READ_1(&sc->mem, HDAC_CORBSIZE);
 	if ((corbsize & HDAC_CORBSIZE_CORBSZCAP_256) ==
@@ -1707,7 +517,7 @@
 	bus_size_t roundsz;
 	int result;
 
-	roundsz = roundup2(size, HDAC_DMA_ALIGNMENT);
+	roundsz = roundup2(size, HDA_DMA_ALIGNMENT);
 	bzero(dma, sizeof(*dma));
 
 	/*
@@ -1715,7 +525,7 @@
 	 */
 	result = bus_dma_tag_create(
 	    bus_get_dma_tag(sc->dev),		/* parent */
-	    HDAC_DMA_ALIGNMENT,			/* alignment */
+	    HDA_DMA_ALIGNMENT,			/* alignment */
 	    0,					/* boundary */
 	    (sc->support_64bit) ? BUS_SPACE_MAXADDR :
 		BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
@@ -1863,12 +673,10 @@
 	irq = &sc->irq;
 	irq->irq_rid = 0x0;
 
-	if ((sc->flags & HDAC_F_MSI) &&
+	if ((sc->quirks_off & HDAC_QUIRK_MSI) == 0 &&
 	    (result = pci_msi_count(sc->dev)) == 1 &&
 	    pci_alloc_msi(sc->dev, &result) == 0)
 		irq->irq_rid = 0x1;
-	else
-		sc->flags &= ~HDAC_F_MSI;
 
 	irq->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ,
 	    &irq->irq_rid, RF_SHAREABLE | RF_ACTIVE);
@@ -2058,884 +866,10 @@
 	HDAC_WRITE_1(&sc->mem, HDAC_RIRBCTL, rirbctl);
 }
 
-
-/****************************************************************************
- * void hdac_scan_codecs(struct hdac_softc *, int)
- *
- * Scan the bus for available codecs, starting with num.
- ****************************************************************************/
-static void
-hdac_scan_codecs(struct hdac_softc *sc)
-{
-	struct hdac_codec *codec;
-	int i;
-	uint16_t statests;
-
-	statests = HDAC_READ_2(&sc->mem, HDAC_STATESTS);
-	for (i = 0; i < HDAC_CODEC_MAX; i++) {
-		if (HDAC_STATESTS_SDIWAKE(statests, i)) {
-			/* We have found a codec. */
-			codec = (struct hdac_codec *)malloc(sizeof(*codec),
-			    M_HDAC, M_ZERO | M_NOWAIT);
-			if (codec == NULL) {
-				device_printf(sc->dev,
-				    "Unable to allocate memory for codec\n");
-				continue;
-			}
-			codec->commands = NULL;
-			codec->responses_received = 0;
-			codec->verbs_sent = 0;
-			codec->sc = sc;
-			codec->cad = i;
-			sc->codecs[i] = codec;
-			hdac_probe_codec(codec);
-		}
-	}
-	/* All codecs have been probed, now try to attach drivers to them */
-	/* bus_generic_attach(sc->dev); */
-}
-
-/****************************************************************************
- * void hdac_probe_codec(struct hdac_softc *, int)
- *
- * Probe a the given codec_id for available function groups.
- ****************************************************************************/
-static void
-hdac_probe_codec(struct hdac_codec *codec)
-{
-	struct hdac_softc *sc = codec->sc;
-	uint32_t vendorid, revisionid, subnode;
-	int startnode;
-	int endnode;
-	int i;
-	nid_t cad = codec->cad;
-
-	HDA_BOOTVERBOSE(
-		device_printf(sc->dev, "Probing codec #%d...\n", cad);
-	);
-	vendorid = hdac_command(sc,
-	    HDA_CMD_GET_PARAMETER(cad, 0x0, HDA_PARAM_VENDOR_ID),
-	    cad);
-	revisionid = hdac_command(sc,
-	    HDA_CMD_GET_PARAMETER(cad, 0x0, HDA_PARAM_REVISION_ID),
-	    cad);
-	codec->vendor_id = HDA_PARAM_VENDOR_ID_VENDOR_ID(vendorid);
-	codec->device_id = HDA_PARAM_VENDOR_ID_DEVICE_ID(vendorid);
-	codec->revision_id = HDA_PARAM_REVISION_ID_REVISION_ID(revisionid);
-	codec->stepping_id = HDA_PARAM_REVISION_ID_STEPPING_ID(revisionid);
-
-	if (vendorid == HDAC_INVALID && revisionid == HDAC_INVALID) {
-		device_printf(sc->dev, "Codec #%d is not responding!"
-		    " Probing aborted.\n", cad);
-		return;
-	}
-
-	device_printf(sc->dev, "HDA Codec #%d: %s\n",
-	    cad, hdac_codec_name(codec));
-	HDA_BOOTVERBOSE(
-		device_printf(sc->dev, " HDA Codec ID: 0x%08x\n",
-		    hdac_codec_id(codec));
-		device_printf(sc->dev, "       Vendor: 0x%04x\n",
-		    codec->vendor_id);
-		device_printf(sc->dev, "       Device: 0x%04x\n",
-		    codec->device_id);
-		device_printf(sc->dev, "     Revision: 0x%02x\n",
-		    codec->revision_id);
-		device_printf(sc->dev, "     Stepping: 0x%02x\n",
-		    codec->stepping_id);
-		device_printf(sc->dev, "PCI Subvendor: 0x%08x\n",
-		    sc->pci_subvendor);
-	);
-	subnode = hdac_command(sc,
-	    HDA_CMD_GET_PARAMETER(cad, 0x0, HDA_PARAM_SUB_NODE_COUNT),
-	    cad);
-	startnode = HDA_PARAM_SUB_NODE_COUNT_START(subnode);
-	endnode = startnode + HDA_PARAM_SUB_NODE_COUNT_TOTAL(subnode);
-
-	HDA_BOOTHVERBOSE(
-		device_printf(sc->dev, "\tstartnode=%d endnode=%d\n",
-		    startnode, endnode);
-	);
-	
-	codec->fgs = (struct hdac_devinfo *)malloc(sizeof(struct hdac_devinfo) *
-	    (endnode - startnode), M_HDAC, M_NOWAIT | M_ZERO);
-	if (codec->fgs == NULL) {
-		device_printf(sc->dev, "%s: Unable to allocate function groups\n",
-		    __func__);
-		return;
-	}
-
-	for (i = startnode; i < endnode; i++)
-		hdac_probe_function(codec, i);
-	return;
-}
-
-/*
- * Probe codec function and add it to the list.
- */
-static void
-hdac_probe_function(struct hdac_codec *codec, nid_t nid)
-{
-	struct hdac_softc *sc = codec->sc;
-	struct hdac_devinfo *devinfo = &codec->fgs[codec->num_fgs];
-	uint32_t fctgrptype;
-	uint32_t res;
-	nid_t cad = codec->cad;
-
-	fctgrptype = HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE(hdac_command(sc,
-	    HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_FCT_GRP_TYPE), cad));
-
-	devinfo->nid = nid;
-	devinfo->node_type = fctgrptype;
-	devinfo->codec = codec;
-
-	res = hdac_command(sc,
-	    HDA_CMD_GET_PARAMETER(cad , nid, HDA_PARAM_SUB_NODE_COUNT), cad);
-
-	devinfo->nodecnt = HDA_PARAM_SUB_NODE_COUNT_TOTAL(res);
-	devinfo->startnode = HDA_PARAM_SUB_NODE_COUNT_START(res);
-	devinfo->endnode = devinfo->startnode + devinfo->nodecnt;
-
-	HDA_BOOTVERBOSE(
-		device_printf(sc->dev,
-		    "\tFound %s FG nid=%d startnode=%d endnode=%d total=%d\n",
-		    (fctgrptype == HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO) ? "audio":
-		    (fctgrptype == HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_MODEM) ? "modem":
-		    "unknown", nid, devinfo->startnode, devinfo->endnode,
-		    devinfo->nodecnt);
-	);
-
-	if (devinfo->nodecnt > 0)
-		devinfo->widget = (struct hdac_widget *)malloc(
-		    sizeof(*(devinfo->widget)) * devinfo->nodecnt, M_HDAC,
-		    M_NOWAIT | M_ZERO);
-	else
-		devinfo->widget = NULL;
-
-	if (devinfo->widget == NULL) {
-		device_printf(sc->dev, "unable to allocate widgets!\n");
-		devinfo->endnode = devinfo->startnode;
-		devinfo->nodecnt = 0;
-		return;
-	}
-
-	codec->num_fgs++;
-}
-
-static void
-hdac_widget_connection_parse(struct hdac_widget *w)
-{
-	struct hdac_softc *sc = w->devinfo->codec->sc;
-	uint32_t res;
-	int i, j, max, ents, entnum;
-	nid_t cad = w->devinfo->codec->cad;
-	nid_t nid = w->nid;
-	nid_t cnid, addcnid, prevcnid;
-
-	w->nconns = 0;
-
-	res = hdac_command(sc,
-	    HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_CONN_LIST_LENGTH), cad);
-
-	ents = HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH(res);
-
-	if (ents < 1)
-		return;
-
-	entnum = HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM(res) ? 2 : 4;
-	max = (sizeof(w->conns) / sizeof(w->conns[0])) - 1;
-	prevcnid = 0;
-
-#define CONN_RMASK(e)		(1 << ((32 / (e)) - 1))
-#define CONN_NMASK(e)		(CONN_RMASK(e) - 1)
-#define CONN_RESVAL(r, e, n)	((r) >> ((32 / (e)) * (n)))
-#define CONN_RANGE(r, e, n)	(CONN_RESVAL(r, e, n) & CONN_RMASK(e))
-#define CONN_CNID(r, e, n)	(CONN_RESVAL(r, e, n) & CONN_NMASK(e))
-
-	for (i = 0; i < ents; i += entnum) {
-		res = hdac_command(sc,
-		    HDA_CMD_GET_CONN_LIST_ENTRY(cad, nid, i), cad);
-		for (j = 0; j < entnum; j++) {
-			cnid = CONN_CNID(res, entnum, j);
-			if (cnid == 0) {
-				if (w->nconns < ents)
-					device_printf(sc->dev,
-					    "%s: nid=%d WARNING: zero cnid "
-					    "entnum=%d j=%d index=%d "
-					    "entries=%d found=%d res=0x%08x\n",
-					    __func__, nid, entnum, j, i,
-					    ents, w->nconns, res);
-				else
-					goto getconns_out;
-			}
-			if (cnid < w->devinfo->startnode ||
-			    cnid >= w->devinfo->endnode) {
-				HDA_BOOTVERBOSE(
-					device_printf(sc->dev,
-					    "GHOST: nid=%d j=%d "
-					    "entnum=%d index=%d res=0x%08x\n",
-					    nid, j, entnum, i, res);
-				);
-			}
-			if (CONN_RANGE(res, entnum, j) == 0)
-				addcnid = cnid;
-			else if (prevcnid == 0 || prevcnid >= cnid) {
-				device_printf(sc->dev,
-				    "%s: WARNING: Invalid child range "
-				    "nid=%d index=%d j=%d entnum=%d "
-				    "prevcnid=%d cnid=%d res=0x%08x\n",
-				    __func__, nid, i, j, entnum, prevcnid,
-				    cnid, res);
-				addcnid = cnid;
-			} else
-				addcnid = prevcnid + 1;
-			while (addcnid <= cnid) {
-				if (w->nconns > max) {
-					device_printf(sc->dev,
-					    "Adding %d (nid=%d): "
-					    "Max connection reached! max=%d\n",
-					    addcnid, nid, max + 1);
-					goto getconns_out;
-				}
-				w->connsenable[w->nconns] = 1;
-				w->conns[w->nconns++] = addcnid++;
-			}
-			prevcnid = cnid;
-		}
-	}
-
-getconns_out:
-	return;
-}
-
-static uint32_t
-hdac_widget_pin_patch(uint32_t config, const char *str)
-{
-	char buf[256];
-	char *key, *value, *rest, *bad;
-	int ival, i;
-
-	strlcpy(buf, str, sizeof(buf));
-	rest = buf;
-	while ((key = strsep(&rest, "=")) != NULL) {
-		value = strsep(&rest, " \t");
-		if (value == NULL)
-			break;
-		ival = strtol(value, &bad, 10);
-		if (strcmp(key, "seq") == 0) {
-			config &= ~HDA_CONFIG_DEFAULTCONF_SEQUENCE_MASK;
-			config |= ((ival << HDA_CONFIG_DEFAULTCONF_SEQUENCE_SHIFT) &
-			    HDA_CONFIG_DEFAULTCONF_SEQUENCE_MASK);
-		} else if (strcmp(key, "as") == 0) {
-			config &= ~HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK;
-			config |= ((ival << HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT) &
-			    HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK);
-		} else if (strcmp(key, "misc") == 0) {
-			config &= ~HDA_CONFIG_DEFAULTCONF_MISC_MASK;
-			config |= ((ival << HDA_CONFIG_DEFAULTCONF_MISC_SHIFT) &
-			    HDA_CONFIG_DEFAULTCONF_MISC_MASK);
-		} else if (strcmp(key, "color") == 0) {
-			config &= ~HDA_CONFIG_DEFAULTCONF_COLOR_MASK;
-			if (bad[0] == 0) {
-				config |= ((ival << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT) &
-				    HDA_CONFIG_DEFAULTCONF_COLOR_MASK);
-			};
-			for (i = 0; i < 16; i++) {
-				if (strcasecmp(HDA_COLORS[i], value) == 0) {
-					config |= (i << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT);
-					break;
-				}
-			}
-		} else if (strcmp(key, "ctype") == 0) {
-			config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_MASK;
-			config |= ((ival << HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_SHIFT) &
-			    HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_MASK);
-		} else if (strcmp(key, "device") == 0) {
-			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
-			if (bad[0] == 0) {
-				config |= ((ival << HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT) &
-				    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK);
-				continue;
-			};
-			for (i = 0; i < 16; i++) {
-				if (strcasecmp(HDA_DEVS[i], value) == 0) {
-					config |= (i << HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT);
-					break;
-				}
-			}
-		} else if (strcmp(key, "loc") == 0) {
-			config &= ~HDA_CONFIG_DEFAULTCONF_LOCATION_MASK;
-			config |= ((ival << HDA_CONFIG_DEFAULTCONF_LOCATION_SHIFT) &
-			    HDA_CONFIG_DEFAULTCONF_LOCATION_MASK);
-		} else if (strcmp(key, "conn") == 0) {
-			config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
-			if (bad[0] == 0) {
-				config |= ((ival << HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT) &
-				    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
-				continue;
-			};
-			for (i = 0; i < 4; i++) {
-				if (strcasecmp(HDA_CONNS[i], value) == 0) {
-					config |= (i << HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT);
-					break;
-				}
-			}
-		}
-	}
-	return (config);
-}
-
-static uint32_t
-hdac_widget_pin_getconfig(struct hdac_widget *w)
-{
-	struct hdac_softc *sc;
-	uint32_t config, orig, id;
-	nid_t cad, nid;
-	char buf[32];
-	const char *res = NULL, *patch = NULL;
-
-	sc = w->devinfo->codec->sc;
-	cad = w->devinfo->codec->cad;
-	nid = w->nid;
-	id = hdac_codec_id(w->devinfo->codec);
-
-	config = hdac_command(sc,
-	    HDA_CMD_GET_CONFIGURATION_DEFAULT(cad, nid),
-	    cad);
-	orig = config;
-
-	HDA_BOOTVERBOSE(
-		hdac_dump_pin_config(w, orig);
-	);
-
-	/* XXX: Old patches require complete review.
-	 * Now they may create more problem then solve due to
-	 * incorrect associations.
-	 */
-	if (id == HDA_CODEC_ALC880 && sc->pci_subvendor == LG_LW20_SUBVENDOR) {
-		switch (nid) {
-		case 26:
-			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
-			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
-			break;
-		case 27:
-			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
-			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT;
-			break;
-		default:
-			break;
-		}
-	} else if (id == HDA_CODEC_ALC880 &&
-	    (sc->pci_subvendor == CLEVO_D900T_SUBVENDOR ||
-	    sc->pci_subvendor == ASUS_M5200_SUBVENDOR)) {
-		/*
-		 * Super broken BIOS
-		 */
-		switch (nid) {
-		case 24:	/* MIC1 */
-			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
-			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
-			break;
-		case 25:	/* XXX MIC2 */
-			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
-			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
-			break;
-		case 26:	/* LINE1 */
-			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
-			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
-			break;
-		case 27:	/* XXX LINE2 */
-			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
-			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
-			break;
-		case 28:	/* CD */
-			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
-			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_CD;
-			break;
-		}
-	} else if (id == HDA_CODEC_ALC883 &&
-	    (sc->pci_subvendor == MSI_MS034A_SUBVENDOR ||
-	    HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, sc->pci_subvendor))) {
-		switch (nid) {
-		case 25:
-			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
-			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
-			break;
-		case 28:
-			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
-			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
-			break;
-		}
-	} else if (id == HDA_CODEC_CX20549 && sc->pci_subvendor ==
-	    HP_V3000_SUBVENDOR) {
-		switch (nid) {
-		case 18:
-			config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
-			config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
-			break;
-		case 20:
-			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
-			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
-			break;
-		case 21:
-			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
-			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
-			break;
-		}
-	} else if (id == HDA_CODEC_CX20551 && sc->pci_subvendor ==
-	    HP_DV5000_SUBVENDOR) {
-		switch (nid) {
-		case 20:
-		case 21:
-			config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
-			config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
-			break;
-		}
-	} else if (id == HDA_CODEC_ALC861 && sc->pci_subvendor ==
-	    ASUS_W6F_SUBVENDOR) {
-		switch (nid) {
-		case 11:
-			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
-			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
-			break;
-		case 12:
-		case 14:
-		case 16:
-		case 31:
-		case 32:
-			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
-			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
-			break;
-		case 15:
-			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
-			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK);
-			break;
-		}
-	} else if (id == HDA_CODEC_ALC861 && sc->pci_subvendor ==
-	    UNIWILL_9075_SUBVENDOR) {
-		switch (nid) {
-		case 15:
-			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
-			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT |
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK);
-			break;
-		}
-	}
-
-	/* New patches */
-	if (id == HDA_CODEC_AD1986A &&
-	    (sc->pci_subvendor == ASUS_M2NPVMX_SUBVENDOR ||
-	    sc->pci_subvendor == ASUS_A8NVMCSM_SUBVENDOR ||
-	    sc->pci_subvendor == ASUS_P5PL2_SUBVENDOR)) {
-		switch (nid) {
-		case 26: /* Headphones with redirection */
-			patch = "as=1 seq=15";
-			break;
-		case 28: /* 5.1 out => 2.0 out + 1 input */
-			patch = "device=Line-in as=8 seq=1";
-			break;
-		case 29: /* Can't use this as input, as the only available mic
-			  * preamplifier is busy by front panel mic (nid 31).
-			  * If you want to use this rear connector as mic input,
-			  * you have to disable the front panel one. */
-			patch = "as=0";
-			break;
-		case 31: /* Lot of inputs configured with as=15 and unusable */
-			patch = "as=8 seq=3";
-			break;
-		case 32:
-			patch = "as=8 seq=4";
-			break;
-		case 34:
-			patch = "as=8 seq=5";
-			break;
-		case 36:
-			patch = "as=8 seq=6";
-			break;
-		}
-	} else if (id == HDA_CODEC_ALC260 &&
-	    HDA_DEV_MATCH(SONY_S5_SUBVENDOR, sc->pci_subvendor)) {
-		switch (nid) {
-		case 16:
-			patch = "seq=15 device=Headphones";
-			break;
-		}
-	} else if (id == HDA_CODEC_ALC268) {
-	    if (sc->pci_subvendor == ACER_T5320_SUBVENDOR) {
-		switch (nid) {
-		case 20: /* Headphones Jack */
-			patch = "as=1 seq=15";
-			break;
-		}
-	    }
-	} else if (id == HDA_CODEC_CX20561 &&
-	    sc->pci_subvendor == LENOVO_B450_SUBVENDOR) {
-		switch (nid) {
-		case 22:
-			patch = "as=1 seq=15";
-			break;
-		}
-	}
-
-	if (patch != NULL)
-		config = hdac_widget_pin_patch(config, patch);
-	
-	snprintf(buf, sizeof(buf), "cad%u.nid%u.config", cad, nid);
-	if (resource_string_value(device_get_name(sc->dev),
-	    device_get_unit(sc->dev), buf, &res) == 0) {
-		if (strncmp(res, "0x", 2) == 0) {
-			config = strtol(res + 2, NULL, 16);
-		} else {
-			config = hdac_widget_pin_patch(config, res);
-		}
-	}
-
-	HDA_BOOTVERBOSE(
-		if (config != orig)
-			device_printf(sc->dev,
-			    "Patching pin config nid=%u 0x%08x -> 0x%08x\n",
-			    nid, orig, config);
-	);
-
-	return (config);
-}
-
-static uint32_t
-hdac_widget_pin_getcaps(struct hdac_widget *w)
-{
-	struct hdac_softc *sc;
-	uint32_t caps, orig, id;
-	nid_t cad, nid;
-
-	sc = w->devinfo->codec->sc;
-	cad = w->devinfo->codec->cad;
-	nid = w->nid;
-	id = hdac_codec_id(w->devinfo->codec);
-
-	caps = hdac_command(sc,
-	    HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_PIN_CAP), cad);
-	orig = caps;
-
-	HDA_BOOTVERBOSE(
-		if (caps != orig)
-			device_printf(sc->dev,
-			    "Patching pin caps nid=%u 0x%08x -> 0x%08x\n",
-			    nid, orig, caps);
-	);
-
-	return (caps);
-}
-
-static void
-hdac_widget_pin_parse(struct hdac_widget *w)
-{
-	struct hdac_softc *sc = w->devinfo->codec->sc;
-	uint32_t config, pincap;
-	const char *devstr;
-	nid_t cad = w->devinfo->codec->cad;
-	nid_t nid = w->nid;
-	int conn, color;
-
-	config = hdac_widget_pin_getconfig(w);
-	w->wclass.pin.config = config;
-
-	pincap = hdac_widget_pin_getcaps(w);
-	w->wclass.pin.cap = pincap;
-
-	w->wclass.pin.ctrl = hdac_command(sc,
-	    HDA_CMD_GET_PIN_WIDGET_CTRL(cad, nid), cad);
-
-	if (HDA_PARAM_PIN_CAP_EAPD_CAP(pincap)) {
-		w->param.eapdbtl = hdac_command(sc,
-		    HDA_CMD_GET_EAPD_BTL_ENABLE(cad, nid), cad);
-		w->param.eapdbtl &= 0x7;
-		w->param.eapdbtl |= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
-	} else
-		w->param.eapdbtl = HDAC_INVALID;
-
-	devstr = HDA_DEVS[(config & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) >>
-	    HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT];
-
-	conn = (config & HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) >>
-	    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT;
-	color = (config & HDA_CONFIG_DEFAULTCONF_COLOR_MASK) >>
-	    HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT;
-
-	strlcat(w->name, ": ", sizeof(w->name));
-	strlcat(w->name, devstr, sizeof(w->name));
-	strlcat(w->name, " (", sizeof(w->name));
-	if (conn == 0 && color != 0 && color != 15) {
-		strlcat(w->name, HDA_COLORS[color], sizeof(w->name));
-		strlcat(w->name, " ", sizeof(w->name));
-	}
-	strlcat(w->name, HDA_CONNS[conn], sizeof(w->name));
-	strlcat(w->name, ")", sizeof(w->name));
-}
-
-static uint32_t
-hdac_widget_getcaps(struct hdac_widget *w, int *waspin)
-{
-	struct hdac_softc *sc;
-	uint32_t caps, orig, id;
-	nid_t cad, nid, beeper = -1;
-
-	sc = w->devinfo->codec->sc;
-	cad = w->devinfo->codec->cad;
-	nid = w->nid;
-	id = hdac_codec_id(w->devinfo->codec);
-
-	caps = hdac_command(sc,
-	    HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_AUDIO_WIDGET_CAP),
-	    cad);
-	orig = caps;
-
-	/* On some codecs beeper is an input pin, but it is not recordable
-	   alone. Also most of BIOSes does not declare beeper pin.
-	   Change beeper pin node type to beeper to help parser. */
-	*waspin = 0;
-	switch (id) {
-	case HDA_CODEC_AD1882:
-	case HDA_CODEC_AD1883:
-	case HDA_CODEC_AD1984:
-	case HDA_CODEC_AD1984A:
-	case HDA_CODEC_AD1984B:
-	case HDA_CODEC_AD1987:
-	case HDA_CODEC_AD1988:
-	case HDA_CODEC_AD1988B:
-	case HDA_CODEC_AD1989B:
-		beeper = 26;
-		break;
-	case HDA_CODEC_ALC260:
-		beeper = 23;
-		break;
-	case HDA_CODEC_ALC262:
-	case HDA_CODEC_ALC268:
-	case HDA_CODEC_ALC880:
-	case HDA_CODEC_ALC882:
-	case HDA_CODEC_ALC883:
-	case HDA_CODEC_ALC885:
-	case HDA_CODEC_ALC888:
-	case HDA_CODEC_ALC889:
-		beeper = 29;
-		break;
-	}
-	if (nid == beeper) {
-		caps &= ~HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK;
-		caps |= HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET <<
-		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT;
-		*waspin = 1;
-	}
-
-	HDA_BOOTVERBOSE(
-		if (caps != orig) {
-			device_printf(sc->dev,
-			    "Patching widget caps nid=%u 0x%08x -> 0x%08x\n",
-			    nid, orig, caps);
-		}
-	);
-
-	return (caps);
-}
-
-static void
-hdac_widget_parse(struct hdac_widget *w)
-{
-	struct hdac_softc *sc = w->devinfo->codec->sc;
-	uint32_t wcap, cap;
-	char *typestr;
-	nid_t cad = w->devinfo->codec->cad;
-	nid_t nid = w->nid;
-
-	wcap = hdac_widget_getcaps(w, &w->waspin);
-
-	w->param.widget_cap = wcap;
-	w->type = HDA_PARAM_AUDIO_WIDGET_CAP_TYPE(wcap);
-
-	switch (w->type) {
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT:
-		typestr = "audio output";
-		break;
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT:
-		typestr = "audio input";
-		break;
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER:
-		typestr = "audio mixer";
-		break;
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR:
-		typestr = "audio selector";
-		break;
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
-		typestr = "pin";
-		break;
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_POWER_WIDGET:
-		typestr = "power widget";
-		break;
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VOLUME_WIDGET:
-		typestr = "volume widget";
-		break;
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET:
-		typestr = "beep widget";
-		break;
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VENDOR_WIDGET:
-		typestr = "vendor widget";
-		break;
-	default:
-		typestr = "unknown type";
-		break;
-	}
-
-	strlcpy(w->name, typestr, sizeof(w->name));
-
-	hdac_widget_connection_parse(w);
-
-	if (HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP(wcap)) {
-		if (HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR(wcap))
-			w->param.outamp_cap =
-			    hdac_command(sc,
-			    HDA_CMD_GET_PARAMETER(cad, nid,
-			    HDA_PARAM_OUTPUT_AMP_CAP), cad);
-		else
-			w->param.outamp_cap =
-			    w->devinfo->function.audio.outamp_cap;
-	} else
-		w->param.outamp_cap = 0;
-
-	if (HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP(wcap)) {
-		if (HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR(wcap))
-			w->param.inamp_cap =
-			    hdac_command(sc,
-			    HDA_CMD_GET_PARAMETER(cad, nid,
-			    HDA_PARAM_INPUT_AMP_CAP), cad);
-		else
-			w->param.inamp_cap =
-			    w->devinfo->function.audio.inamp_cap;
-	} else
-		w->param.inamp_cap = 0;
-
-	if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT ||
-	    w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) {
-		if (HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR(wcap)) {
-			cap = hdac_command(sc,
-			    HDA_CMD_GET_PARAMETER(cad, nid,
-			    HDA_PARAM_SUPP_STREAM_FORMATS), cad);
-			w->param.supp_stream_formats = (cap != 0) ? cap :
-			    w->devinfo->function.audio.supp_stream_formats;
-			cap = hdac_command(sc,
-			    HDA_CMD_GET_PARAMETER(cad, nid,
-			    HDA_PARAM_SUPP_PCM_SIZE_RATE), cad);
-			w->param.supp_pcm_size_rate = (cap != 0) ? cap :
-			    w->devinfo->function.audio.supp_pcm_size_rate;
-		} else {
-			w->param.supp_stream_formats =
-			    w->devinfo->function.audio.supp_stream_formats;
-			w->param.supp_pcm_size_rate =
-			    w->devinfo->function.audio.supp_pcm_size_rate;
-		}
-	} else {
-		w->param.supp_stream_formats = 0;
-		w->param.supp_pcm_size_rate = 0;
-	}
-
-	if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-		hdac_widget_pin_parse(w);
-}
-
-static struct hdac_widget *
-hdac_widget_get(struct hdac_devinfo *devinfo, nid_t nid)
-{
-	if (devinfo == NULL || devinfo->widget == NULL ||
-		    nid < devinfo->startnode || nid >= devinfo->endnode)
-		return (NULL);
-	return (&devinfo->widget[nid - devinfo->startnode]);
-}
-
-static __inline int
-hda_poll_channel(struct hdac_chan *ch)
-{
-	uint32_t sz, delta;
-	volatile uint32_t ptr;
-
-	if (!(ch->flags & HDAC_CHN_RUNNING))
-		return (0);
-
-	sz = ch->blksz * ch->blkcnt;
-	if (ch->dmapos != NULL)
-		ptr = *(ch->dmapos);
-	else
-		ptr = HDAC_READ_4(&ch->devinfo->codec->sc->mem,
-		    ch->off + HDAC_SDLPIB);
-	ch->ptr = ptr;
-	ptr %= sz;
-	ptr &= ~(ch->blksz - 1);
-	delta = (sz + ptr - ch->prevptr) % sz;
-
-	if (delta < ch->blksz)
-		return (0);
-
-	ch->prevptr = ptr;
-
-	return (1);
-}
-
-static void
-hda_poll_callback(void *arg)
-{
-	struct hdac_softc *sc = arg;
-	uint32_t trigger;
-	int i, active = 0;
-
-	if (sc == NULL)
-		return;
-
-	hdac_lock(sc);
-	if (sc->polling == 0) {
-		hdac_unlock(sc);
-		return;
-	}
-
-	trigger = 0;
-	for (i = 0; i < sc->num_chans; i++) {
-		if ((sc->chans[i].flags & HDAC_CHN_RUNNING) == 0)
-		    continue;
-		active = 1;
-		if (hda_poll_channel(&sc->chans[i]))
-		    trigger |= (1 << i);
-	}
-
-	/* XXX */
-	if (active)
-		callout_reset(&sc->poll_hda, sc->poll_ticks,
-		    hda_poll_callback, sc);
-
-	hdac_unlock(sc);
-
-	for (i = 0; i < sc->num_chans; i++) {
-		if (trigger & (1 << i))
-			chn_intr(sc->chans[i].c);
-	}
-}
-
 static int
 hdac_rirb_flush(struct hdac_softc *sc)
 {
 	struct hdac_rirb *rirb_base, *rirb;
-	struct hdac_codec *codec;
-	struct hdac_command_list *commands;
 	nid_t cad;
 	uint32_t resp;
 	uint8_t rirbwp;
@@ -2949,46 +883,46 @@
 #endif
 
 	ret = 0;
-
 	while (sc->rirb_rp != rirbwp) {
 		sc->rirb_rp++;
 		sc->rirb_rp %= sc->rirb_size;
 		rirb = &rirb_base[sc->rirb_rp];
 		cad = HDAC_RIRB_RESPONSE_EX_SDATA_IN(rirb->response_ex);
-		if (cad < 0 || cad >= HDAC_CODEC_MAX ||
-		    sc->codecs[cad] == NULL)
-			continue;
 		resp = rirb->response;
-		codec = sc->codecs[cad];
-		commands = codec->commands;
 		if (rirb->response_ex & HDAC_RIRB_RESPONSE_EX_UNSOLICITED) {
-			sc->unsolq[sc->unsolq_wp++] = (cad << 16) |
-			    ((resp >> 26) & 0xffff);
+			sc->unsolq[sc->unsolq_wp++] = resp;
 			sc->unsolq_wp %= HDAC_UNSOLQ_MAX;
-		} else if (commands != NULL && commands->num_commands > 0 &&
-		    codec->responses_received < commands->num_commands)
-			commands->responses[codec->responses_received++] =
-			    resp;
+			sc->unsolq[sc->unsolq_wp++] = cad;
+			sc->unsolq_wp %= HDAC_UNSOLQ_MAX;
+		} else if (sc->codecs[cad].pending <= 0) {
+			device_printf(sc->dev, "Unexpected unsolicited "
+			    "response from address %d: %08x\n", cad, resp);
+		} else {
+			sc->codecs[cad].response = resp;
+			sc->codecs[cad].pending--;
+		}
 		ret++;
 	}
-
 	return (ret);
 }
 
 static int
 hdac_unsolq_flush(struct hdac_softc *sc)
 {
+	device_t child;
 	nid_t cad;
-	uint32_t tag;
+	uint32_t resp;
 	int ret = 0;
 
 	if (sc->unsolq_st == HDAC_UNSOLQ_READY) {
 		sc->unsolq_st = HDAC_UNSOLQ_BUSY;
 		while (sc->unsolq_rp != sc->unsolq_wp) {
-			cad = sc->unsolq[sc->unsolq_rp] >> 16;
-			tag = sc->unsolq[sc->unsolq_rp++] & 0xffff;
+			resp = sc->unsolq[sc->unsolq_rp++];
 			sc->unsolq_rp %= HDAC_UNSOLQ_MAX;
-			hdac_unsolicited_handler(sc->codecs[cad], tag);
+			cad = sc->unsolq[sc->unsolq_rp++];
+			sc->unsolq_rp %= HDAC_UNSOLQ_MAX;
+			if ((child = sc->codecs[cad].dev) != NULL)
+				HDAC_UNSOL_INTR(child, resp);
 			ret++;
 		}
 		sc->unsolq_st = HDAC_UNSOLQ_READY;
@@ -2997,376 +931,55 @@
 	return (ret);
 }
 
-static void
-hdac_poll_callback(void *arg)
-{
-	struct hdac_softc *sc = arg;
-	if (sc == NULL)
-		return;
-
-	hdac_lock(sc);
-	if (sc->polling == 0 || sc->poll_ival == 0) {
-		hdac_unlock(sc);
-		return;
-	}
-	if (hdac_rirb_flush(sc) != 0)
-		hdac_unsolq_flush(sc);
-	callout_reset(&sc->poll_hdac, sc->poll_ival, hdac_poll_callback, sc);
-	hdac_unlock(sc);
-}
-
-static void
-hdac_poll_reinit(struct hdac_softc *sc)
-{
-	int i, pollticks, min = 1000000;
-	struct hdac_chan *ch;
-
-	for (i = 0; i < sc->num_chans; i++) {
-		if ((sc->chans[i].flags & HDAC_CHN_RUNNING) == 0)
-			continue;
-		ch = &sc->chans[i];
-		pollticks = ((uint64_t)hz * ch->blksz) /
-		    ((uint64_t)sndbuf_getalign(ch->b) * sndbuf_getspd(ch->b));
-		pollticks >>= 1;
-		if (pollticks > hz)
-			pollticks = hz;
-		if (pollticks < 1) {
-			HDA_BOOTVERBOSE(
-				device_printf(sc->dev,
-				    "%s: pollticks=%d < 1 !\n",
-				    __func__, pollticks);
-			);
-			pollticks = 1;
-		}
-		if (min > pollticks)
-			min = pollticks;
-	}
-	HDA_BOOTVERBOSE(
-		device_printf(sc->dev,
-		    "%s: pollticks %d -> %d\n",
-		    __func__, sc->poll_ticks, min);
-	);
-	sc->poll_ticks = min;
-	if (min == 1000000)
-		callout_stop(&sc->poll_hda);
-	else
-		callout_reset(&sc->poll_hda, 1, hda_poll_callback, sc);
-}
-
-static void
-hdac_stream_stop(struct hdac_chan *ch)
-{
-	struct hdac_softc *sc = ch->devinfo->codec->sc;
-	uint32_t ctl;
-
-	ctl = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDCTL0);
-	ctl &= ~(HDAC_SDCTL_IOCE | HDAC_SDCTL_FEIE | HDAC_SDCTL_DEIE |
-	    HDAC_SDCTL_RUN);
-	HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDCTL0, ctl);
-
-	ch->flags &= ~HDAC_CHN_RUNNING;
-
-	if (sc->polling != 0)
-		hdac_poll_reinit(sc);
-
-	ctl = HDAC_READ_4(&sc->mem, HDAC_INTCTL);
-	ctl &= ~(1 << (ch->off >> 5));
-	HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, ctl);
-}
-
-static void
-hdac_stream_start(struct hdac_chan *ch)
-{
-	struct hdac_softc *sc = ch->devinfo->codec->sc;
-	uint32_t ctl;
-
-	ch->flags |= HDAC_CHN_RUNNING;
-
-	if (sc->polling != 0)
-		hdac_poll_reinit(sc);
-
-	ctl = HDAC_READ_4(&sc->mem, HDAC_INTCTL);
-	ctl |= 1 << (ch->off >> 5);
-	HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, ctl);
-
-	ctl = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDCTL0);
-	ctl |= HDAC_SDCTL_IOCE | HDAC_SDCTL_FEIE | HDAC_SDCTL_DEIE |
-	    HDAC_SDCTL_RUN;
-	HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDCTL0, ctl);
-}
-
-static void
-hdac_stream_reset(struct hdac_chan *ch)
-{
-	struct hdac_softc *sc = ch->devinfo->codec->sc;
-	int timeout = 1000;
-	int to = timeout;
-	uint32_t ctl;
-
-	ctl = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDCTL0);
-	ctl |= HDAC_SDCTL_SRST;
-	HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDCTL0, ctl);
-	do {
-		ctl = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDCTL0);
-		if (ctl & HDAC_SDCTL_SRST)
-			break;
-		DELAY(10);
-	} while (--to);
-	if (!(ctl & HDAC_SDCTL_SRST)) {
-		device_printf(sc->dev, "timeout in reset\n");
-	}
-	ctl &= ~HDAC_SDCTL_SRST;
-	HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDCTL0, ctl);
-	to = timeout;
-	do {
-		ctl = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDCTL0);
-		if (!(ctl & HDAC_SDCTL_SRST))
-			break;
-		DELAY(10);
-	} while (--to);
-	if (ctl & HDAC_SDCTL_SRST)
-		device_printf(sc->dev, "can't reset!\n");
-}
-
-static void
-hdac_stream_setid(struct hdac_chan *ch)
-{
-	struct hdac_softc *sc = ch->devinfo->codec->sc;
-	uint32_t ctl;
-
-	ctl = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDCTL2);
-	ctl &= ~HDAC_SDCTL2_STRM_MASK;
-	ctl |= ch->sid << HDAC_SDCTL2_STRM_SHIFT;
-	HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDCTL2, ctl);
-}
-
-static void
-hdac_bdl_setup(struct hdac_chan *ch)
-{
-	struct hdac_softc *sc = ch->devinfo->codec->sc;
-	struct hdac_bdle *bdle;
-	uint64_t addr;
-	uint32_t blksz, blkcnt;
-	int i;
-
-	addr = (uint64_t)sndbuf_getbufaddr(ch->b);
-	bdle = (struct hdac_bdle *)ch->bdl_dma.dma_vaddr;
-
-	blksz = ch->blksz;
-	blkcnt = ch->blkcnt;
-
-	for (i = 0; i < blkcnt; i++, bdle++) {
-		bdle->addrl = (uint32_t)addr;
-		bdle->addrh = (uint32_t)(addr >> 32);
-		bdle->len = blksz;
-		bdle->ioc = 1;
-		addr += blksz;
-	}
-
-	HDAC_WRITE_4(&sc->mem, ch->off + HDAC_SDCBL, blksz * blkcnt);
-	HDAC_WRITE_2(&sc->mem, ch->off + HDAC_SDLVI, blkcnt - 1);
-	addr = ch->bdl_dma.dma_paddr;
-	HDAC_WRITE_4(&sc->mem, ch->off + HDAC_SDBDPL, (uint32_t)addr);
-	HDAC_WRITE_4(&sc->mem, ch->off + HDAC_SDBDPU, (uint32_t)(addr >> 32));
-	if (ch->dmapos != NULL &&
-	    !(HDAC_READ_4(&sc->mem, HDAC_DPIBLBASE) & 0x00000001)) {
-		addr = sc->pos_dma.dma_paddr;
-		HDAC_WRITE_4(&sc->mem, HDAC_DPIBLBASE,
-		    ((uint32_t)addr & HDAC_DPLBASE_DPLBASE_MASK) | 0x00000001);
-		HDAC_WRITE_4(&sc->mem, HDAC_DPIBUBASE, (uint32_t)(addr >> 32));
-	}
-}
-
-static int
-hdac_bdl_alloc(struct hdac_chan *ch)
-{
-	struct hdac_softc *sc = ch->devinfo->codec->sc;
-	int rc;
-
-	rc = hdac_dma_alloc(sc, &ch->bdl_dma,
-	    sizeof(struct hdac_bdle) * HDA_BDL_MAX);
-	if (rc) {
-		device_printf(sc->dev, "can't alloc bdl\n");
-		return (rc);
-	}
-
-	return (0);
-}
-
-static void
-hdac_audio_ctl_amp_set_internal(struct hdac_softc *sc, nid_t cad, nid_t nid,
-					int index, int lmute, int rmute,
-					int left, int right, int dir)
-{
-	uint16_t v = 0;
-
-	if (sc == NULL)
-		return;
-
-	if (left != right || lmute != rmute) {
-		v = (1 << (15 - dir)) | (1 << 13) | (index << 8) |
-		    (lmute << 7) | left;
-		hdac_command(sc,
-		    HDA_CMD_SET_AMP_GAIN_MUTE(cad, nid, v), cad);
-		v = (1 << (15 - dir)) | (1 << 12) | (index << 8) |
-		    (rmute << 7) | right;
-	} else
-		v = (1 << (15 - dir)) | (3 << 12) | (index << 8) |
-		    (lmute << 7) | left;
-
-	hdac_command(sc,
-	    HDA_CMD_SET_AMP_GAIN_MUTE(cad, nid, v), cad);
-}
-
-static void
-hdac_audio_ctl_amp_set(struct hdac_audio_ctl *ctl, uint32_t mute,
-						int left, int right)
-{
-	struct hdac_softc *sc;
-	nid_t nid, cad;
-	int lmute, rmute;
-
-	sc = ctl->widget->devinfo->codec->sc;
-	cad = ctl->widget->devinfo->codec->cad;
-	nid = ctl->widget->nid;
-
-	/* Save new values if valid. */
-	if (mute != HDA_AMP_MUTE_DEFAULT)
-		ctl->muted = mute;
-	if (left != HDA_AMP_VOL_DEFAULT)
-		ctl->left = left;
-	if (right != HDA_AMP_VOL_DEFAULT)
-		ctl->right = right;
-	/* Prepare effective values */
-	if (ctl->forcemute) {
-		lmute = 1;
-		rmute = 1;
-		left = 0;
-		right = 0;
-	} else {
-		lmute = HDA_AMP_LEFT_MUTED(ctl->muted);
-		rmute = HDA_AMP_RIGHT_MUTED(ctl->muted);
-		left = ctl->left;
-		right = ctl->right;
-	}
-	/* Apply effective values */
-	if (ctl->dir & HDA_CTL_OUT)
-		hdac_audio_ctl_amp_set_internal(sc, cad, nid, ctl->index,
-		    lmute, rmute, left, right, 0);
-	if (ctl->dir & HDA_CTL_IN)
-    		hdac_audio_ctl_amp_set_internal(sc, cad, nid, ctl->index,
-		    lmute, rmute, left, right, 1);
-}
-
-static void
-hdac_widget_connection_select(struct hdac_widget *w, uint8_t index)
-{
-	if (w == NULL || w->nconns < 1 || index > (w->nconns - 1))
-		return;
-	hdac_command(w->devinfo->codec->sc,
-	    HDA_CMD_SET_CONNECTION_SELECT_CONTROL(w->devinfo->codec->cad,
-	    w->nid, index), w->devinfo->codec->cad);
-	w->selconn = index;
-}
-
-
 /****************************************************************************
  * uint32_t hdac_command_sendone_internal
  *
  * Wrapper function that sends only one command to a given codec
  ****************************************************************************/
 static uint32_t
-hdac_command_sendone_internal(struct hdac_softc *sc, uint32_t verb, nid_t cad)
+hdac_send_command(struct hdac_softc *sc, nid_t cad, uint32_t verb)
 {
-	struct hdac_command_list cl;
-	uint32_t response = HDAC_INVALID;
+	int timeout;
+	uint32_t *corb;
 
 	if (!hdac_lockowned(sc))
 		device_printf(sc->dev, "WARNING!!!! mtx not owned!!!!\n");
-	cl.num_commands = 1;
-	cl.verbs = &verb;
-	cl.responses = &response;
+	verb &= ~HDA_CMD_CAD_MASK;
+	verb |= ((uint32_t)cad) << HDA_CMD_CAD_SHIFT;
+	sc->codecs[cad].response = HDA_INVALID;
 
-	hdac_command_send_internal(sc, &cl, cad);
+	sc->codecs[cad].pending++;
+	sc->corb_wp++;
+	sc->corb_wp %= sc->corb_size;
+	corb = (uint32_t *)sc->corb_dma.dma_vaddr;
+#if 0
+	bus_dmamap_sync(sc->corb_dma.dma_tag,
+	    sc->corb_dma.dma_map, BUS_DMASYNC_PREWRITE);
+#endif
+	corb[sc->corb_wp] = verb;
+#if 0
+	bus_dmamap_sync(sc->corb_dma.dma_tag,
+	    sc->corb_dma.dma_map, BUS_DMASYNC_POSTWRITE);
+#endif
+	HDAC_WRITE_2(&sc->mem, HDAC_CORBWP, sc->corb_wp);
 
-	return (response);
+	timeout = 10000;
+	do {
+		if (hdac_rirb_flush(sc) == 0)
+			DELAY(10);
+	} while (sc->codecs[cad].pending != 0 && --timeout);
+
+	if (sc->codecs[cad].pending != 0) {
+		device_printf(sc->dev, "Command timeout on address %d\n", cad);
+		sc->codecs[cad].pending = 0;
+	}
+
+	if (sc->unsolq_rp != sc->unsolq_wp)
+		taskqueue_enqueue(taskqueue_thread, &sc->unsolq_task);
+	return (sc->codecs[cad].response);
 }
 
 /****************************************************************************
- * hdac_command_send_internal
- *
- * Send a command list to the codec via the corb. We queue as much verbs as
- * we can and msleep on the codec. When the interrupt get the responses
- * back from the rirb, it will wake us up so we can queue the remaining verbs
- * if any.
- ****************************************************************************/
-static void
-hdac_command_send_internal(struct hdac_softc *sc,
-			struct hdac_command_list *commands, nid_t cad)
-{
-	struct hdac_codec *codec;
-	int corbrp;
-	uint32_t *corb;
-	int timeout;
-	int retry = 10;
-	struct hdac_rirb *rirb_base;
-
-	if (sc == NULL || sc->codecs[cad] == NULL || commands == NULL ||
-	    commands->num_commands < 1)
-		return;
-
-	codec = sc->codecs[cad];
-	codec->commands = commands;
-	codec->responses_received = 0;
-	codec->verbs_sent = 0;
-	corb = (uint32_t *)sc->corb_dma.dma_vaddr;
-	rirb_base = (struct hdac_rirb *)sc->rirb_dma.dma_vaddr;
-
-	do {
-		if (codec->verbs_sent != commands->num_commands) {
-			/* Queue as many verbs as possible */
-			corbrp = HDAC_READ_2(&sc->mem, HDAC_CORBRP);
-#if 0
-			bus_dmamap_sync(sc->corb_dma.dma_tag,
-			    sc->corb_dma.dma_map, BUS_DMASYNC_PREWRITE);
-#endif
-			while (codec->verbs_sent != commands->num_commands &&
-			    ((sc->corb_wp + 1) % sc->corb_size) != corbrp) {
-				sc->corb_wp++;
-				sc->corb_wp %= sc->corb_size;
-				corb[sc->corb_wp] =
-				    commands->verbs[codec->verbs_sent++];
-			}
-
-			/* Send the verbs to the codecs */
-#if 0
-			bus_dmamap_sync(sc->corb_dma.dma_tag,
-			    sc->corb_dma.dma_map, BUS_DMASYNC_POSTWRITE);
-#endif
-			HDAC_WRITE_2(&sc->mem, HDAC_CORBWP, sc->corb_wp);
-		}
-
-		timeout = 1000;
-		while (hdac_rirb_flush(sc) == 0 && --timeout)
-			DELAY(10);
-	} while ((codec->verbs_sent != commands->num_commands ||
-	    codec->responses_received != commands->num_commands) && --retry);
-
-	if (retry == 0)
-		device_printf(sc->dev,
-		    "%s: TIMEOUT numcmd=%d, sent=%d, received=%d\n",
-		    __func__, commands->num_commands, codec->verbs_sent,
-		    codec->responses_received);
-
-	codec->commands = NULL;
-	codec->responses_received = 0;
-	codec->verbs_sent = 0;
-
-	hdac_unsolq_flush(sc);
-}
-
-
-/****************************************************************************
  * Device Methods
  ****************************************************************************/
 
@@ -3411,7 +1024,7 @@
 	    	result = BUS_PROBE_GENERIC;
 	}
 	if (result != ENXIO) {
-		strlcat(desc, " High Definition Audio Controller",
+		strlcat(desc, " HDA Controller",
 		    sizeof(desc));
 		device_set_desc_copy(dev, desc);
 	}
@@ -3419,711 +1032,6 @@
 	return (result);
 }
 
-static void *
-hdac_channel_init(kobj_t obj, void *data, struct snd_dbuf *b,
-					struct pcm_channel *c, int dir)
-{
-	struct hdac_pcm_devinfo *pdevinfo = data;
-	struct hdac_devinfo *devinfo = pdevinfo->devinfo;
-	struct hdac_softc *sc = devinfo->codec->sc;
-	struct hdac_chan *ch;
-	int i, ord = 0, chid;
-
-	hdac_lock(sc);
-
-	chid = (dir == PCMDIR_PLAY)?pdevinfo->play:pdevinfo->rec;
-	ch = &sc->chans[chid];
-	for (i = 0; i < sc->num_chans && i < chid; i++) {
-		if (ch->dir == sc->chans[i].dir)
-			ord++;
-	}
-	if (dir == PCMDIR_PLAY) {
-		ch->off = (sc->num_iss + ord) << 5;
-	} else {
-		ch->off = ord << 5;
-	}
-
-	if (devinfo->function.audio.quirks & HDA_QUIRK_FIXEDRATE) {
-		ch->caps.minspeed = ch->caps.maxspeed = 48000;
-		ch->pcmrates[0] = 48000;
-		ch->pcmrates[1] = 0;
-	}
-	if (sc->pos_dma.dma_vaddr != NULL)
-		ch->dmapos = (uint32_t *)(sc->pos_dma.dma_vaddr +
-		    (sc->streamcnt * 8));
-	else
-		ch->dmapos = NULL;
-	ch->sid = ++sc->streamcnt;
-	ch->dir = dir;
-	ch->b = b;
-	ch->c = c;
-	ch->blksz = pdevinfo->chan_size / pdevinfo->chan_blkcnt;
-	ch->blkcnt = pdevinfo->chan_blkcnt;
-	hdac_unlock(sc);
-
-	if (hdac_bdl_alloc(ch) != 0) {
-		ch->blkcnt = 0;
-		return (NULL);
-	}
-
-	if (sndbuf_alloc(ch->b, sc->chan_dmat,
-	    (sc->flags & HDAC_F_DMA_NOCACHE) ? BUS_DMA_NOCACHE : 0,
-	    pdevinfo->chan_size) != 0)
-		return (NULL);
-
-	return (ch);
-}
-
-static int
-hdac_channel_setformat(kobj_t obj, void *data, uint32_t format)
-{
-	struct hdac_chan *ch = data;
-	int i;
-
-	for (i = 0; ch->caps.fmtlist[i] != 0; i++) {
-		if (format == ch->caps.fmtlist[i]) {
-			ch->fmt = format;
-			return (0);
-		}
-	}
-
-	return (EINVAL);
-}
-
-static uint32_t
-hdac_channel_setspeed(kobj_t obj, void *data, uint32_t speed)
-{
-	struct hdac_chan *ch = data;
-	uint32_t spd = 0, threshold;
-	int i;
-
-	for (i = 0; ch->pcmrates[i] != 0; i++) {
-		spd = ch->pcmrates[i];
-		threshold = spd + ((ch->pcmrates[i + 1] != 0) ?
-		    ((ch->pcmrates[i + 1] - spd) >> 1) : 0);
-		if (speed < threshold)
-			break;
-	}
-
-	if (spd == 0)	/* impossible */
-		ch->spd = 48000;
-	else
-		ch->spd = spd;
-
-	return (ch->spd);
-}
-
-static void
-hdac_stream_setup(struct hdac_chan *ch)
-{
-	struct hdac_softc *sc = ch->devinfo->codec->sc;
-	struct hdac_audio_as *as = &ch->devinfo->function.audio.as[ch->as];
-	struct hdac_widget *w;
-	int i, chn, totalchn, c;
-	nid_t cad = ch->devinfo->codec->cad;
-	uint16_t fmt, dfmt;
-	uint16_t chmap[2][5] = {{ 0x0010, 0x0001, 0x0201, 0x0231, 0x0231 }, /* 5.1 */
-				{ 0x0010, 0x0001, 0x2001, 0x2031, 0x2431 }};/* 7.1 */
-	int map = -1;
-
-	totalchn = AFMT_CHANNEL(ch->fmt);
-	HDA_BOOTHVERBOSE(
-		device_printf(ch->pdevinfo->dev,
-		    "PCMDIR_%s: Stream setup fmt=%08x speed=%d\n",
-		    (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC",
-		    ch->fmt, ch->spd);
-	);
-	fmt = 0;
-	if (ch->fmt & AFMT_S16_LE)
-		fmt |= ch->bit16 << 4;
-	else if (ch->fmt & AFMT_S32_LE)
-		fmt |= ch->bit32 << 4;
-	else
-		fmt |= 1 << 4;
-	for (i = 0; i < HDA_RATE_TAB_LEN; i++) {
-		if (hda_rate_tab[i].valid && ch->spd == hda_rate_tab[i].rate) {
-			fmt |= hda_rate_tab[i].base;
-			fmt |= hda_rate_tab[i].mul;
-			fmt |= hda_rate_tab[i].div;
-			break;
-		}
-	}
-	fmt |= (totalchn - 1);
-
-	/* Set channel mapping for known speaker setups. */
-	if (as->pinset == 0x0007 || as->pinset == 0x0013) /* Standard 5.1 */
-		map = 0;
-	else if (as->pinset == 0x0017) /* Standard 7.1 */
-		map = 1;
-
-	HDAC_WRITE_2(&sc->mem, ch->off + HDAC_SDFMT, fmt);
-		
-	dfmt = HDA_CMD_SET_DIGITAL_CONV_FMT1_DIGEN;
-	if (ch->fmt & AFMT_AC3)
-		dfmt |= HDA_CMD_SET_DIGITAL_CONV_FMT1_NAUDIO;
-
-	chn = 0;
-	for (i = 0; ch->io[i] != -1; i++) {
-		w = hdac_widget_get(ch->devinfo, ch->io[i]);
-		if (w == NULL)
-			continue;
-
-		/* If HP redirection is enabled, but failed to use same
-		   DAC, make last DAC to duplicate first one. */
-		if (as->fakeredir && i == (as->pincnt - 1)) {
-			c = (ch->sid << 4);
-		} else {
-			if (map >= 0) /* Map known speaker setups. */
-				chn = (((chmap[map][totalchn / 2] >> i * 4) &
-				    0xf) - 1) * 2;
-			if (chn < 0 || chn >= totalchn) {
-				c = 0;
-			} else {
-				c = (ch->sid << 4) | chn;
-			}
-		}
-		HDA_BOOTHVERBOSE(
-			device_printf(ch->pdevinfo->dev,
-			    "PCMDIR_%s: Stream setup nid=%d: "
-			    "fmt=0x%04x, dfmt=0x%04x, chan=0x%04x\n",
-			    (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC",
-			    ch->io[i], fmt, dfmt, c);
-		);
-		hdac_command(sc,
-		    HDA_CMD_SET_CONV_FMT(cad, ch->io[i], fmt), cad);
-		if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) {
-			hdac_command(sc,
-			    HDA_CMD_SET_DIGITAL_CONV_FMT1(cad, ch->io[i], dfmt),
-			    cad);
-		}
-		hdac_command(sc,
-		    HDA_CMD_SET_CONV_STREAM_CHAN(cad, ch->io[i], c), cad);
-#if 0
-		hdac_command(sc,
-		    HDA_CMD_SET_CONV_CHAN_COUNT(cad, ch->io[i], 1), cad);
-		hdac_command(sc,
-		    HDA_CMD_SET_HDMI_CHAN_SLOT(cad, ch->io[i], 0x00), cad);
-		hdac_command(sc,
-		    HDA_CMD_SET_HDMI_CHAN_SLOT(cad, ch->io[i], 0x11), cad);
-#endif
-		chn += HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) + 1;
-	}
-}
-
-/*
- * Greatest Common Divisor.
- */
-static unsigned
-gcd(unsigned a, unsigned b)
-{
-	u_int c;
-
-	while (b != 0) {
-		c = a;
-		a = b;
-		b = (c % b);
-	}
-	return (a);
-}
-
-/*
- * Least Common Multiple.
- */
-static unsigned
-lcm(unsigned a, unsigned b)
-{
-
-	return ((a * b) / gcd(a, b));
-}
-
-static int
-hdac_channel_setfragments(kobj_t obj, void *data,
-					uint32_t blksz, uint32_t blkcnt)
-{
-	struct hdac_chan *ch = data;
-	struct hdac_softc *sc = ch->devinfo->codec->sc;
-
-	blksz -= blksz % lcm(HDAC_DMA_ALIGNMENT, sndbuf_getalign(ch->b));
-
-	if (blksz > (sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN))
-		blksz = sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN;
-	if (blksz < HDA_BLK_MIN)
-		blksz = HDA_BLK_MIN;
-	if (blkcnt > HDA_BDL_MAX)
-		blkcnt = HDA_BDL_MAX;
-	if (blkcnt < HDA_BDL_MIN)
-		blkcnt = HDA_BDL_MIN;
-
-	while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->b)) {
-		if ((blkcnt >> 1) >= HDA_BDL_MIN)
-			blkcnt >>= 1;
-		else if ((blksz >> 1) >= HDA_BLK_MIN)
-			blksz >>= 1;
-		else
-			break;
-	}
-
-	if ((sndbuf_getblksz(ch->b) != blksz ||
-	    sndbuf_getblkcnt(ch->b) != blkcnt) &&
-	    sndbuf_resize(ch->b, blkcnt, blksz) != 0)
-		device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n",
-		    __func__, blksz, blkcnt);
-
-	ch->blksz = sndbuf_getblksz(ch->b);
-	ch->blkcnt = sndbuf_getblkcnt(ch->b);
-
-	return (0);
-}
-
-static uint32_t
-hdac_channel_setblocksize(kobj_t obj, void *data, uint32_t blksz)
-{
-	struct hdac_chan *ch = data;
-
-	hdac_channel_setfragments(obj, data, blksz, ch->pdevinfo->chan_blkcnt);
-
-	return (ch->blksz);
-}
-
-static void
-hdac_channel_stop(struct hdac_softc *sc, struct hdac_chan *ch)
-{
-	struct hdac_devinfo *devinfo = ch->devinfo;
-	struct hdac_widget *w;
-	nid_t cad = devinfo->codec->cad;
-	int i;
-
-	hdac_stream_stop(ch);
-
-	for (i = 0; ch->io[i] != -1; i++) {
-		w = hdac_widget_get(ch->devinfo, ch->io[i]);
-		if (w == NULL)
-			continue;
-		if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) {
-			hdac_command(sc,
-			    HDA_CMD_SET_DIGITAL_CONV_FMT1(cad, ch->io[i], 0),
-			    cad);
-		}
-		hdac_command(sc,
-		    HDA_CMD_SET_CONV_STREAM_CHAN(cad, ch->io[i],
-		    0), cad);
-	}
-}
-
-static void
-hdac_channel_start(struct hdac_softc *sc, struct hdac_chan *ch)
-{
-	ch->ptr = 0;
-	ch->prevptr = 0;
-	hdac_stream_stop(ch);
-	hdac_stream_reset(ch);
-	hdac_bdl_setup(ch);
-	hdac_stream_setid(ch);
-	hdac_stream_setup(ch);
-	hdac_stream_start(ch);
-}
-
-static int
-hdac_channel_trigger(kobj_t obj, void *data, int go)
-{
-	struct hdac_chan *ch = data;
-	struct hdac_softc *sc = ch->devinfo->codec->sc;
-
-	if (!PCMTRIG_COMMON(go))
-		return (0);
-
-	hdac_lock(sc);
-	switch (go) {
-	case PCMTRIG_START:
-		hdac_channel_start(sc, ch);
-		break;
-	case PCMTRIG_STOP:
-	case PCMTRIG_ABORT:
-		hdac_channel_stop(sc, ch);
-		break;
-	default:
-		break;
-	}
-	hdac_unlock(sc);
-
-	return (0);
-}
-
-static uint32_t
-hdac_channel_getptr(kobj_t obj, void *data)
-{
-	struct hdac_chan *ch = data;
-	struct hdac_softc *sc = ch->devinfo->codec->sc;
-	uint32_t ptr;
-
-	hdac_lock(sc);
-	if (sc->polling != 0)
-		ptr = ch->ptr;
-	else if (ch->dmapos != NULL)
-		ptr = *(ch->dmapos);
-	else
-		ptr = HDAC_READ_4(&sc->mem, ch->off + HDAC_SDLPIB);
-	hdac_unlock(sc);
-
-	/*
-	 * Round to available space and force 128 bytes aligment.
-	 */
-	ptr %= ch->blksz * ch->blkcnt;
-	ptr &= HDA_BLK_ALIGN;
-
-	return (ptr);
-}
-
-static struct pcmchan_caps *
-hdac_channel_getcaps(kobj_t obj, void *data)
-{
-	return (&((struct hdac_chan *)data)->caps);
-}
-
-static kobj_method_t hdac_channel_methods[] = {
-	KOBJMETHOD(channel_init,		hdac_channel_init),
-	KOBJMETHOD(channel_setformat,		hdac_channel_setformat),
-	KOBJMETHOD(channel_setspeed,		hdac_channel_setspeed),
-	KOBJMETHOD(channel_setblocksize,	hdac_channel_setblocksize),
-	KOBJMETHOD(channel_setfragments,	hdac_channel_setfragments),
-	KOBJMETHOD(channel_trigger,		hdac_channel_trigger),
-	KOBJMETHOD(channel_getptr,		hdac_channel_getptr),
-	KOBJMETHOD(channel_getcaps,		hdac_channel_getcaps),
-	KOBJMETHOD_END
-};
-CHANNEL_DECLARE(hdac_channel);
-
-static int
-hdac_audio_ctl_ossmixer_init(struct snd_mixer *m)
-{
-	struct hdac_pcm_devinfo *pdevinfo = mix_getdevinfo(m);
-	struct hdac_devinfo *devinfo = pdevinfo->devinfo;
-	struct hdac_softc *sc = devinfo->codec->sc;
-	struct hdac_widget *w, *cw;
-	struct hdac_audio_ctl *ctl;
-	uint32_t mask, recmask, id;
-	int i, j, softpcmvol;
-
-	hdac_lock(sc);
-
-	/* Make sure that in case of soft volume it won't stay muted. */
-	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-		pdevinfo->left[i] = 100;
-		pdevinfo->right[i] = 100;
-	}
-
-	mask = 0;
-	recmask = 0;
-	id = hdac_codec_id(devinfo->codec);
-
-	/* Declate EAPD as ogain control. */
-	if (pdevinfo->play >= 0) {
-		for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-			w = hdac_widget_get(devinfo, i);
-			if (w == NULL || w->enable == 0)
-				continue;
-			if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX ||
-			    w->param.eapdbtl == HDAC_INVALID ||
-			    w->bindas != sc->chans[pdevinfo->play].as)
-				continue;
-			mask |= SOUND_MASK_OGAIN;
-			break;
-		}
-	}
-
-	/* Declare volume controls assigned to this association. */
-	i = 0;
-	ctl = NULL;
-	while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) {
-		if (ctl->enable == 0)
-			continue;
-		if ((pdevinfo->play >= 0 &&
-		    ctl->widget->bindas == sc->chans[pdevinfo->play].as) ||
-		    (pdevinfo->rec >= 0 &&
-		    ctl->widget->bindas == sc->chans[pdevinfo->rec].as) ||
-		    (ctl->widget->bindas == -2 && pdevinfo->index == 0))
-			mask |= ctl->ossmask;
-	}
-
-	/* Declare record sources available to this association. */
-	if (pdevinfo->rec >= 0) {
-		struct hdac_chan *ch = &sc->chans[pdevinfo->rec];
-		for (i = 0; ch->io[i] != -1; i++) {
-			w = hdac_widget_get(devinfo, ch->io[i]);
-			if (w == NULL || w->enable == 0)
-				continue;
-			for (j = 0; j < w->nconns; j++) {
-				if (w->connsenable[j] == 0)
-					continue;
-				cw = hdac_widget_get(devinfo, w->conns[j]);
-				if (cw == NULL || cw->enable == 0)
-					continue;
-				if (cw->bindas != sc->chans[pdevinfo->rec].as &&
-				    cw->bindas != -2)
-					continue;
-				recmask |= cw->ossmask;
-			}
-		}
-	}
-
-	/* Declare soft PCM volume if needed. */
-	if (pdevinfo->play >= 0) {
-		ctl = NULL;
-		if ((mask & SOUND_MASK_PCM) == 0 ||
-		    (devinfo->function.audio.quirks & HDA_QUIRK_SOFTPCMVOL)) {
-			softpcmvol = 1;
-			mask |= SOUND_MASK_PCM;
-		} else {
-			softpcmvol = 0;
-			i = 0;
-			while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) {
-				if (ctl->enable == 0)
-					continue;
-				if (ctl->widget->bindas != sc->chans[pdevinfo->play].as &&
-				    (ctl->widget->bindas != -2 || pdevinfo->index != 0))
-					continue;
-				if (!(ctl->ossmask & SOUND_MASK_PCM))
-					continue;
-				if (ctl->step > 0)
-					break;
-			}
-		}
-
-		if (softpcmvol == 1 || ctl == NULL) {
-			pcm_setflags(pdevinfo->dev, pcm_getflags(pdevinfo->dev) | SD_F_SOFTPCMVOL);
-			HDA_BOOTVERBOSE(
-				device_printf(pdevinfo->dev,
-				    "%s Soft PCM volume\n",
-				    (softpcmvol == 1) ? "Forcing" : "Enabling");
-			);
-		}
-	}
-
-	/* Declare master volume if needed. */
-	if (pdevinfo->play >= 0) {
-		if ((mask & (SOUND_MASK_VOLUME | SOUND_MASK_PCM)) ==
-		    SOUND_MASK_PCM) {
-			mask |= SOUND_MASK_VOLUME;
-			mix_setparentchild(m, SOUND_MIXER_VOLUME,
-			    SOUND_MASK_PCM);
-			mix_setrealdev(m, SOUND_MIXER_VOLUME,
-			    SOUND_MIXER_NONE);
-			HDA_BOOTVERBOSE(
-				device_printf(pdevinfo->dev,
-				    "Forcing master volume with PCM\n");
-			);
-		}
-	}
-
-	recmask &= (1 << SOUND_MIXER_NRDEVICES) - 1;
-	mask &= (1 << SOUND_MIXER_NRDEVICES) - 1;
-
-	mix_setrecdevs(m, recmask);
-	mix_setdevs(m, mask);
-
-	hdac_unlock(sc);
-
-	return (0);
-}
-
-static int
-hdac_audio_ctl_ossmixer_set(struct snd_mixer *m, unsigned dev,
-					unsigned left, unsigned right)
-{
-	struct hdac_pcm_devinfo *pdevinfo = mix_getdevinfo(m);
-	struct hdac_devinfo *devinfo = pdevinfo->devinfo;
-	struct hdac_softc *sc = devinfo->codec->sc;
-	struct hdac_widget *w;
-	struct hdac_audio_ctl *ctl;
-	uint32_t mute;
-	int lvol, rvol;
-	int i, j;
-
-	hdac_lock(sc);
-	/* Save new values. */
-	pdevinfo->left[dev] = left;
-	pdevinfo->right[dev] = right;
-	
-	/* 'ogain' is the special case implemented with EAPD. */
-	if (dev == SOUND_MIXER_OGAIN) {
-		uint32_t orig;
-		w = NULL;
-		for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-			w = hdac_widget_get(devinfo, i);
-			if (w == NULL || w->enable == 0)
-				continue;
-			if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX ||
-			    w->param.eapdbtl == HDAC_INVALID)
-				continue;
-			break;
-		}
-		if (i >= devinfo->endnode) {
-			hdac_unlock(sc);
-			return (-1);
-		}
-		orig = w->param.eapdbtl;
-		if (left == 0)
-			w->param.eapdbtl &= ~HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
-		else
-			w->param.eapdbtl |= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
-		if (orig != w->param.eapdbtl) {
-			uint32_t val;
-
-			val = w->param.eapdbtl;
-			if (devinfo->function.audio.quirks & HDA_QUIRK_EAPDINV)
-				val ^= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
-			hdac_command(sc,
-			    HDA_CMD_SET_EAPD_BTL_ENABLE(devinfo->codec->cad,
-			    w->nid, val), devinfo->codec->cad);
-		}
-		hdac_unlock(sc);
-		return (left | (left << 8));
-	}
-
-	/* Recalculate all controls related to this OSS device. */
-	i = 0;
-	while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) {
-		if (ctl->enable == 0 ||
-		    !(ctl->ossmask & (1 << dev)))
-			continue;
-		if (!((pdevinfo->play >= 0 &&
-		    ctl->widget->bindas == sc->chans[pdevinfo->play].as) ||
-		    (pdevinfo->rec >= 0 &&
-		    ctl->widget->bindas == sc->chans[pdevinfo->rec].as) ||
-		    ctl->widget->bindas == -2))
-			continue;
-
-		lvol = 100;
-		rvol = 100;
-		for (j = 0; j < SOUND_MIXER_NRDEVICES; j++) {
-			if (ctl->ossmask & (1 << j)) {
-				lvol = lvol * pdevinfo->left[j] / 100;
-				rvol = rvol * pdevinfo->right[j] / 100;
-			}
-		}
-		mute = (lvol == 0) ? HDA_AMP_MUTE_LEFT : 0;
-		mute |= (rvol == 0) ? HDA_AMP_MUTE_RIGHT : 0;
-		lvol = (lvol * ctl->step + 50) / 100;
-		rvol = (rvol * ctl->step + 50) / 100;
-		hdac_audio_ctl_amp_set(ctl, mute, lvol, rvol);
-	}
-	hdac_unlock(sc);
-
-	return (left | (right << 8));
-}
-
-/*
- * Commutate specified record source.
- */
-static uint32_t
-hdac_audio_ctl_recsel_comm(struct hdac_pcm_devinfo *pdevinfo, uint32_t src, nid_t nid, int depth)
-{
-	struct hdac_devinfo *devinfo = pdevinfo->devinfo;
-	struct hdac_widget *w, *cw;
-	struct hdac_audio_ctl *ctl;
-	char buf[64];
-	int i, muted;
-	uint32_t res = 0;
-
-	if (depth > HDA_PARSE_MAXDEPTH)
-		return (0);
-
-	w = hdac_widget_get(devinfo, nid);
-	if (w == NULL || w->enable == 0)
-		return (0);
-		
-	for (i = 0; i < w->nconns; i++) {
-		if (w->connsenable[i] == 0)
-			continue;
-		cw = hdac_widget_get(devinfo, w->conns[i]);
-		if (cw == NULL || cw->enable == 0 || cw->bindas == -1)
-			continue;
-		/* Call recursively to trace signal to it's source if needed. */
-		if ((src & cw->ossmask) != 0) {
-			if (cw->ossdev < 0) {
-				res |= hdac_audio_ctl_recsel_comm(pdevinfo, src,
-				    w->conns[i], depth + 1);
-			} else {
-				res |= cw->ossmask;
-			}
-		}
-		/* We have two special cases: mixers and others (selectors). */
-		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER) {
-			ctl = hdac_audio_ctl_amp_get(devinfo,
-			    w->nid, HDA_CTL_IN, i, 1);
-			if (ctl == NULL) 
-				continue;
-			/* If we have input control on this node mute them
-			 * according to requested sources. */
-			muted = (src & cw->ossmask) ? 0 : 1;
-	    		if (muted != ctl->forcemute) {
-				ctl->forcemute = muted;
-				hdac_audio_ctl_amp_set(ctl,
-				    HDA_AMP_MUTE_DEFAULT,
-				    HDA_AMP_VOL_DEFAULT, HDA_AMP_VOL_DEFAULT);
-			}
-			HDA_BOOTHVERBOSE(
-				device_printf(pdevinfo->dev,
-				    "Recsel (%s): nid %d source %d %s\n",
-				    hdac_audio_ctl_ossmixer_mask2allname(
-				    src, buf, sizeof(buf)),
-				    nid, i, muted?"mute":"unmute");
-			);
-		} else {
-			if (w->nconns == 1)
-				break;
-			if ((src & cw->ossmask) == 0)
-				continue;
-			/* If we found requested source - select it and exit. */
-			hdac_widget_connection_select(w, i);
-			HDA_BOOTHVERBOSE(
-				device_printf(pdevinfo->dev,
-				    "Recsel (%s): nid %d source %d select\n",
-				    hdac_audio_ctl_ossmixer_mask2allname(
-			    	    src, buf, sizeof(buf)),
-				    nid, i);
-			);
-			break;
-		}
-	}
-	return (res);
-}
-
-static uint32_t
-hdac_audio_ctl_ossmixer_setrecsrc(struct snd_mixer *m, uint32_t src)
-{
-	struct hdac_pcm_devinfo *pdevinfo = mix_getdevinfo(m);
-	struct hdac_devinfo *devinfo = pdevinfo->devinfo;
-	struct hdac_widget *w;
-	struct hdac_softc *sc = devinfo->codec->sc;
-	struct hdac_chan *ch;
-	int i;
-	uint32_t ret = 0xffffffff;
-
-	hdac_lock(sc);
-
-	/* Commutate requested recsrc for each ADC. */
-	ch = &sc->chans[pdevinfo->rec];
-	for (i = 0; ch->io[i] != -1; i++) {
-		w = hdac_widget_get(devinfo, ch->io[i]);
-		if (w == NULL || w->enable == 0)
-			continue;
-		ret &= hdac_audio_ctl_recsel_comm(pdevinfo, src, ch->io[i], 0);
-	}
-
-	hdac_unlock(sc);
-
-	return ((ret == 0xffffffff)? 0 : ret);
-}
-
-static kobj_method_t hdac_audio_ctl_ossmixer_methods[] = {
-	KOBJMETHOD(mixer_init,		hdac_audio_ctl_ossmixer_init),
-	KOBJMETHOD(mixer_set,		hdac_audio_ctl_ossmixer_set),
-	KOBJMETHOD(mixer_setrecsrc,	hdac_audio_ctl_ossmixer_setrecsrc),
-	KOBJMETHOD_END
-};
-MIXER_DECLARE(hdac_audio_ctl_ossmixer);
-
 static void
 hdac_unsolq_task(void *context, int pending)
 {
@@ -4154,6 +1062,7 @@
 	uint16_t vendor;
 	uint8_t v;
 
+	sc = device_get_softc(dev);
 	HDA_BOOTVERBOSE(
 		device_printf(dev, "HDA Driver Revision: %s\n",
 		    HDA_DRV_TEST_REV);
@@ -4177,38 +1086,44 @@
 		}
 	}
 
-	sc = device_get_softc(dev);
-	sc->lock = snd_mtxcreate(device_get_nameunit(dev), HDAC_MTX_NAME);
+	sc->lock = snd_mtxcreate(device_get_nameunit(dev), "HDA driver mutex");
 	sc->dev = dev;
-	sc->pci_subvendor = (uint32_t)pci_get_subdevice(sc->dev) << 16;
-	sc->pci_subvendor |= (uint32_t)pci_get_subvendor(sc->dev) & 0x0000ffff;
-	vendor = pci_get_vendor(dev);
-
-	if (sc->pci_subvendor == HP_NX6325_SUBVENDORX) {
-		/* Screw nx6325 - subdevice/subvendor swapped */
-		sc->pci_subvendor = HP_NX6325_SUBVENDOR;
+	TASK_INIT(&sc->unsolq_task, 0, hdac_unsolq_task, sc);
+	callout_init(&sc->poll_callout, CALLOUT_MPSAFE);
+	for (i = 0; i < HDAC_CODEC_MAX; i++)
+		sc->codecs[i].dev = NULL;
+	if (devid >= 0) {
+		sc->quirks_on = hdac_devices[devid].quirks_on;
+		sc->quirks_off = hdac_devices[devid].quirks_off;
+	} else {
+		sc->quirks_on = 0;
+		sc->quirks_off = 0;
 	}
-
-	callout_init(&sc->poll_hda, CALLOUT_MPSAFE);
-	callout_init(&sc->poll_hdac, CALLOUT_MPSAFE);
-	callout_init(&sc->poll_jack, CALLOUT_MPSAFE);
-
-	TASK_INIT(&sc->unsolq_task, 0, hdac_unsolq_task, sc);
-
-	sc->poll_ticks = 1000000;
-	sc->poll_ival = HDAC_POLL_INTERVAL;
+	if (resource_int_value(device_get_name(dev),
+	    device_get_unit(dev), "msi", &i) == 0) {
+		if (i == 0)
+			sc->quirks_off |= HDAC_QUIRK_MSI;
+		else {
+			sc->quirks_on |= HDAC_QUIRK_MSI;
+			sc->quirks_off |= ~HDAC_QUIRK_MSI;
+		}
+	}
+	hdac_config_fetch(sc, &sc->quirks_on, &sc->quirks_off);
+	HDA_BOOTVERBOSE(
+		device_printf(sc->dev,
+		    "Config options: on=0x%08x off=0x%08x\n",
+		    sc->quirks_on, sc->quirks_off);
+	);
+	sc->poll_ival = hz;
 	if (resource_int_value(device_get_name(dev),
 	    device_get_unit(dev), "polling", &i) == 0 && i != 0)
 		sc->polling = 1;
 	else
 		sc->polling = 0;
 
-	sc->hdabus = NULL;
-	for (i = 0; i < HDAC_CODEC_MAX; i++)
-		sc->codecs[i] = NULL;
-
 	pci_enable_busmaster(dev);
 
+	vendor = pci_get_vendor(dev);
 	if (vendor == INTEL_VENDORID) {
 		/* TCSEL -> TC0 */
 		v = pci_read_config(dev, 0x44, 1);
@@ -4219,18 +1134,6 @@
 		);
 	}
 
-	if (devid >= 0 && (hdac_devices[devid].flags & HDAC_NO_MSI))
-		sc->flags &= ~HDAC_F_MSI;
-	else
-		sc->flags |= HDAC_F_MSI;
-	if (resource_int_value(device_get_name(dev),
-	    device_get_unit(dev), "msi", &i) == 0) {
-		if (i == 0)
-			sc->flags &= ~HDAC_F_MSI;
-		else
-			sc->flags |= HDAC_F_MSI;
-	}
-
 #if defined(__i386__) || defined(__amd64__)
 	sc->flags |= HDAC_F_DMA_NOCACHE;
 
@@ -4299,10 +1202,7 @@
 	if (result != 0)
 		goto hdac_attach_fail;
 
-	if (devid >= 0 && (hdac_devices[devid].flags & HDAC_NO_64BIT))
-		sc->support_64bit = 0;
-
-	/* Allocate CORB and RIRB dma memory */
+	/* Allocate CORB, RIRB, POS and BDLs dma memory */
 	result = hdac_dma_alloc(sc, &sc->corb_dma,
 	    sc->corb_size * sizeof(uint32_t));
 	if (result != 0)
@@ -4311,10 +1211,34 @@
 	    sc->rirb_size * sizeof(struct hdac_rirb));
 	if (result != 0)
 		goto hdac_attach_fail;
+	sc->streams = malloc(sizeof(struct hdac_stream) * sc->num_ss,
+	    M_HDAC, M_ZERO | M_WAITOK);
+	for (i = 0; i < sc->num_ss; i++) {
+		result = hdac_dma_alloc(sc, &sc->streams[i].bdl,
+		    sizeof(struct hdac_bdle) * HDA_BDL_MAX);
+		if (result != 0)
+			goto hdac_attach_fail;
+	}
+	if (sc->quirks_on & HDAC_QUIRK_DMAPOS) {
+		if (hdac_dma_alloc(sc, &sc->pos_dma, (sc->num_ss) * 8) != 0) {
+			HDA_BOOTVERBOSE(
+				device_printf(dev, "Failed to "
+				    "allocate DMA pos buffer "
+				    "(non-fatal)\n");
+			);
+		} else {
+			uint64_t addr = sc->pos_dma.dma_paddr;
+
+			HDAC_WRITE_4(&sc->mem, HDAC_DPIBUBASE, addr >> 32);
+			HDAC_WRITE_4(&sc->mem, HDAC_DPIBLBASE,
+			    (addr & HDAC_DPLBASE_DPLBASE_MASK) |
+			    HDAC_DPLBASE_DPLBASE_DMAPBE);
+		}
+	}
 
 	result = bus_dma_tag_create(
 	    bus_get_dma_tag(sc->dev),		/* parent */
-	    HDAC_DMA_ALIGNMENT,			/* alignment */
+	    HDA_DMA_ALIGNMENT,			/* alignment */
 	    0,					/* boundary */
 	    (sc->support_64bit) ? BUS_SPACE_MAXADDR :
 		BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
@@ -4356,6 +1280,9 @@
 
 hdac_attach_fail:
 	hdac_irq_free(sc);
+	for (i = 0; i < sc->num_ss; i++)
+		hdac_dma_free(sc, &sc->streams[i].bdl);
+	free(sc->streams, M_HDAC);
 	hdac_dma_free(sc, &sc->rirb_dma);
 	hdac_dma_free(sc, &sc->corb_dma);
 	hdac_mem_free(sc);
@@ -4364,3127 +1291,97 @@
 	return (ENXIO);
 }
 
-static void
-hdac_audio_parse(struct hdac_devinfo *devinfo)
+static int
+sysctl_hdac_pindump(SYSCTL_HANDLER_ARGS)
 {
-	struct hdac_codec *codec = devinfo->codec;
-	struct hdac_softc *sc = codec->sc;
-	struct hdac_widget *w;
-	uint32_t res;
-	int i;
-	nid_t cad, nid;
+	struct hdac_softc *sc;
+	device_t *devlist;
+	device_t dev;
+	int devcount, i, err, val;
 
-	cad = devinfo->codec->cad;
-	nid = devinfo->nid;
+	dev = oidp->oid_arg1;
+	sc = device_get_softc(dev);
+	if (sc == NULL)
+		return (EINVAL);
+	val = 0;
+	err = sysctl_handle_int(oidp, &val, 0, req);
+	if (err != 0 || req->newptr == NULL || val == 0)
+		return (err);
 
-	res = hdac_command(sc,
-	    HDA_CMD_GET_PARAMETER(cad , nid, HDA_PARAM_GPIO_COUNT), cad);
-	devinfo->function.audio.gpio = res;
+	/* XXX: Temporary. For debugging. */
+	if (val == 100) {
+		hdac_suspend(dev);
+		return (0);
+	} else if (val == 101) {
+		hdac_resume(dev);
+		return (0);
+	}
 
-	HDA_BOOTVERBOSE(
-		device_printf(sc->dev, "GPIO: 0x%08x "
-		    "NumGPIO=%d NumGPO=%d "
-		    "NumGPI=%d GPIWake=%d GPIUnsol=%d\n",
-		    devinfo->function.audio.gpio,
-		    HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->function.audio.gpio),
-		    HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->function.audio.gpio),
-		    HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->function.audio.gpio),
-		    HDA_PARAM_GPIO_COUNT_GPI_WAKE(devinfo->function.audio.gpio),
-		    HDA_PARAM_GPIO_COUNT_GPI_UNSOL(devinfo->function.audio.gpio));
-	);
+	if ((err = device_get_children(dev, &devlist, &devcount)) != 0)
+		return (err);
+	hdac_lock(sc);
+	for (i = 0; i < devcount; i++)
+		HDAC_PINDUMP(devlist[i]);
+	hdac_unlock(sc);
+	free(devlist, M_TEMP);
+	return (0);
+}
 
-	res = hdac_command(sc,
-	    HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_SUPP_STREAM_FORMATS),
-	    cad);
-	devinfo->function.audio.supp_stream_formats = res;
+static int
+hdac_data_rate(uint16_t fmt)
+{
+	static const int bits[8] = { 8, 16, 20, 24, 32, 32, 32, 32 };
+	int rate;
 
-	res = hdac_command(sc,
-	    HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_SUPP_PCM_SIZE_RATE),
-	    cad);
-	devinfo->function.audio.supp_pcm_size_rate = res;
-
-	res = hdac_command(sc,
-	    HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_OUTPUT_AMP_CAP),
-	    cad);
-	devinfo->function.audio.outamp_cap = res;
-
-	res = hdac_command(sc,
-	    HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_INPUT_AMP_CAP),
-	    cad);
-	devinfo->function.audio.inamp_cap = res;
-
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL)
-			device_printf(sc->dev, "Ghost widget! nid=%d!\n", i);
-		else {
-			w->devinfo = devinfo;
-			w->nid = i;
-			w->enable = 1;
-			w->selconn = -1;
-			w->pflags = 0;
-			w->ossdev = -1;
-			w->bindas = -1;
-			w->param.eapdbtl = HDAC_INVALID;
-			hdac_widget_parse(w);
-		}
-	}
+	if (fmt & (1 << 14))
+		rate = 44100;
+	else
+		rate = 48000;
+	rate *= ((fmt >> 11) & 0x07) + 1;
+	rate /= ((fmt >> 8) & 0x07) + 1;
+	rate *= ((bits[(fmt >> 4) & 0x03]) * ((fmt & 0x0f) + 1) + 7) / 8;
+	return (rate);
 }
 
 static void
-hdac_audio_ctl_parse(struct hdac_devinfo *devinfo)
+hdac_poll_reinit(struct hdac_softc *sc)
 {
-	struct hdac_softc *sc = devinfo->codec->sc;
-	struct hdac_audio_ctl *ctls;
-	struct hdac_widget *w, *cw;
-	int i, j, cnt, max, ocap, icap;
-	int mute, offset, step, size;
+	int i, pollticks, min = 1000000;
+	struct hdac_stream *s;
 
-	/* XXX This is redundant */
-	max = 0;
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
+	if (sc->polling == 0)
+		return;
+	if (sc->unsol_registered > 0)
+		min = hz / 2;
+	for (i = 0; i < sc->num_ss; i++) {
+		s = &sc->streams[i];
+		if (s->running == 0)
 			continue;
-		if (w->param.outamp_cap != 0)
-			max++;
-		if (w->param.inamp_cap != 0) {
-			switch (w->type) {
-			case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR:
-			case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER:
-				for (j = 0; j < w->nconns; j++) {
-					cw = hdac_widget_get(devinfo,
-					    w->conns[j]);
-					if (cw == NULL || cw->enable == 0)
-						continue;
-					max++;
-				}
-				break;
-			default:
-				max++;
-				break;
-			}
+		pollticks = ((uint64_t)hz * s->blksz) /
+		    hdac_data_rate(s->format);
+		pollticks >>= 1;
+		if (pollticks > hz)
+			pollticks = hz;
+		if (pollticks < 1) {
+			HDA_BOOTVERBOSE(
+				device_printf(sc->dev,
+				    "poll interval < 1 tick !\n");
+			);
+			pollticks = 1;
 		}
-	}
-
-	devinfo->function.audio.ctlcnt = max;
-
-	if (max < 1)
-		return;
-
-	ctls = (struct hdac_audio_ctl *)malloc(
-	    sizeof(*ctls) * max, M_HDAC, M_ZERO | M_NOWAIT);
-
-	if (ctls == NULL) {
-		/* Blekh! */
-		device_printf(sc->dev, "unable to allocate ctls!\n");
-		devinfo->function.audio.ctlcnt = 0;
-		return;
-	}
-
-	cnt = 0;
-	for (i = devinfo->startnode; cnt < max && i < devinfo->endnode; i++) {
-		if (cnt >= max) {
-			device_printf(sc->dev, "%s: Ctl overflow!\n",
-			    __func__);
-			break;
-		}
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		ocap = w->param.outamp_cap;
-		icap = w->param.inamp_cap;
-		if (ocap != 0) {
-			mute = HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(ocap);
-			step = HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(ocap);
-			size = HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(ocap);
-			offset = HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(ocap);
-			/*if (offset > step) {
-				HDA_BOOTVERBOSE(
-					device_printf(sc->dev,
-					    "BUGGY outamp: nid=%d "
-					    "[offset=%d > step=%d]\n",
-					    w->nid, offset, step);
-				);
-				offset = step;
-			}*/
-			ctls[cnt].enable = 1;
-			ctls[cnt].widget = w;
-			ctls[cnt].mute = mute;
-			ctls[cnt].step = step;
-			ctls[cnt].size = size;
-			ctls[cnt].offset = offset;
-			ctls[cnt].left = offset;
-			ctls[cnt].right = offset;
-			if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX ||
-			    w->waspin)
-				ctls[cnt].ndir = HDA_CTL_IN;
-			else 
-				ctls[cnt].ndir = HDA_CTL_OUT;
-			ctls[cnt++].dir = HDA_CTL_OUT;
-		}
-
-		if (icap != 0) {
-			mute = HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(icap);
-			step = HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(icap);
-			size = HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(icap);
-			offset = HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(icap);
-			/*if (offset > step) {
-				HDA_BOOTVERBOSE(
-					device_printf(sc->dev,
-					    "BUGGY inamp: nid=%d "
-					    "[offset=%d > step=%d]\n",
-					    w->nid, offset, step);
-				);
-				offset = step;
-			}*/
-			switch (w->type) {
-			case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR:
-			case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER:
-				for (j = 0; j < w->nconns; j++) {
-					if (cnt >= max) {
-						device_printf(sc->dev,
-						    "%s: Ctl overflow!\n",
-						    __func__);
-						break;
-					}
-					cw = hdac_widget_get(devinfo,
-					    w->conns[j]);
-					if (cw == NULL || cw->enable == 0)
-						continue;
-					ctls[cnt].enable = 1;
-					ctls[cnt].widget = w;
-					ctls[cnt].childwidget = cw;
-					ctls[cnt].index = j;
-					ctls[cnt].mute = mute;
-					ctls[cnt].step = step;
-					ctls[cnt].size = size;
-					ctls[cnt].offset = offset;
-					ctls[cnt].left = offset;
-					ctls[cnt].right = offset;
-	    				ctls[cnt].ndir = HDA_CTL_IN;
-					ctls[cnt++].dir = HDA_CTL_IN;
-				}
-				break;
-			default:
-				if (cnt >= max) {
-					device_printf(sc->dev,
-					    "%s: Ctl overflow!\n",
-					    __func__);
-					break;
-				}
-				ctls[cnt].enable = 1;
-				ctls[cnt].widget = w;
-				ctls[cnt].mute = mute;
-				ctls[cnt].step = step;
-				ctls[cnt].size = size;
-				ctls[cnt].offset = offset;
-				ctls[cnt].left = offset;
-				ctls[cnt].right = offset;
-				if (w->type ==
-				    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-					ctls[cnt].ndir = HDA_CTL_OUT;
-				else 
-					ctls[cnt].ndir = HDA_CTL_IN;
-				ctls[cnt++].dir = HDA_CTL_IN;
-				break;
-			}
-		}
-	}
-
-	devinfo->function.audio.ctl = ctls;
-}
-
-static void
-hdac_audio_as_parse(struct hdac_devinfo *devinfo)
-{
-	struct hdac_softc *sc = devinfo->codec->sc;
-	struct hdac_audio_as *as;
-	struct hdac_widget *w;
-	int i, j, cnt, max, type, dir, assoc, seq, first, hpredir;
-
-	/* Count present associations */
-	max = 0;
-	for (j = 1; j < 16; j++) {
-		for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-			w = hdac_widget_get(devinfo, i);
-			if (w == NULL || w->enable == 0)
-				continue;
-			if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-				continue;
-			if (HDA_CONFIG_DEFAULTCONF_ASSOCIATION(w->wclass.pin.config)
-			    != j)
-				continue;
-			max++;
-			if (j != 15)  /* There could be many 1-pin assocs #15 */
-				break;
-		}
-	}
-
-	devinfo->function.audio.ascnt = max;
-
-	if (max < 1)
-		return;
-
-	as = (struct hdac_audio_as *)malloc(
-	    sizeof(*as) * max, M_HDAC, M_ZERO | M_NOWAIT);
-
-	if (as == NULL) {
-		/* Blekh! */
-		device_printf(sc->dev, "unable to allocate assocs!\n");
-		devinfo->function.audio.ascnt = 0;
-		return;
-	}
-	
-	for (i = 0; i < max; i++) {
-		as[i].hpredir = -1;
-		as[i].chan = -1;
-		as[i].digital = 0;
-	}
-
-	/* Scan associations skipping as=0. */
-	cnt = 0;
-	for (j = 1; j < 16; j++) {
-		first = 16;
-		hpredir = 0;
-		for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-			w = hdac_widget_get(devinfo, i);
-			if (w == NULL || w->enable == 0)
-				continue;
-			if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-				continue;
-			assoc = HDA_CONFIG_DEFAULTCONF_ASSOCIATION(w->wclass.pin.config);
-			seq = HDA_CONFIG_DEFAULTCONF_SEQUENCE(w->wclass.pin.config);
-			if (assoc != j) {
-				continue;
-			}
-			KASSERT(cnt < max,
-			    ("%s: Associations owerflow (%d of %d)",
-			    __func__, cnt, max));
-			type = w->wclass.pin.config &
-			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
-			/* Get pin direction. */
-			if (type == HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT ||
-			    type == HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER ||
-			    type == HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT ||
-			    type == HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_OUT ||
-			    type == HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_OUT)
-				dir = HDA_CTL_OUT;
-			else
-				dir = HDA_CTL_IN;
-			/* If this is a first pin - create new association. */
-			if (as[cnt].pincnt == 0) {
-				as[cnt].enable = 1;
-				as[cnt].index = j;
-				as[cnt].dir = dir;
-			}
-			if (seq < first)
-				first = seq;
-			/* Check association correctness. */
-			if (as[cnt].pins[seq] != 0) {
-				device_printf(sc->dev, "%s: Duplicate pin %d (%d) "
-				    "in association %d! Disabling association.\n",
-				    __func__, seq, w->nid, j);
-				as[cnt].enable = 0;
-			}
-			if (dir != as[cnt].dir) {
-				device_printf(sc->dev, "%s: Pin %d has wrong "
-				    "direction for association %d! Disabling "
-				    "association.\n",
-				    __func__, w->nid, j);
-				as[cnt].enable = 0;
-			}
-			if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) {
-				if (HDA_PARAM_PIN_CAP_DP(w->wclass.pin.cap))
-					as[cnt].digital = 3;
-				else if (HDA_PARAM_PIN_CAP_HDMI(w->wclass.pin.cap))
-					as[cnt].digital = 2;
-				else
-					as[cnt].digital = 1;
-			}
-			/* Headphones with seq=15 may mean redirection. */
-			if (type == HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT &&
-			    seq == 15)
-				hpredir = 1;
-			as[cnt].pins[seq] = w->nid;
-			as[cnt].pincnt++;
-			/* Association 15 is a multiple unassociated pins. */
-			if (j == 15)
-				cnt++;
-		}
-		if (j != 15 && as[cnt].pincnt > 0) {
-			if (hpredir && as[cnt].pincnt > 1)
-				as[cnt].hpredir = first;
-			cnt++;
-		}
+		if (min > pollticks)
+			min = pollticks;
 	}
 	HDA_BOOTVERBOSE(
 		device_printf(sc->dev,
-		    "%d associations found:\n", max);
-		for (i = 0; i < max; i++) {
-			device_printf(sc->dev,
-			    "Association %d (%d) %s%s:\n",
-			    i, as[i].index, (as[i].dir == HDA_CTL_IN)?"in":"out",
-			    as[i].enable?"":" (disabled)");
-			for (j = 0; j < 16; j++) {
-				if (as[i].pins[j] == 0)
-					continue;
-				device_printf(sc->dev,
-				    " Pin nid=%d seq=%d\n",
-				    as[i].pins[j], j);
-			}
-		}
+		    "poll interval %d -> %d ticks\n",
+		    sc->poll_ival, min);
 	);
-
-	devinfo->function.audio.as = as;
-}
-
-static const struct {
-	uint32_t model;
-	uint32_t id;
-	uint32_t set, unset;
-} hdac_quirks[] = {
-	/*
-	 * XXX Force stereo quirk. Monoural recording / playback
-	 *     on few codecs (especially ALC880) seems broken or
-	 *     perhaps unsupported.
-	 */
-	{ HDA_MATCH_ALL, HDA_MATCH_ALL,
-	    HDA_QUIRK_FORCESTEREO | HDA_QUIRK_IVREF, 0 },
-	{ ACER_ALL_SUBVENDOR, HDA_MATCH_ALL,
-	    HDA_QUIRK_GPIO0, 0 },
-	{ ASUS_G2K_SUBVENDOR, HDA_CODEC_ALC660,
-	    HDA_QUIRK_GPIO0, 0 },
-	{ ASUS_M5200_SUBVENDOR, HDA_CODEC_ALC880,
-	    HDA_QUIRK_GPIO0, 0 },
-	{ ASUS_A7M_SUBVENDOR, HDA_CODEC_ALC880,
-	    HDA_QUIRK_GPIO0, 0 },
-	{ ASUS_A7T_SUBVENDOR, HDA_CODEC_ALC882,
-	    HDA_QUIRK_GPIO0, 0 },
-	{ ASUS_W2J_SUBVENDOR, HDA_CODEC_ALC882,
-	    HDA_QUIRK_GPIO0, 0 },
-	{ ASUS_U5F_SUBVENDOR, HDA_CODEC_AD1986A,
-	    HDA_QUIRK_EAPDINV, 0 },
-	{ ASUS_A8X_SUBVENDOR, HDA_CODEC_AD1986A,
-	    HDA_QUIRK_EAPDINV, 0 },
-	{ ASUS_F3JC_SUBVENDOR, HDA_CODEC_ALC861,
-	    HDA_QUIRK_OVREF, 0 },
-	{ UNIWILL_9075_SUBVENDOR, HDA_CODEC_ALC861,
-	    HDA_QUIRK_OVREF, 0 },
-	/*{ ASUS_M2N_SUBVENDOR, HDA_CODEC_AD1988,
-	    HDA_QUIRK_IVREF80, HDA_QUIRK_IVREF50 | HDA_QUIRK_IVREF100 },*/
-	{ MEDION_MD95257_SUBVENDOR, HDA_CODEC_ALC880,
-	    HDA_QUIRK_GPIO1, 0 },
-	{ LENOVO_3KN100_SUBVENDOR, HDA_CODEC_AD1986A,
-	    HDA_QUIRK_EAPDINV | HDA_QUIRK_SENSEINV, 0 },
-	{ SAMSUNG_Q1_SUBVENDOR, HDA_CODEC_AD1986A,
-	    HDA_QUIRK_EAPDINV, 0 },
-	{ APPLE_MB3_SUBVENDOR, HDA_CODEC_ALC885,
-	    HDA_QUIRK_GPIO0 | HDA_QUIRK_OVREF50, 0},
-	{ APPLE_INTEL_MAC, HDA_CODEC_STAC9221,
-	    HDA_QUIRK_GPIO0 | HDA_QUIRK_GPIO1, 0 },
-	{ APPLE_MACBOOKPRO55, HDA_CODEC_CS4206,
-	    HDA_QUIRK_GPIO1 | HDA_QUIRK_GPIO3, 0 },
-	{ DELL_D630_SUBVENDOR, HDA_CODEC_STAC9205X,
-	    HDA_QUIRK_GPIO0, 0 },
-	{ DELL_V1400_SUBVENDOR, HDA_CODEC_STAC9228X,
-	    HDA_QUIRK_GPIO2, 0 },
-	{ DELL_V1500_SUBVENDOR, HDA_CODEC_STAC9205X,
-	    HDA_QUIRK_GPIO0, 0 },
-	{ HDA_MATCH_ALL, HDA_CODEC_AD1988,
-	    HDA_QUIRK_IVREF80, HDA_QUIRK_IVREF50 | HDA_QUIRK_IVREF100 },
-	{ HDA_MATCH_ALL, HDA_CODEC_AD1988B,
-	    HDA_QUIRK_IVREF80, HDA_QUIRK_IVREF50 | HDA_QUIRK_IVREF100 },
-	{ HDA_MATCH_ALL, HDA_CODEC_CX20549,
-	    0, HDA_QUIRK_FORCESTEREO }
-};
-#define HDAC_QUIRKS_LEN (sizeof(hdac_quirks) / sizeof(hdac_quirks[0]))
-
-static void
-hdac_vendor_patch_parse(struct hdac_devinfo *devinfo)
-{
-	struct hdac_widget *w;
-	uint32_t id, subvendor;
-	int i;
-
-	id = hdac_codec_id(devinfo->codec);
-	subvendor = devinfo->codec->sc->pci_subvendor;
-
-	/*
-	 * Quirks
-	 */
-	for (i = 0; i < HDAC_QUIRKS_LEN; i++) {
-		if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subvendor) &&
-		    HDA_DEV_MATCH(hdac_quirks[i].id, id)))
-			continue;
-		if (hdac_quirks[i].set != 0)
-			devinfo->function.audio.quirks |=
-			    hdac_quirks[i].set;
-		if (hdac_quirks[i].unset != 0)
-			devinfo->function.audio.quirks &=
-			    ~(hdac_quirks[i].unset);
-	}
-
-	switch (id) {
-	case HDA_CODEC_AD1983:
-		/*
-		 * This codec has several possible usages, but none
-		 * fit the parser best. Help parser to choose better.
-		 */
-		/* Disable direct unmixed playback to get pcm volume. */
-		w = hdac_widget_get(devinfo, 5);
-		if (w != NULL)
-			w->connsenable[0] = 0;
-		w = hdac_widget_get(devinfo, 6);
-		if (w != NULL)
-			w->connsenable[0] = 0;
-		w = hdac_widget_get(devinfo, 11);
-		if (w != NULL)
-			w->connsenable[0] = 0;
-		/* Disable mic and line selectors. */
-		w = hdac_widget_get(devinfo, 12);
-		if (w != NULL)
-			w->connsenable[1] = 0;
-		w = hdac_widget_get(devinfo, 13);
-		if (w != NULL)
-			w->connsenable[1] = 0;
-		/* Disable recording from mono playback mix. */
-		w = hdac_widget_get(devinfo, 20);
-		if (w != NULL)
-			w->connsenable[3] = 0;
-		break;
-	case HDA_CODEC_AD1986A:
-		/*
-		 * This codec has overcomplicated input mixing.
-		 * Make some cleaning there.
-		 */
-		/* Disable input mono mixer. Not needed and not supported. */
-		w = hdac_widget_get(devinfo, 43);
-		if (w != NULL)
-			w->enable = 0;
-		/* Disable any with any input mixing mesh. Use separately. */
-		w = hdac_widget_get(devinfo, 39);
-		if (w != NULL)
-			w->enable = 0;
-		w = hdac_widget_get(devinfo, 40);
-		if (w != NULL)
-			w->enable = 0;
-		w = hdac_widget_get(devinfo, 41);
-		if (w != NULL)
-			w->enable = 0;
-		w = hdac_widget_get(devinfo, 42);
-		if (w != NULL)
-			w->enable = 0;
-		/* Disable duplicate mixer node connector. */
-		w = hdac_widget_get(devinfo, 15);
-		if (w != NULL)
-			w->connsenable[3] = 0;
-		/* There is only one mic preamplifier, use it effectively. */
-		w = hdac_widget_get(devinfo, 31);
-		if (w != NULL) {
-			if ((w->wclass.pin.config &
-			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
-			    HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
-				w = hdac_widget_get(devinfo, 16);
-				if (w != NULL)
-				    w->connsenable[2] = 0;
-			} else {
-				w = hdac_widget_get(devinfo, 15);
-				if (w != NULL)
-				    w->connsenable[0] = 0;
-			}
-		}
-		w = hdac_widget_get(devinfo, 32);
-		if (w != NULL) {
-			if ((w->wclass.pin.config &
-			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
-			    HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
-				w = hdac_widget_get(devinfo, 16);
-				if (w != NULL)
-				    w->connsenable[0] = 0;
-			} else {
-				w = hdac_widget_get(devinfo, 15);
-				if (w != NULL)
-				    w->connsenable[1] = 0;
-			}
-		}
-
-		if (subvendor == ASUS_A8X_SUBVENDOR) {
-			/*
-			 * This is just plain ridiculous.. There
-			 * are several A8 series that share the same
-			 * pci id but works differently (EAPD).
-			 */
-			w = hdac_widget_get(devinfo, 26);
-			if (w != NULL && w->type ==
-			    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
-			    (w->wclass.pin.config &
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) !=
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE)
-				devinfo->function.audio.quirks &=
-				    ~HDA_QUIRK_EAPDINV;
-		}
-		break;
-	case HDA_CODEC_AD1981HD:
-		/*
-		 * This codec has very unusual design with several
-		 * points inappropriate for the present parser.
-		 */
-		/* Disable recording from mono playback mix. */
-		w = hdac_widget_get(devinfo, 21);
-		if (w != NULL)
-			w->connsenable[3] = 0;
-		/* Disable rear to front mic mixer, use separately. */
-		w = hdac_widget_get(devinfo, 31);
-		if (w != NULL)
-			w->enable = 0;
-		/* Disable direct playback, use mixer. */
-		w = hdac_widget_get(devinfo, 5);
-		if (w != NULL)
-			w->connsenable[0] = 0;
-		w = hdac_widget_get(devinfo, 6);
-		if (w != NULL)
-			w->connsenable[0] = 0;
-		w = hdac_widget_get(devinfo, 9);
-		if (w != NULL)
-			w->connsenable[0] = 0;
-		w = hdac_widget_get(devinfo, 24);
-		if (w != NULL)
-			w->connsenable[0] = 0;
-		break;
-	case HDA_CODEC_CX20582:
-	case HDA_CODEC_CX20583:
-	case HDA_CODEC_CX20584:
-	case HDA_CODEC_CX20585:
-	case HDA_CODEC_CX20590:
-		/*
-		 * These codecs have extra connectivity on record side
-		 * too reach for the present parser.
-		 */
-		w = hdac_widget_get(devinfo, 20);
-		if (w != NULL)
-			w->connsenable[1] = 0;
-		w = hdac_widget_get(devinfo, 21);
-		if (w != NULL)
-			w->connsenable[1] = 0;
-		w = hdac_widget_get(devinfo, 22);
-		if (w != NULL)
-			w->connsenable[0] = 0;
-		break;
-	case HDA_CODEC_VT1708S_0:
-	case HDA_CODEC_VT1708S_1:
-	case HDA_CODEC_VT1708S_2:
-	case HDA_CODEC_VT1708S_3:
-	case HDA_CODEC_VT1708S_4:
-	case HDA_CODEC_VT1708S_5:
-	case HDA_CODEC_VT1708S_6:
-	case HDA_CODEC_VT1708S_7:
-		/*
-		 * These codecs have hidden mic boost controls.
-		 */
-		w = hdac_widget_get(devinfo, 26);
-		if (w != NULL)
-			w->param.inamp_cap =
-			    (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
-			    (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
-			    (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
-		w = hdac_widget_get(devinfo, 30);
-		if (w != NULL)
-			w->param.inamp_cap =
-			    (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
-			    (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
-			    (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
-		break;
-	}
-}
-
-/*
- * Trace path from DAC to pin.
- */
-static nid_t
-hdac_audio_trace_dac(struct hdac_devinfo *devinfo, int as, int seq, nid_t nid,
-    int dupseq, int min, int only, int depth)
-{
-	struct hdac_widget *w;
-	int i, im = -1;
-	nid_t m = 0, ret;
-
-	if (depth > HDA_PARSE_MAXDEPTH)
-		return (0);
-	w = hdac_widget_get(devinfo, nid);
-	if (w == NULL || w->enable == 0)
-		return (0);
-	HDA_BOOTHVERBOSE(
-		if (!only) {
-			device_printf(devinfo->codec->sc->dev,
-			    " %*stracing via nid %d\n",
-				depth + 1, "", w->nid);
-		}
-	);
-	/* Use only unused widgets */
-	if (w->bindas >= 0 && w->bindas != as) {
-		HDA_BOOTHVERBOSE(
-			if (!only) {
-				device_printf(devinfo->codec->sc->dev,
-				    " %*snid %d busy by association %d\n",
-					depth + 1, "", w->nid, w->bindas);
-			}
-		);
-		return (0);
-	}
-	if (dupseq < 0) {
-		if (w->bindseqmask != 0) {
-			HDA_BOOTHVERBOSE(
-				if (!only) {
-					device_printf(devinfo->codec->sc->dev,
-					    " %*snid %d busy by seqmask %x\n",
-						depth + 1, "", w->nid, w->bindseqmask);
-				}
-			);
-			return (0);
-		}
-	} else {
-		/* If this is headphones - allow duplicate first pin. */
-		if (w->bindseqmask != 0 &&
-		    (w->bindseqmask & (1 << dupseq)) == 0) {
-			HDA_BOOTHVERBOSE(
-				device_printf(devinfo->codec->sc->dev,
-				    " %*snid %d busy by seqmask %x\n",
-					depth + 1, "", w->nid, w->bindseqmask);
-			);
-			return (0);
-		}
-	}
-		
-	switch (w->type) {
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT:
-		/* Do not traverse input. AD1988 has digital monitor
-		for which we are not ready. */
-		break;
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT:
-		/* If we are tracing HP take only dac of first pin. */
-		if ((only == 0 || only == w->nid) &&
-		    (w->nid >= min) && (dupseq < 0 || w->nid ==
-		    devinfo->function.audio.as[as].dacs[dupseq]))
-			m = w->nid;
-		break;
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
-		if (depth > 0)
-			break;
-		/* Fall */
-	default:
-		/* Find reachable DACs with smallest nid respecting constraints. */
-		for (i = 0; i < w->nconns; i++) {
-			if (w->connsenable[i] == 0)
-				continue;
-			if (w->selconn != -1 && w->selconn != i)
-				continue;
-			if ((ret = hdac_audio_trace_dac(devinfo, as, seq,
-			    w->conns[i], dupseq, min, only, depth + 1)) != 0) {
-				if (m == 0 || ret < m) {
-					m = ret;
-					im = i;
-				}
-				if (only || dupseq >= 0)
-					break;
-			}
-		}
-		if (m && only && ((w->nconns > 1 &&
-		    w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER) ||
-		    w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR))
-			w->selconn = im;
-		break;
-	}
-	if (m && only) {
-		w->bindas = as;
-		w->bindseqmask |= (1 << seq);
-	}
-	HDA_BOOTHVERBOSE(
-		if (!only) {
-			device_printf(devinfo->codec->sc->dev,
-			    " %*snid %d returned %d\n",
-				depth + 1, "", w->nid, m);
-		}
-	);
-	return (m);
-}
-
-/*
- * Trace path from widget to ADC.
- */
-static nid_t
-hdac_audio_trace_adc(struct hdac_devinfo *devinfo, int as, int seq, nid_t nid,
-    int only, int depth)
-{
-	struct hdac_widget *w, *wc;
-	int i, j;
-	nid_t res = 0;
-
-	if (depth > HDA_PARSE_MAXDEPTH)
-		return (0);
-	w = hdac_widget_get(devinfo, nid);
-	if (w == NULL || w->enable == 0)
-		return (0);
-	HDA_BOOTHVERBOSE(
-		device_printf(devinfo->codec->sc->dev,
-		    " %*stracing via nid %d\n",
-			depth + 1, "", w->nid);
-	);
-	/* Use only unused widgets */
-	if (w->bindas >= 0 && w->bindas != as) {
-		HDA_BOOTHVERBOSE(
-			device_printf(devinfo->codec->sc->dev,
-			    " %*snid %d busy by association %d\n",
-				depth + 1, "", w->nid, w->bindas);
-		);
-		return (0);
-	}
-		
-	switch (w->type) {
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT:
-		/* If we are tracing HP take only dac of first pin. */
-		if (only == w->nid)
-			res = 1;
-		break;
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
-		if (depth > 0)
-			break;
-		/* Fall */
-	default:
-		/* Try to find reachable ADCs with specified nid. */
-		for (j = devinfo->startnode; j < devinfo->endnode; j++) {
-			wc = hdac_widget_get(devinfo, j);
-			if (wc == NULL || wc->enable == 0)
-				continue;
-			for (i = 0; i < wc->nconns; i++) {
-				if (wc->connsenable[i] == 0)
-					continue;
-				if (wc->conns[i] != nid)
-					continue;
-				if (hdac_audio_trace_adc(devinfo, as, seq,
-				    j, only, depth + 1) != 0) {
-					res = 1;
-					if (((wc->nconns > 1 &&
-					    wc->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER) ||
-					    wc->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR) &&
-					    wc->selconn == -1)
-						wc->selconn = i;
-				}
-			}
-		}
-		break;
-	}
-	if (res) {
-		w->bindas = as;
-		w->bindseqmask |= (1 << seq);
-	}
-	HDA_BOOTHVERBOSE(
-		device_printf(devinfo->codec->sc->dev,
-		    " %*snid %d returned %d\n",
-			depth + 1, "", w->nid, res);
-	);
-	return (res);
-}
-
-/*
- * Erase trace path of the specified association.
- */
-static void
-hdac_audio_undo_trace(struct hdac_devinfo *devinfo, int as, int seq)
-{
-	struct hdac_widget *w;
-	int i;
-	
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->bindas == as) {
-			if (seq >= 0) {
-				w->bindseqmask &= ~(1 << seq);
-				if (w->bindseqmask == 0) {
-					w->bindas = -1;
-					w->selconn = -1;
-				}
-			} else {
-				w->bindas = -1;
-				w->bindseqmask = 0;
-				w->selconn = -1;
-			}
-		}
-	}
-}
-
-/*
- * Trace association path from DAC to output
- */
-static int
-hdac_audio_trace_as_out(struct hdac_devinfo *devinfo, int as, int seq)
-{
-	struct hdac_audio_as *ases = devinfo->function.audio.as;
-	int i, hpredir;
-	nid_t min, res;
-
-	/* Find next pin */
-	for (i = seq; i < 16 && ases[as].pins[i] == 0; i++)
-		;
-	/* Check if there is no any left. If so - we succeeded. */
-	if (i == 16)
-		return (1);
-	
-	hpredir = (i == 15 && ases[as].fakeredir == 0)?ases[as].hpredir:-1;
-	min = 0;
-	res = 0;
-	do {
-		HDA_BOOTHVERBOSE(
-			device_printf(devinfo->codec->sc->dev,
-			    " Tracing pin %d with min nid %d",
-			    ases[as].pins[i], min);
-			if (hpredir >= 0)
-				printf(" and hpredir %d", hpredir);
-			printf("\n");
-		);
-		/* Trace this pin taking min nid into account. */
-		res = hdac_audio_trace_dac(devinfo, as, i,
-		    ases[as].pins[i], hpredir, min, 0, 0);
-		if (res == 0) {
-			/* If we failed - return to previous and redo it. */
-			HDA_BOOTVERBOSE(
-				device_printf(devinfo->codec->sc->dev,
-				    " Unable to trace pin %d seq %d with min "
-				    "nid %d",
-				    ases[as].pins[i], i, min);
-				if (hpredir >= 0)
-					printf(" and hpredir %d", hpredir);
-				printf("\n");
-			);
-			return (0);
-		}
-		HDA_BOOTVERBOSE(
-			device_printf(devinfo->codec->sc->dev,
-			    " Pin %d traced to DAC %d",
-			    ases[as].pins[i], res);
-			if (hpredir >= 0)
-				printf(" and hpredir %d", hpredir);
-			if (ases[as].fakeredir)
-				printf(" with fake redirection");
-			printf("\n");
-		);
-		/* Trace again to mark the path */
-		hdac_audio_trace_dac(devinfo, as, i,
-		    ases[as].pins[i], hpredir, min, res, 0);
-		ases[as].dacs[i] = res;
-		/* We succeeded, so call next. */
-		if (hdac_audio_trace_as_out(devinfo, as, i + 1))
-			return (1);
-		/* If next failed, we should retry with next min */
-		hdac_audio_undo_trace(devinfo, as, i);
-		ases[as].dacs[i] = 0;
-		min = res + 1;
-	} while (1);
-}
-
-/*
- * Trace association path from input to ADC
- */
-static int
-hdac_audio_trace_as_in(struct hdac_devinfo *devinfo, int as)
-{
-	struct hdac_audio_as *ases = devinfo->function.audio.as;
-	struct hdac_widget *w;
-	int i, j, k;
-
-	for (j = devinfo->startnode; j < devinfo->endnode; j++) {
-		w = hdac_widget_get(devinfo, j);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT)
-			continue;
-		if (w->bindas >= 0 && w->bindas != as)
-			continue;
-
-		/* Find next pin */
-		for (i = 0; i < 16; i++) {
-			if (ases[as].pins[i] == 0)
-				continue;
-	
-			HDA_BOOTHVERBOSE(
-				device_printf(devinfo->codec->sc->dev,
-				    " Tracing pin %d to ADC %d\n",
-				    ases[as].pins[i], j);
-			);
-			/* Trace this pin taking goal into account. */
-			if (hdac_audio_trace_adc(devinfo, as, i,
-			    ases[as].pins[i], j, 0) == 0) {
-				/* If we failed - return to previous and redo it. */
-				HDA_BOOTVERBOSE(
-					device_printf(devinfo->codec->sc->dev,
-					    " Unable to trace pin %d to ADC %d, undo traces\n",
-					    ases[as].pins[i], j);
-				);
-				hdac_audio_undo_trace(devinfo, as, -1);
-				for (k = 0; k < 16; k++)
-					ases[as].dacs[k] = 0;
-				break;
-			}
-			HDA_BOOTVERBOSE(
-				device_printf(devinfo->codec->sc->dev,
-				    " Pin %d traced to ADC %d\n",
-				    ases[as].pins[i], j);
-			);
-			ases[as].dacs[i] = j;
-		}
-		if (i == 16)
-			return (1);
-	}
-	return (0);
-}
-
-/*
- * Trace input monitor path from mixer to output association.
- */
-static int
-hdac_audio_trace_to_out(struct hdac_devinfo *devinfo, nid_t nid, int depth)
-{
-	struct hdac_audio_as *ases = devinfo->function.audio.as;
-	struct hdac_widget *w, *wc;
-	int i, j;
-	nid_t res = 0;
-
-	if (depth > HDA_PARSE_MAXDEPTH)
-		return (0);
-	w = hdac_widget_get(devinfo, nid);
-	if (w == NULL || w->enable == 0)
-		return (0);
-	HDA_BOOTHVERBOSE(
-		device_printf(devinfo->codec->sc->dev,
-		    " %*stracing via nid %d\n",
-			depth + 1, "", w->nid);
-	);
-	/* Use only unused widgets */
-	if (depth > 0 && w->bindas != -1) {
-		if (w->bindas < 0 || ases[w->bindas].dir == HDA_CTL_OUT) {
-			HDA_BOOTHVERBOSE(
-				device_printf(devinfo->codec->sc->dev,
-				    " %*snid %d found output association %d\n",
-					depth + 1, "", w->nid, w->bindas);
-			);
-			if (w->bindas >= 0)
-				w->pflags |= HDA_ADC_MONITOR;
-			return (1);
-		} else {
-			HDA_BOOTHVERBOSE(
-				device_printf(devinfo->codec->sc->dev,
-				    " %*snid %d busy by input association %d\n",
-					depth + 1, "", w->nid, w->bindas);
-			);
-			return (0);
-		}
-	}
-		
-	switch (w->type) {
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT:
-		/* Do not traverse input. AD1988 has digital monitor
-		for which we are not ready. */
-		break;
-	case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
-		if (depth > 0)
-			break;
-		/* Fall */
-	default:
-		/* Try to find reachable ADCs with specified nid. */
-		for (j = devinfo->startnode; j < devinfo->endnode; j++) {
-			wc = hdac_widget_get(devinfo, j);
-			if (wc == NULL || wc->enable == 0)
-				continue;
-			for (i = 0; i < wc->nconns; i++) {
-				if (wc->connsenable[i] == 0)
-					continue;
-				if (wc->conns[i] != nid)
-					continue;
-				if (hdac_audio_trace_to_out(devinfo,
-				    j, depth + 1) != 0) {
-					res = 1;
-					if (wc->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR &&
-					    wc->selconn == -1)
-						wc->selconn = i;
-				}
-			}
-		}
-		break;
-	}
-	if (res && w->bindas == -1)
-		w->bindas = -2;
-
-	HDA_BOOTHVERBOSE(
-		device_printf(devinfo->codec->sc->dev,
-		    " %*snid %d returned %d\n",
-			depth + 1, "", w->nid, res);
-	);
-	return (res);
-}
-
-/*
- * Trace extra associations (beeper, monitor)
- */
-static void
-hdac_audio_trace_as_extra(struct hdac_devinfo *devinfo)
-{
-	struct hdac_audio_as *as = devinfo->function.audio.as;
-	struct hdac_widget *w;
-	int j;
-
-	/* Input monitor */
-	/* Find mixer associated with input, but supplying signal
-	   for output associations. Hope it will be input monitor. */
-	HDA_BOOTVERBOSE(
-		device_printf(devinfo->codec->sc->dev,
-		    "Tracing input monitor\n");
-	);
-	for (j = devinfo->startnode; j < devinfo->endnode; j++) {
-		w = hdac_widget_get(devinfo, j);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
-			continue;
-		if (w->bindas < 0 || as[w->bindas].dir != HDA_CTL_IN)
-			continue;
-		HDA_BOOTVERBOSE(
-			device_printf(devinfo->codec->sc->dev,
-			    " Tracing nid %d to out\n",
-			    j);
-		);
-		if (hdac_audio_trace_to_out(devinfo, w->nid, 0)) {
-			HDA_BOOTVERBOSE(
-				device_printf(devinfo->codec->sc->dev,
-				    " nid %d is input monitor\n",
-					w->nid);
-			);
-			w->ossdev = SOUND_MIXER_IMIX;
-		}
-	}
-
-	/* Other inputs monitor */
-	/* Find input pins supplying signal for output associations.
-	   Hope it will be input monitoring. */
-	HDA_BOOTVERBOSE(
-		device_printf(devinfo->codec->sc->dev,
-		    "Tracing other input monitors\n");
-	);
-	for (j = devinfo->startnode; j < devinfo->endnode; j++) {
-		w = hdac_widget_get(devinfo, j);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-			continue;
-		if (w->bindas < 0 || as[w->bindas].dir != HDA_CTL_IN)
-			continue;
-		HDA_BOOTVERBOSE(
-			device_printf(devinfo->codec->sc->dev,
-			    " Tracing nid %d to out\n",
-			    j);
-		);
-		if (hdac_audio_trace_to_out(devinfo, w->nid, 0)) {
-			HDA_BOOTVERBOSE(
-				device_printf(devinfo->codec->sc->dev,
-				    " nid %d is input monitor\n",
-					w->nid);
-			);
-		}
-	}
-
-	/* Beeper */
-	HDA_BOOTVERBOSE(
-		device_printf(devinfo->codec->sc->dev,
-		    "Tracing beeper\n");
-	);
-	for (j = devinfo->startnode; j < devinfo->endnode; j++) {
-		w = hdac_widget_get(devinfo, j);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET)
-			continue;
-		HDA_BOOTHVERBOSE(
-			device_printf(devinfo->codec->sc->dev,
-			    " Tracing nid %d to out\n",
-			    j);
-		);
-		if (hdac_audio_trace_to_out(devinfo, w->nid, 0)) {
-			HDA_BOOTVERBOSE(
-				device_printf(devinfo->codec->sc->dev,
-				    " nid %d traced to out\n",
-				    j);
-			);
-		}
-		w->bindas = -2;
-	}
-}
-
-/*
- * Bind assotiations to PCM channels
- */
-static void
-hdac_audio_bind_as(struct hdac_devinfo *devinfo)
-{
-	struct hdac_softc *sc = devinfo->codec->sc;
-	struct hdac_audio_as *as = devinfo->function.audio.as;
-	int j, cnt = 0, free;
-
-	for (j = 0; j < devinfo->function.audio.ascnt; j++) {
-		if (as[j].enable)
-			cnt++;
-	}
-	if (sc->num_chans == 0) {
-		sc->chans = (struct hdac_chan *)malloc(
-		    sizeof(struct hdac_chan) * cnt,
-		    M_HDAC, M_ZERO | M_NOWAIT);
-		if (sc->chans == NULL) {
-			device_printf(sc->dev,
-			    "Channels memory allocation failed!\n");
-			return;
-		}
-	} else {
-		sc->chans = (struct hdac_chan *)realloc(sc->chans, 
-		    sizeof(struct hdac_chan) * (sc->num_chans + cnt),
-		    M_HDAC, M_ZERO | M_NOWAIT);
-		if (sc->chans == NULL) {
-			sc->num_chans = 0;
-			device_printf(sc->dev,
-			    "Channels memory allocation failed!\n");
-			return;
-		}
-		/* Fixup relative pointers after realloc */
-		for (j = 0; j < sc->num_chans; j++)
-			sc->chans[j].caps.fmtlist = sc->chans[j].fmtlist;
-	}
-	free = sc->num_chans;
-	sc->num_chans += cnt;
-
-	for (j = free; j < free + cnt; j++) {
-		sc->chans[j].devinfo = devinfo;
-		sc->chans[j].as = -1;
-	}
-
-	/* Assign associations in order of their numbers, */
-	for (j = 0; j < devinfo->function.audio.ascnt; j++) {
-		if (as[j].enable == 0)
-			continue;
-		
-		as[j].chan = free;
-		sc->chans[free].as = j;
-		sc->chans[free].dir =
-		    (as[j].dir == HDA_CTL_IN) ? PCMDIR_REC : PCMDIR_PLAY;
-		hdac_pcmchannel_setup(&sc->chans[free]);
-		free++;
-	}
-}
-
-static void
-hdac_audio_disable_nonaudio(struct hdac_devinfo *devinfo)
-{
-	struct hdac_widget *w;
-	int i;
-
-	/* Disable power and volume widgets. */
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_POWER_WIDGET ||
-		    w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VOLUME_WIDGET) {
-			w->enable = 0;
-			HDA_BOOTHVERBOSE(
-				device_printf(devinfo->codec->sc->dev, 
-				    " Disabling nid %d due to it's"
-				    " non-audio type.\n",
-				    w->nid);
-			);
-		}
-	}
-}
-
-static void
-hdac_audio_disable_useless(struct hdac_devinfo *devinfo)
-{
-	struct hdac_widget *w, *cw;
-	struct hdac_audio_ctl *ctl;
-	int done, found, i, j, k;
-
-	/* Disable useless pins. */
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
-			if ((w->wclass.pin.config &
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) ==
-			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE) {
-				w->enable = 0;
-				HDA_BOOTHVERBOSE(
-					device_printf(devinfo->codec->sc->dev, 
-					    " Disabling pin nid %d due"
-					    " to None connectivity.\n",
-					    w->nid);
-				);
-			} else if ((w->wclass.pin.config &
-			    HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK) == 0) {
-				w->enable = 0;
-				HDA_BOOTHVERBOSE(
-					device_printf(devinfo->codec->sc->dev, 
-					    " Disabling unassociated"
-					    " pin nid %d.\n",
-					    w->nid);
-				);
-			}
-		}
-	}
-	do {
-		done = 1;
-		/* Disable and mute controls for disabled widgets. */
-		i = 0;
-		while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) {
-			if (ctl->enable == 0)
-				continue;
-			if (ctl->widget->enable == 0 ||
-			    (ctl->childwidget != NULL &&
-			    ctl->childwidget->enable == 0)) {
-				ctl->forcemute = 1;
-				ctl->muted = HDA_AMP_MUTE_ALL;
-				ctl->left = 0;
-				ctl->right = 0;
-				ctl->enable = 0;
-				if (ctl->ndir == HDA_CTL_IN)
-					ctl->widget->connsenable[ctl->index] = 0;
-				done = 0;
-				HDA_BOOTHVERBOSE(
-					device_printf(devinfo->codec->sc->dev, 
-					    " Disabling ctl %d nid %d cnid %d due"
-					    " to disabled widget.\n", i,
-					    ctl->widget->nid,
-					    (ctl->childwidget != NULL)?
-					    ctl->childwidget->nid:-1);
-				);
-			}
-		}
-		/* Disable useless widgets. */
-		for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-			w = hdac_widget_get(devinfo, i);
-			if (w == NULL || w->enable == 0)
-				continue;
-			/* Disable inputs with disabled child widgets. */
-			for (j = 0; j < w->nconns; j++) {
-				if (w->connsenable[j]) {
-					cw = hdac_widget_get(devinfo, w->conns[j]);
-					if (cw == NULL || cw->enable == 0) {
-						w->connsenable[j] = 0;
-						HDA_BOOTHVERBOSE(
-							device_printf(devinfo->codec->sc->dev, 
-							    " Disabling nid %d connection %d due"
-							    " to disabled child widget.\n",
-							    i, j);
-						);
-					}
-				}
-			}
-			if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR &&
-			    w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
-				continue;
-			/* Disable mixers and selectors without inputs. */
-			found = 0;
-			for (j = 0; j < w->nconns; j++) {
-				if (w->connsenable[j]) {
-					found = 1;
-					break;
-				}
-			}
-			if (found == 0) {
-				w->enable = 0;
-				done = 0;
-				HDA_BOOTHVERBOSE(
-					device_printf(devinfo->codec->sc->dev, 
-					    " Disabling nid %d due to all it's"
-					    " inputs disabled.\n", w->nid);
-				);
-			}
-			/* Disable nodes without consumers. */
-			if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR &&
-			    w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
-				continue;
-			found = 0;
-			for (k = devinfo->startnode; k < devinfo->endnode; k++) {
-				cw = hdac_widget_get(devinfo, k);
-				if (cw == NULL || cw->enable == 0)
-					continue;
-				for (j = 0; j < cw->nconns; j++) {
-					if (cw->connsenable[j] && cw->conns[j] == i) {
-						found = 1;
-						break;
-					}
-				}
-			}
-			if (found == 0) {
-				w->enable = 0;
-				done = 0;
-				HDA_BOOTHVERBOSE(
-					device_printf(devinfo->codec->sc->dev, 
-					    " Disabling nid %d due to all it's"
-					    " consumers disabled.\n", w->nid);
-				);
-			}
-		}
-	} while (done == 0);
-
-}
-
-static void
-hdac_audio_disable_unas(struct hdac_devinfo *devinfo)
-{
-	struct hdac_audio_as *as = devinfo->function.audio.as;
-	struct hdac_widget *w, *cw;
-	struct hdac_audio_ctl *ctl;
-	int i, j, k;
-
-	/* Disable unassosiated widgets. */
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->bindas == -1) {
-			w->enable = 0;
-			HDA_BOOTHVERBOSE(
-				device_printf(devinfo->codec->sc->dev, 
-				    " Disabling unassociated nid %d.\n",
-				    w->nid);
-			);
-		}
-	}
-	/* Disable input connections on input pin and
-	 * output on output. */
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-			continue;
-		if (w->bindas < 0)
-			continue;
-		if (as[w->bindas].dir == HDA_CTL_IN) {
-			for (j = 0; j < w->nconns; j++) {
-				if (w->connsenable[j] == 0)
-					continue;
-				w->connsenable[j] = 0;
-				HDA_BOOTHVERBOSE(
-					device_printf(devinfo->codec->sc->dev, 
-					    " Disabling connection to input pin "
-					    "nid %d conn %d.\n",
-					    i, j);
-				);
-			}
-			ctl = hdac_audio_ctl_amp_get(devinfo, w->nid,
-			    HDA_CTL_IN, -1, 1);
-			if (ctl && ctl->enable) {
-				ctl->forcemute = 1;
-				ctl->muted = HDA_AMP_MUTE_ALL;
-				ctl->left = 0;
-				ctl->right = 0;
-				ctl->enable = 0;
-			}
-		} else {
-			ctl = hdac_audio_ctl_amp_get(devinfo, w->nid,
-			    HDA_CTL_OUT, -1, 1);
-			if (ctl && ctl->enable) {
-				ctl->forcemute = 1;
-				ctl->muted = HDA_AMP_MUTE_ALL;
-				ctl->left = 0;
-				ctl->right = 0;
-				ctl->enable = 0;
-			}
-			for (k = devinfo->startnode; k < devinfo->endnode; k++) {
-				cw = hdac_widget_get(devinfo, k);
-				if (cw == NULL || cw->enable == 0)
-					continue;
-				for (j = 0; j < cw->nconns; j++) {
-					if (cw->connsenable[j] && cw->conns[j] == i) {
-						cw->connsenable[j] = 0;
-						HDA_BOOTHVERBOSE(
-							device_printf(devinfo->codec->sc->dev, 
-							    " Disabling connection from output pin "
-							    "nid %d conn %d cnid %d.\n",
-							    k, j, i);
-						);
-						if (cw->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
-						    cw->nconns > 1)
-							continue;
-						ctl = hdac_audio_ctl_amp_get(devinfo, k,
-		    				    HDA_CTL_IN, j, 1);
-						if (ctl && ctl->enable) {
-							ctl->forcemute = 1;
-							ctl->muted = HDA_AMP_MUTE_ALL;
-							ctl->left = 0;
-							ctl->right = 0;
-							ctl->enable = 0;
-						}
-					}
-				}
-			}
-		}
-	}
-}
-
-static void
-hdac_audio_disable_notselected(struct hdac_devinfo *devinfo)
-{
-	struct hdac_audio_as *as = devinfo->function.audio.as;
-	struct hdac_widget *w;
-	int i, j;
-
-	/* On playback path we can safely disable all unseleted inputs. */
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->nconns <= 1)
-			continue;
-		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
-			continue;
-		if (w->bindas < 0 || as[w->bindas].dir == HDA_CTL_IN)
-			continue;
-		for (j = 0; j < w->nconns; j++) {
-			if (w->connsenable[j] == 0)
-				continue;
-			if (w->selconn < 0 || w->selconn == j)
-				continue;
-			w->connsenable[j] = 0;
-			HDA_BOOTHVERBOSE(
-				device_printf(devinfo->codec->sc->dev, 
-				    " Disabling unselected connection "
-				    "nid %d conn %d.\n",
-				    i, j);
-			);
-		}
-	}
-}
-
-static void
-hdac_audio_disable_crossas(struct hdac_devinfo *devinfo)
-{
-	struct hdac_audio_as *ases = devinfo->function.audio.as;
-	struct hdac_widget *w, *cw;
-	struct hdac_audio_ctl *ctl;
-	int i, j;
-
-	/* Disable crossassociatement and unwanted crosschannel connections. */
-	/* ... using selectors */
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->nconns <= 1)
-			continue;
-		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
-			continue;
-		if (w->bindas == -2)
-			continue;
-		for (j = 0; j < w->nconns; j++) {
-			if (w->connsenable[j] == 0)
-				continue;
-			cw = hdac_widget_get(devinfo, w->conns[j]);
-			if (cw == NULL || w->enable == 0)
-				continue;
-			if (cw->bindas == -2 || 
-			    ((w->pflags & HDA_ADC_MONITOR) &&
-			     cw->bindas >= 0 &&
-			     ases[cw->bindas].dir == HDA_CTL_IN))
-				continue;
-			if (w->bindas == cw->bindas &&
-			    (w->bindseqmask & cw->bindseqmask) != 0)
-				continue;
-			w->connsenable[j] = 0;
-			HDA_BOOTHVERBOSE(
-				device_printf(devinfo->codec->sc->dev, 
-				    " Disabling crossassociatement connection "
-				    "nid %d conn %d cnid %d.\n",
-				    i, j, cw->nid);
-			);
-		}
-	}
-	/* ... using controls */
-	i = 0;
-	while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) {
-		if (ctl->enable == 0 || ctl->childwidget == NULL)
-			continue;
-		if (ctl->widget->bindas == -2) 
-			continue;
-		if (ctl->childwidget->bindas == -2 ||
-		    ((ctl->widget->pflags & HDA_ADC_MONITOR) &&
-		     ctl->childwidget->bindas >= 0 &&
-		     ases[ctl->childwidget->bindas].dir == HDA_CTL_IN))
-			continue;
-		if (ctl->widget->bindas != ctl->childwidget->bindas ||
-		    (ctl->widget->bindseqmask & ctl->childwidget->bindseqmask) == 0) {
-			ctl->forcemute = 1;
-			ctl->muted = HDA_AMP_MUTE_ALL;
-			ctl->left = 0;
-			ctl->right = 0;
-			ctl->enable = 0;
-			if (ctl->ndir == HDA_CTL_IN)
-				ctl->widget->connsenable[ctl->index] = 0;
-			HDA_BOOTHVERBOSE(
-				device_printf(devinfo->codec->sc->dev, 
-				    " Disabling crossassociatement connection "
-				    "ctl %d nid %d cnid %d.\n", i,
-				    ctl->widget->nid,
-				    ctl->childwidget->nid);
-			);
-		}
-	}
-
-}
-
-#define HDA_CTL_GIVE(ctl)	((ctl)->step?1:0)
-
-/*
- * Find controls to control amplification for source.
- */
-static int
-hdac_audio_ctl_source_amp(struct hdac_devinfo *devinfo, nid_t nid, int index,
-    int ossdev, int ctlable, int depth, int need)
-{
-	struct hdac_widget *w, *wc;
-	struct hdac_audio_ctl *ctl;
-	int i, j, conns = 0, rneed;
-	
-	if (depth > HDA_PARSE_MAXDEPTH)
-		return (need);
-
-	w = hdac_widget_get(devinfo, nid);
-	if (w == NULL || w->enable == 0)
-		return (need);
-
-	/* Count number of active inputs. */
-	if (depth > 0) {
-		for (j = 0; j < w->nconns; j++) {
-			if (w->connsenable[j])
-				conns++;
-		}
-	}
-
-	/* If this is not a first step - use input mixer.
-	   Pins have common input ctl so care must be taken. */
-	if (depth > 0 && ctlable && (conns == 1 ||
-	    w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)) {
-		ctl = hdac_audio_ctl_amp_get(devinfo, w->nid, HDA_CTL_IN,
-		    index, 1);
-		if (ctl) {
-			if (HDA_CTL_GIVE(ctl) & need)
-				ctl->ossmask |= (1 << ossdev);
-			else
-				ctl->possmask |= (1 << ossdev);
-			need &= ~HDA_CTL_GIVE(ctl);
-		}
-	}
-	
-	/* If widget has own ossdev - not traverse it.
-	   It will be traversed on it's own. */
-	if (w->ossdev >= 0 && depth > 0)
-		return (need);
-
-	/* We must not traverse pin */
-	if ((w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT ||
-	    w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) &&
-	    depth > 0)
-		return (need);
-	
-	/* record that this widget exports such signal, */
-	w->ossmask |= (1 << ossdev);
-
-	/* If signals mixed, we can't assign controls farther.
-	 * Ignore this on depth zero. Caller must knows why.
-	 * Ignore this for static selectors if this input selected.
-	 */
-	if (conns > 1)
-		ctlable = 0;
-
-	if (ctlable) {
-		ctl = hdac_audio_ctl_amp_get(devinfo, w->nid, HDA_CTL_OUT, -1, 1);
-		if (ctl) {
-			if (HDA_CTL_GIVE(ctl) & need)
-				ctl->ossmask |= (1 << ossdev);
-			else
-				ctl->possmask |= (1 << ossdev);
-			need &= ~HDA_CTL_GIVE(ctl);
-		}
-	}
-	
-	rneed = 0;
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		wc = hdac_widget_get(devinfo, i);
-		if (wc == NULL || wc->enable == 0)
-			continue;
-		for (j = 0; j < wc->nconns; j++) {
-			if (wc->connsenable[j] && wc->conns[j] == nid) {
-				rneed |= hdac_audio_ctl_source_amp(devinfo,
-				    wc->nid, j, ossdev, ctlable, depth + 1, need);
-			}
-		}
-	}
-	rneed &= need;
-	
-	return (rneed);
-}
-
-/*
- * Find controls to control amplification for destination.
- */
-static void
-hdac_audio_ctl_dest_amp(struct hdac_devinfo *devinfo, nid_t nid, int index,
-    int ossdev, int depth, int need)
-{
-	struct hdac_audio_as *as = devinfo->function.audio.as;
-	struct hdac_widget *w, *wc;
-	struct hdac_audio_ctl *ctl;
-	int i, j, consumers;
-	
-	if (depth > HDA_PARSE_MAXDEPTH)
-		return;
-
-	w = hdac_widget_get(devinfo, nid);
-	if (w == NULL || w->enable == 0)
-		return;
-
-	if (depth > 0) {
-		/* If this node produce output for several consumers,
-		   we can't touch it. */
-		consumers = 0;
-		for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-			wc = hdac_widget_get(devinfo, i);
-			if (wc == NULL || wc->enable == 0)
-				continue;
-			for (j = 0; j < wc->nconns; j++) {
-				if (wc->connsenable[j] && wc->conns[j] == nid)
-					consumers++;
-			}
-		}
-		/* The only exception is if real HP redirection is configured
-		   and this is a duplication point.
-		   XXX: Actually exception is not completely correct.
-		   XXX: Duplication point check is not perfect. */
-		if ((consumers == 2 && (w->bindas < 0 ||
-		    as[w->bindas].hpredir < 0 || as[w->bindas].fakeredir ||
-		    (w->bindseqmask & (1 << 15)) == 0)) ||
-		    consumers > 2)
-			return;
-
-		/* Else use it's output mixer. */
-		ctl = hdac_audio_ctl_amp_get(devinfo, w->nid,
-		    HDA_CTL_OUT, -1, 1);
-		if (ctl) {
-			if (HDA_CTL_GIVE(ctl) & need)
-				ctl->ossmask |= (1 << ossdev);
-			else
-				ctl->possmask |= (1 << ossdev);
-			need &= ~HDA_CTL_GIVE(ctl);
-		}
-	}
-	
-	/* We must not traverse pin */
-	if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
-	    depth > 0)
-		return;
-	
-	for (i = 0; i < w->nconns; i++) {
-		int tneed = need;
-		if (w->connsenable[i] == 0)
-			continue;
-		if (index >= 0 && i != index)
-			continue;
-		ctl = hdac_audio_ctl_amp_get(devinfo, w->nid,
-		    HDA_CTL_IN, i, 1);
-		if (ctl) {
-			if (HDA_CTL_GIVE(ctl) & tneed)
-				ctl->ossmask |= (1 << ossdev);
-			else
-				ctl->possmask |= (1 << ossdev);
-			tneed &= ~HDA_CTL_GIVE(ctl);
-		}
-		hdac_audio_ctl_dest_amp(devinfo, w->conns[i], -1, ossdev,
-		    depth + 1, tneed);
-	}
-}
-
-/*
- * Assign OSS names to sound sources
- */
-static void
-hdac_audio_assign_names(struct hdac_devinfo *devinfo)
-{
-	struct hdac_audio_as *as = devinfo->function.audio.as;
-	struct hdac_widget *w;
-	int i, j;
-	int type = -1, use, used = 0;
-	static const int types[7][13] = {
-	    { SOUND_MIXER_LINE, SOUND_MIXER_LINE1, SOUND_MIXER_LINE2, 
-	      SOUND_MIXER_LINE3, -1 },	/* line */
-	    { SOUND_MIXER_MONITOR, SOUND_MIXER_MIC, -1 }, /* int mic */
-	    { SOUND_MIXER_MIC, SOUND_MIXER_MONITOR, -1 }, /* ext mic */
-	    { SOUND_MIXER_CD, -1 },	/* cd */
-	    { SOUND_MIXER_SPEAKER, -1 },	/* speaker */
-	    { SOUND_MIXER_DIGITAL1, SOUND_MIXER_DIGITAL2, SOUND_MIXER_DIGITAL3,
-	      -1 },	/* digital */
-	    { SOUND_MIXER_LINE, SOUND_MIXER_LINE1, SOUND_MIXER_LINE2,
-	      SOUND_MIXER_LINE3, SOUND_MIXER_PHONEIN, SOUND_MIXER_PHONEOUT,
-	      SOUND_MIXER_VIDEO, SOUND_MIXER_RADIO, SOUND_MIXER_DIGITAL1,
-	      SOUND_MIXER_DIGITAL2, SOUND_MIXER_DIGITAL3, SOUND_MIXER_MONITOR,
-	      -1 }	/* others */
-	};
-
-	/* Surely known names */
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->bindas == -1)
-			continue;
-		use = -1;
-		switch (w->type) {
-		case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
-			if (as[w->bindas].dir == HDA_CTL_OUT)
-				break;
-			type = -1;
-			switch (w->wclass.pin.config & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) {
-			case HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN:
-				type = 0;
-				break;
-			case HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN:
-				if ((w->wclass.pin.config & HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK)
-				    == HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK)
-					break;
-				type = 1;
-				break;
-			case HDA_CONFIG_DEFAULTCONF_DEVICE_CD:
-				type = 3;
-				break;
-			case HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER:
-				type = 4;
-				break;
-			case HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_IN:
-			case HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_IN:
-				type = 5;
-				break;
-			}
-			if (type == -1)
-				break;
-			j = 0;
-			while (types[type][j] >= 0 &&
-			    (used & (1 << types[type][j])) != 0) {
-				j++;
-			}
-			if (types[type][j] >= 0)
-				use = types[type][j];
-			break;
-		case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT:
-			use = SOUND_MIXER_PCM;
-			break;
-		case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET:
-			use = SOUND_MIXER_SPEAKER;
-			break;
-		default:
-			break;
-		}
-		if (use >= 0) {
-			w->ossdev = use;
-			used |= (1 << use);
-		}
-	}
-	/* Semi-known names */
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->ossdev >= 0)
-			continue;
-		if (w->bindas == -1)
-			continue;
-		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-			continue;
-		if (as[w->bindas].dir == HDA_CTL_OUT)
-			continue;
-		type = -1;
-		switch (w->wclass.pin.config & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) {
-		case HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT:
-		case HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER:
-		case HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT:
-		case HDA_CONFIG_DEFAULTCONF_DEVICE_AUX:
-			type = 0;
-			break;
-		case HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN:
-			type = 2;
-			break;
-		case HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_OUT:
-		case HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_OUT:
-			type = 5;
-			break;
-		}
-		if (type == -1)
-			break;
-		j = 0;
-		while (types[type][j] >= 0 &&
-		    (used & (1 << types[type][j])) != 0) {
-			j++;
-		}
-		if (types[type][j] >= 0) {
-			w->ossdev = types[type][j];
-			used |= (1 << types[type][j]);
-		}
-	}
-	/* Others */
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->ossdev >= 0)
-			continue;
-		if (w->bindas == -1)
-			continue;
-		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-			continue;
-		if (as[w->bindas].dir == HDA_CTL_OUT)
-			continue;
-		j = 0;
-		while (types[6][j] >= 0 &&
-		    (used & (1 << types[6][j])) != 0) {
-			j++;
-		}
-		if (types[6][j] >= 0) {
-			w->ossdev = types[6][j];
-			used |= (1 << types[6][j]);
-		}
-	}
-}
-
-static void
-hdac_audio_build_tree(struct hdac_devinfo *devinfo)
-{
-	struct hdac_audio_as *as = devinfo->function.audio.as;
-	int j, res;
-
-	/* Trace all associations in order of their numbers, */
-	for (j = 0; j < devinfo->function.audio.ascnt; j++) {
-		if (as[j].enable == 0)
-			continue;
-		HDA_BOOTVERBOSE(
-			device_printf(devinfo->codec->sc->dev,
-			    "Tracing association %d (%d)\n", j, as[j].index);
-		);
-		if (as[j].dir == HDA_CTL_OUT) {
-retry:
-			res = hdac_audio_trace_as_out(devinfo, j, 0);
-			if (res == 0 && as[j].hpredir >= 0 &&
-			    as[j].fakeredir == 0) {
-				/* If codec can't do analog HP redirection
-				   try to make it using one more DAC. */
-				as[j].fakeredir = 1;
-				goto retry;
-			}
-		} else {
-			res = hdac_audio_trace_as_in(devinfo, j);
-		}
-		if (res) {
-			HDA_BOOTVERBOSE(
-				device_printf(devinfo->codec->sc->dev,
-				    "Association %d (%d) trace succeeded\n",
-				    j, as[j].index);
-			);
-		} else {
-			HDA_BOOTVERBOSE(
-				device_printf(devinfo->codec->sc->dev,
-				    "Association %d (%d) trace failed\n",
-				    j, as[j].index);
-			);
-			as[j].enable = 0;
-		}
-	}
-
-	/* Trace mixer and beeper pseudo associations. */
-	hdac_audio_trace_as_extra(devinfo);
-}
-
-static void
-hdac_audio_assign_mixers(struct hdac_devinfo *devinfo)
-{
-	struct hdac_audio_as *as = devinfo->function.audio.as;
-	struct hdac_audio_ctl *ctl;
-	struct hdac_widget *w, *cw;
-	int i, j;
-
-	/* Assign mixers to the tree. */
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT ||
-		    w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET ||
-		    (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
-		    as[w->bindas].dir == HDA_CTL_IN)) {
-			if (w->ossdev < 0)
-				continue;
-			hdac_audio_ctl_source_amp(devinfo, w->nid, -1,
-			    w->ossdev, 1, 0, 1);
-		} else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) {
-			hdac_audio_ctl_dest_amp(devinfo, w->nid, -1,
-			    SOUND_MIXER_RECLEV, 0, 1);
-		} else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
-		    as[w->bindas].dir == HDA_CTL_OUT) {
-			hdac_audio_ctl_dest_amp(devinfo, w->nid, -1,
-			    SOUND_MIXER_VOLUME, 0, 1);
-		}
-		if (w->ossdev == SOUND_MIXER_IMIX) {
-			if (hdac_audio_ctl_source_amp(devinfo, w->nid, -1,
-			    w->ossdev, 1, 0, 1)) {
-				/* If we are unable to control input monitor
-				   as source - try to control it as destination. */
-				hdac_audio_ctl_dest_amp(devinfo, w->nid, -1,
-				    w->ossdev, 0, 1);
-			}
-		}
-		if (w->pflags & HDA_ADC_MONITOR) {
-			for (j = 0; j < w->nconns; j++) {
-				if (!w->connsenable[j])
-				    continue;
-				cw = hdac_widget_get(devinfo, w->conns[j]);
-				if (cw == NULL || cw->enable == 0)
-				    continue;
-				if (cw->bindas == -1)
-				    continue;
-				if (cw->bindas >= 0 &&
-				    as[cw->bindas].dir != HDA_CTL_IN)
-					continue;
-				hdac_audio_ctl_dest_amp(devinfo,
-				    w->nid, j, SOUND_MIXER_IGAIN, 0, 1);
-			}
-		}
-	}
-	/* Treat unrequired as possible. */
-	i = 0;
-	while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) {
-		if (ctl->ossmask == 0)
-			ctl->ossmask = ctl->possmask;
-	}
-}
-
-static void
-hdac_audio_prepare_pin_ctrl(struct hdac_devinfo *devinfo)
-{
-	struct hdac_audio_as *as = devinfo->function.audio.as;
-	struct hdac_widget *w;
-	uint32_t pincap;
-	int i;
-
-	for (i = 0; i < devinfo->nodecnt; i++) {
-		w = &devinfo->widget[i];
-		if (w == NULL)
-			continue;
-		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-			continue;
-
-		pincap = w->wclass.pin.cap;
-
-		/* Disable everything. */
-		w->wclass.pin.ctrl &= ~(
-		    HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE |
-		    HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE |
-		    HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE |
-		    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK);
-
-		if (w->enable == 0 ||
-		    w->bindas < 0 || as[w->bindas].enable == 0) {
-			/* Pin is unused so left it disabled. */
-			continue;
-		} else if (as[w->bindas].dir == HDA_CTL_IN) {
-			/* Input pin, configure for input. */
-			if (HDA_PARAM_PIN_CAP_INPUT_CAP(pincap))
-				w->wclass.pin.ctrl |=
-				    HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE;
-
-			if ((devinfo->function.audio.quirks & HDA_QUIRK_IVREF100) &&
-			    HDA_PARAM_PIN_CAP_VREF_CTRL_100(pincap))
-				w->wclass.pin.ctrl |=
-				    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
-				    HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_100);
-			else if ((devinfo->function.audio.quirks & HDA_QUIRK_IVREF80) &&
-			    HDA_PARAM_PIN_CAP_VREF_CTRL_80(pincap))
-				w->wclass.pin.ctrl |=
-				    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
-				    HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_80);
-			else if ((devinfo->function.audio.quirks & HDA_QUIRK_IVREF50) &&
-			    HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap))
-				w->wclass.pin.ctrl |=
-				    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
-				    HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_50);
-		} else {
-			/* Output pin, configure for output. */
-			if (HDA_PARAM_PIN_CAP_OUTPUT_CAP(pincap))
-				w->wclass.pin.ctrl |=
-				    HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE;
-
-			if (HDA_PARAM_PIN_CAP_HEADPHONE_CAP(pincap) &&
-			    (w->wclass.pin.config &
-			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
-			    HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT)
-				w->wclass.pin.ctrl |=
-				    HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE;
-
-			if ((devinfo->function.audio.quirks & HDA_QUIRK_OVREF100) &&
-			    HDA_PARAM_PIN_CAP_VREF_CTRL_100(pincap))
-				w->wclass.pin.ctrl |=
-				    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
-				    HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_100);
-			else if ((devinfo->function.audio.quirks & HDA_QUIRK_OVREF80) &&
-			    HDA_PARAM_PIN_CAP_VREF_CTRL_80(pincap))
-				w->wclass.pin.ctrl |=
-				    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
-				    HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_80);
-			else if ((devinfo->function.audio.quirks & HDA_QUIRK_OVREF50) &&
-			    HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap))
-				w->wclass.pin.ctrl |=
-				    HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(
-				    HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_50);
-		}
-	}
-}
-
-static void
-hdac_audio_ctl_commit(struct hdac_devinfo *devinfo)
-{
-	struct hdac_audio_ctl *ctl;
-	int i, z;
-
-	i = 0;
-	while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) {
-		if (ctl->enable == 0 || ctl->ossmask != 0) {
-			/* Mute disabled and mixer controllable controls.
-			 * Last will be initialized by mixer_init().
-			 * This expected to reduce click on startup. */
-			hdac_audio_ctl_amp_set(ctl, HDA_AMP_MUTE_ALL, 0, 0);
-			continue;
-		}
-		/* Init fixed controls to 0dB amplification. */
-		z = ctl->offset;
-		if (z > ctl->step)
-			z = ctl->step;
-		hdac_audio_ctl_amp_set(ctl, HDA_AMP_MUTE_NONE, z, z);
-	}
-}
-
-static void
-hdac_audio_commit(struct hdac_devinfo *devinfo)
-{
-	struct hdac_softc *sc = devinfo->codec->sc;
-	struct hdac_widget *w;
-	nid_t cad;
-	uint32_t id, gdata, gmask, gdir;
-	int commitgpio, numgpio;
-	int i;
-
-	cad = devinfo->codec->cad;
-
-	if (sc->pci_subvendor == APPLE_INTEL_MAC)
-		hdac_command(sc, HDA_CMD_12BIT(cad, devinfo->nid,
-		    0x7e7, 0), cad);
-	id = hdac_codec_id(devinfo->codec);
-	switch (id) {
-	case HDA_CODEC_VT1708S_0:
-	case HDA_CODEC_VT1708S_1:
-	case HDA_CODEC_VT1708S_2:
-	case HDA_CODEC_VT1708S_3:
-	case HDA_CODEC_VT1708S_4:
-	case HDA_CODEC_VT1708S_5:
-	case HDA_CODEC_VT1708S_6:
-	case HDA_CODEC_VT1708S_7:
-		/* Enable Mic Boost Volume controls. */
-		hdac_command(sc, HDA_CMD_12BIT(cad, devinfo->nid,
-		    0xf98, 0x01), cad);
-		/* Don't bypass mixer. */
-		hdac_command(sc, HDA_CMD_12BIT(cad, devinfo->nid,
-		    0xf88, 0xc0), cad);
-		break;
-	}
-
-	/* Commit controls. */
-	hdac_audio_ctl_commit(devinfo);
-	
-	/* Commit selectors, pins and EAPD. */
-	for (i = 0; i < devinfo->nodecnt; i++) {
-		w = &devinfo->widget[i];
-		if (w == NULL)
-			continue;
-		if (w->selconn == -1)
-			w->selconn = 0;
-		if (w->nconns > 0)
-			hdac_widget_connection_select(w, w->selconn);
-		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
-			hdac_command(sc,
-			    HDA_CMD_SET_PIN_WIDGET_CTRL(cad, w->nid,
-			    w->wclass.pin.ctrl), cad);
-		}
-		if (w->param.eapdbtl != HDAC_INVALID) {
-		    	uint32_t val;
-
-			val = w->param.eapdbtl;
-			if (devinfo->function.audio.quirks &
-			    HDA_QUIRK_EAPDINV)
-				val ^= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
-			hdac_command(sc,
-			    HDA_CMD_SET_EAPD_BTL_ENABLE(cad, w->nid,
-			    val), cad);
-		}
-	}
-
-	/* Commit GPIOs. */
-	gdata = 0;
-	gmask = 0;
-	gdir = 0;
-	commitgpio = 0;
-	numgpio = HDA_PARAM_GPIO_COUNT_NUM_GPIO(
-	    devinfo->function.audio.gpio);
-
-	if (devinfo->function.audio.quirks & HDA_QUIRK_GPIOFLUSH)
-		commitgpio = (numgpio > 0) ? 1 : 0;
-	else {
-		for (i = 0; i < numgpio && i < HDA_GPIO_MAX; i++) {
-			if (!(devinfo->function.audio.quirks &
-			    (1 << i)))
-				continue;
-			if (commitgpio == 0) {
-				commitgpio = 1;
-				HDA_BOOTVERBOSE(
-					gdata = hdac_command(sc,
-					    HDA_CMD_GET_GPIO_DATA(cad,
-					    devinfo->nid), cad);
-					gmask = hdac_command(sc,
-					    HDA_CMD_GET_GPIO_ENABLE_MASK(cad,
-					    devinfo->nid), cad);
-					gdir = hdac_command(sc,
-					    HDA_CMD_GET_GPIO_DIRECTION(cad,
-					    devinfo->nid), cad);
-					device_printf(sc->dev,
-					    "GPIO init: data=0x%08x "
-					    "mask=0x%08x dir=0x%08x\n",
-					    gdata, gmask, gdir);
-					gdata = 0;
-					gmask = 0;
-					gdir = 0;
-				);
-			}
-			gdata |= 1 << i;
-			gmask |= 1 << i;
-			gdir |= 1 << i;
-		}
-	}
-
-	if (commitgpio != 0) {
-		HDA_BOOTVERBOSE(
-			device_printf(sc->dev,
-			    "GPIO commit: data=0x%08x mask=0x%08x "
-			    "dir=0x%08x\n",
-			    gdata, gmask, gdir);
-		);
-		hdac_command(sc,
-		    HDA_CMD_SET_GPIO_ENABLE_MASK(cad, devinfo->nid,
-		    gmask), cad);
-		hdac_command(sc,
-		    HDA_CMD_SET_GPIO_DIRECTION(cad, devinfo->nid,
-		    gdir), cad);
-		hdac_command(sc,
-		    HDA_CMD_SET_GPIO_DATA(cad, devinfo->nid,
-		    gdata), cad);
-	}
-}
-
-static void
-hdac_powerup(struct hdac_devinfo *devinfo)
-{
-	struct hdac_softc *sc = devinfo->codec->sc;
-	nid_t cad = devinfo->codec->cad;
-	int i;
-
-	hdac_command(sc,
-	    HDA_CMD_SET_POWER_STATE(cad,
-	    devinfo->nid, HDA_CMD_POWER_STATE_D0),
-	    cad);
-	DELAY(100);
-
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		hdac_command(sc,
-		    HDA_CMD_SET_POWER_STATE(cad,
-		    i, HDA_CMD_POWER_STATE_D0),
-		    cad);
-	}
-	DELAY(1000);
-}
-
-static int
-hdac_pcmchannel_setup(struct hdac_chan *ch)
-{
-	struct hdac_devinfo *devinfo = ch->devinfo;
-	struct hdac_audio_as *as = devinfo->function.audio.as;
-	struct hdac_widget *w;
-	uint32_t cap, fmtcap, pcmcap;
-	int i, j, ret, channels, onlystereo;
-	uint16_t pinset;
-
-	ch->caps = hdac_caps;
-	ch->caps.fmtlist = ch->fmtlist;
-	ch->bit16 = 1;
-	ch->bit32 = 0;
-	ch->pcmrates[0] = 48000;
-	ch->pcmrates[1] = 0;
-
-	ret = 0;
-	channels = 0;
-	onlystereo = 1;
-	pinset = 0;
-	fmtcap = devinfo->function.audio.supp_stream_formats;
-	pcmcap = devinfo->function.audio.supp_pcm_size_rate;
-
-	for (i = 0; i < 16; i++) {
-		/* Check as is correct */
-		if (ch->as < 0)
-			break;
-		/* Cound only present DACs */
-		if (as[ch->as].dacs[i] <= 0)
-			continue;
-		/* Ignore duplicates */
-		for (j = 0; j < ret; j++) {
-			if (ch->io[j] == as[ch->as].dacs[i])
-				break;
-		}
-		if (j < ret)
-			continue;
-
-		w = hdac_widget_get(devinfo, as[ch->as].dacs[i]);
-		if (w == NULL || w->enable == 0)
-			continue;
-		cap = w->param.supp_stream_formats;
-		if (!HDA_PARAM_SUPP_STREAM_FORMATS_PCM(cap) &&
-		    !HDA_PARAM_SUPP_STREAM_FORMATS_AC3(cap))
-			continue;
-		/* Many CODECs does not declare AC3 support on SPDIF.
-		   I don't beleave that they doesn't support it! */
-		if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap))
-			cap |= HDA_PARAM_SUPP_STREAM_FORMATS_AC3_MASK;
-		if (ret == 0) {
-			fmtcap = cap;
-			pcmcap = w->param.supp_pcm_size_rate;
-		} else {
-			fmtcap &= cap;
-			pcmcap &= w->param.supp_pcm_size_rate;
-		}
-		ch->io[ret++] = as[ch->as].dacs[i];
-		/* Do not count redirection pin/dac channels. */
-		if (i == 15 && as[ch->as].hpredir >= 0)
-			continue;
-		channels += HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) + 1;
-		if (HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap) != 1)
-			onlystereo = 0;
-		pinset |= (1 << i);
-	}
-	ch->io[ret] = -1;
-
-	if (as[ch->as].fakeredir)
-		ret--;
-	/* Standard speaks only about stereo pins and playback, ... */
-	if ((!onlystereo) || as[ch->as].dir != HDA_CTL_OUT)
-		pinset = 0;
-	/* ..., but there it gives us info about speakers layout. */
-	as[ch->as].pinset = pinset;
-
-	ch->supp_stream_formats = fmtcap;
-	ch->supp_pcm_size_rate = pcmcap;
-
-	/*
-	 *  8bit = 0
-	 * 16bit = 1
-	 * 20bit = 2
-	 * 24bit = 3
-	 * 32bit = 4
-	 */
-	if (ret > 0) {
-		i = 0;
-		if (HDA_PARAM_SUPP_STREAM_FORMATS_PCM(fmtcap)) {
-			if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT(pcmcap))
-				ch->bit16 = 1;
-			else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT(pcmcap))
-				ch->bit16 = 0;
-			if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT(pcmcap))
-				ch->bit32 = 4;
-			else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT(pcmcap))
-				ch->bit32 = 3;
-			else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT(pcmcap))
-				ch->bit32 = 2;
-			if (!(devinfo->function.audio.quirks & HDA_QUIRK_FORCESTEREO)) {
-				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 1, 0);
-				if (ch->bit32)
-					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 1, 0);
-			}
-			if (channels >= 2) {
-				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 2, 0);
-				if (ch->bit32)
-					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 2, 0);
-			}
-			if (channels == 4 || /* Any 4-channel */
-			    pinset == 0x0007 || /* 5.1 */
-			    pinset == 0x0013 || /* 5.1 */
-			    pinset == 0x0017) {  /* 7.1 */
-				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 4, 0);
-				if (ch->bit32)
-					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 4, 0);
-			}
-			if (channels == 6 || /* Any 6-channel */
-			    pinset == 0x0017) {  /* 7.1 */
-				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 6, 1);
-				if (ch->bit32)
-					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 6, 1);
-			}
-			if (channels == 8) { /* Any 8-channel */
-				ch->fmtlist[i++] = SND_FORMAT(AFMT_S16_LE, 8, 1);
-				if (ch->bit32)
-					ch->fmtlist[i++] = SND_FORMAT(AFMT_S32_LE, 8, 1);
-			}
-		}
-		if (HDA_PARAM_SUPP_STREAM_FORMATS_AC3(fmtcap)) {
-			ch->fmtlist[i++] = SND_FORMAT(AFMT_AC3, 2, 0);
-		}
-		ch->fmtlist[i] = 0;
-		i = 0;
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ(pcmcap))
-			ch->pcmrates[i++] = 8000;
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ(pcmcap))
-			ch->pcmrates[i++] = 11025;
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ(pcmcap))
-			ch->pcmrates[i++] = 16000;
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ(pcmcap))
-			ch->pcmrates[i++] = 22050;
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ(pcmcap))
-			ch->pcmrates[i++] = 32000;
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ(pcmcap))
-			ch->pcmrates[i++] = 44100;
-		/* if (HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ(pcmcap)) */
-		ch->pcmrates[i++] = 48000;
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ(pcmcap))
-			ch->pcmrates[i++] = 88200;
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ(pcmcap))
-			ch->pcmrates[i++] = 96000;
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ(pcmcap))
-			ch->pcmrates[i++] = 176400;
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ(pcmcap))
-			ch->pcmrates[i++] = 192000;
-		/* if (HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ(pcmcap)) */
-		ch->pcmrates[i] = 0;
-		if (i > 0) {
-			ch->caps.minspeed = ch->pcmrates[0];
-			ch->caps.maxspeed = ch->pcmrates[i - 1];
-		}
-	}
-
-	return (ret);
-}
-
-static void
-hdac_create_pcms(struct hdac_devinfo *devinfo)
-{
-	struct hdac_softc *sc = devinfo->codec->sc;
-	struct hdac_audio_as *as = devinfo->function.audio.as;
-	int i, j, apdev = 0, ardev = 0, dpdev = 0, drdev = 0;
-
-	for (i = 0; i < devinfo->function.audio.ascnt; i++) {
-		if (as[i].enable == 0)
-			continue;
-		if (as[i].dir == HDA_CTL_IN) {
-			if (as[i].digital)
-				drdev++;
-			else
-				ardev++;
-		} else {
-			if (as[i].digital)
-				dpdev++;
-			else
-				apdev++;
-		}
-	}
-	devinfo->function.audio.num_devs =
-	    max(ardev, apdev) + max(drdev, dpdev);
-	devinfo->function.audio.devs =
-	    (struct hdac_pcm_devinfo *)malloc(
-	    devinfo->function.audio.num_devs * sizeof(struct hdac_pcm_devinfo),
-	    M_HDAC, M_ZERO | M_NOWAIT);
-	if (devinfo->function.audio.devs == NULL) {
-		device_printf(sc->dev,
-		    "Unable to allocate memory for devices\n");
-		return;
-	}
-	for (i = 0; i < devinfo->function.audio.num_devs; i++) {
-		devinfo->function.audio.devs[i].index = i;
-		devinfo->function.audio.devs[i].devinfo = devinfo;
-		devinfo->function.audio.devs[i].play = -1;
-		devinfo->function.audio.devs[i].rec = -1;
-		devinfo->function.audio.devs[i].digital = 255;
-	}
-	for (i = 0; i < devinfo->function.audio.ascnt; i++) {
-		if (as[i].enable == 0)
-			continue;
-		for (j = 0; j < devinfo->function.audio.num_devs; j++) {
-			if (devinfo->function.audio.devs[j].digital != 255 &&
-			    (!devinfo->function.audio.devs[j].digital) !=
-			    (!as[i].digital))
-				continue;
-			if (as[i].dir == HDA_CTL_IN) {
-				if (devinfo->function.audio.devs[j].rec >= 0)
-					continue;
-				devinfo->function.audio.devs[j].rec
-				    = as[i].chan;
-			} else {
-				if (devinfo->function.audio.devs[j].play >= 0)
-					continue;
-				devinfo->function.audio.devs[j].play
-				    = as[i].chan;
-			}
-			sc->chans[as[i].chan].pdevinfo =
-			    &devinfo->function.audio.devs[j];
-			devinfo->function.audio.devs[j].digital =
-			    as[i].digital;
-			break;
-		}
-	}
-	for (i = 0; i < devinfo->function.audio.num_devs; i++) {
-		struct hdac_pcm_devinfo *pdevinfo = 
-		    &devinfo->function.audio.devs[i];
-		pdevinfo->dev =
-		    device_add_child(sc->dev, "pcm", -1);
-		device_set_ivars(pdevinfo->dev,
-		     (void *)pdevinfo);
-	}
-}
-
-static void
-hdac_dump_ctls(struct hdac_pcm_devinfo *pdevinfo, const char *banner, uint32_t flag)
-{
-	struct hdac_devinfo *devinfo = pdevinfo->devinfo;
-	struct hdac_audio_ctl *ctl;
-	struct hdac_softc *sc = devinfo->codec->sc;
-	char buf[64];
-	int i, j, printed;
-
-	if (flag == 0) {
-		flag = ~(SOUND_MASK_VOLUME | SOUND_MASK_PCM |
-		    SOUND_MASK_CD | SOUND_MASK_LINE | SOUND_MASK_RECLEV |
-		    SOUND_MASK_MIC | SOUND_MASK_SPEAKER | SOUND_MASK_IGAIN |
-		    SOUND_MASK_OGAIN | SOUND_MASK_IMIX | SOUND_MASK_MONITOR);
-	}
-
-	for (j = 0; j < SOUND_MIXER_NRDEVICES; j++) {
-		if ((flag & (1 << j)) == 0)
-			continue;
-		i = 0;
-		printed = 0;
-		while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) {
-			if (ctl->enable == 0 ||
-			    ctl->widget->enable == 0)
-				continue;
-			if (!((pdevinfo->play >= 0 &&
-			    ctl->widget->bindas == sc->chans[pdevinfo->play].as) ||
-			    (pdevinfo->rec >= 0 &&
-			    ctl->widget->bindas == sc->chans[pdevinfo->rec].as) ||
-			    (ctl->widget->bindas == -2 && pdevinfo->index == 0)))
-				continue;
-			if ((ctl->ossmask & (1 << j)) == 0)
-				continue;
-
-	    		if (printed == 0) {
-				device_printf(pdevinfo->dev, "\n");
-				if (banner != NULL) {
-					device_printf(pdevinfo->dev, "%s", banner);
-				} else {
-					device_printf(pdevinfo->dev, "Unknown Ctl");
-				}
-				printf(" (OSS: %s)\n",
-				    hdac_audio_ctl_ossmixer_mask2allname(1 << j,
-				    buf, sizeof(buf)));
-				device_printf(pdevinfo->dev, "   |\n");
-				printed = 1;
-			}
-			device_printf(pdevinfo->dev, "   +- ctl %2d (nid %3d %s", i,
-				ctl->widget->nid,
-				(ctl->ndir == HDA_CTL_IN)?"in ":"out");
-			if (ctl->ndir == HDA_CTL_IN && ctl->ndir == ctl->dir)
-				printf(" %2d): ", ctl->index);
-			else
-				printf("):    ");
-			if (ctl->step > 0) {
-				printf("%+d/%+ddB (%d steps)%s\n",
-			    	    (0 - ctl->offset) * (ctl->size + 1) / 4,
-				    (ctl->step - ctl->offset) * (ctl->size + 1) / 4,
-				    ctl->step + 1,
-				    ctl->mute?" + mute":"");
-			} else
-				printf("%s\n", ctl->mute?"mute":"");
-		}
-	}
-}
-
-static void
-hdac_dump_audio_formats(device_t dev, uint32_t fcap, uint32_t pcmcap)
-{
-	uint32_t cap;
-
-	cap = fcap;
-	if (cap != 0) {
-		device_printf(dev, "     Stream cap: 0x%08x\n", cap);
-		device_printf(dev, "                ");
-		if (HDA_PARAM_SUPP_STREAM_FORMATS_AC3(cap))
-			printf(" AC3");
-		if (HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32(cap))
-			printf(" FLOAT32");
-		if (HDA_PARAM_SUPP_STREAM_FORMATS_PCM(cap))
-			printf(" PCM");
-		printf("\n");
-	}
-	cap = pcmcap;
-	if (cap != 0) {
-		device_printf(dev, "        PCM cap: 0x%08x\n", cap);
-		device_printf(dev, "                ");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT(cap))
-			printf(" 8");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT(cap))
-			printf(" 16");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT(cap))
-			printf(" 20");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT(cap))
-			printf(" 24");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT(cap))
-			printf(" 32");
-		printf(" bits,");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ(cap))
-			printf(" 8");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ(cap))
-			printf(" 11");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ(cap))
-			printf(" 16");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ(cap))
-			printf(" 22");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ(cap))
-			printf(" 32");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ(cap))
-			printf(" 44");
-		printf(" 48");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ(cap))
-			printf(" 88");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ(cap))
-			printf(" 96");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ(cap))
-			printf(" 176");
-		if (HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ(cap))
-			printf(" 192");
-		printf(" KHz\n");
-	}
-}
-
-static void
-hdac_dump_pin(struct hdac_softc *sc, struct hdac_widget *w)
-{
-	uint32_t pincap;
-
-	pincap = w->wclass.pin.cap;
-
-	device_printf(sc->dev, "        Pin cap: 0x%08x\n", pincap);
-	device_printf(sc->dev, "                ");
-	if (HDA_PARAM_PIN_CAP_IMP_SENSE_CAP(pincap))
-		printf(" ISC");
-	if (HDA_PARAM_PIN_CAP_TRIGGER_REQD(pincap))
-		printf(" TRQD");
-	if (HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(pincap))
-		printf(" PDC");
-	if (HDA_PARAM_PIN_CAP_HEADPHONE_CAP(pincap))
-		printf(" HP");
-	if (HDA_PARAM_PIN_CAP_OUTPUT_CAP(pincap))
-		printf(" OUT");
-	if (HDA_PARAM_PIN_CAP_INPUT_CAP(pincap))
-		printf(" IN");
-	if (HDA_PARAM_PIN_CAP_BALANCED_IO_PINS(pincap))
-		printf(" BAL");
-	if (HDA_PARAM_PIN_CAP_HDMI(pincap))
-		printf(" HDMI");
-	if (HDA_PARAM_PIN_CAP_VREF_CTRL(pincap)) {
-		printf(" VREF[");
-		if (HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap))
-			printf(" 50");
-		if (HDA_PARAM_PIN_CAP_VREF_CTRL_80(pincap))
-			printf(" 80");
-		if (HDA_PARAM_PIN_CAP_VREF_CTRL_100(pincap))
-			printf(" 100");
-		if (HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND(pincap))
-			printf(" GROUND");
-		if (HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ(pincap))
-			printf(" HIZ");
-		printf(" ]");
-	}
-	if (HDA_PARAM_PIN_CAP_EAPD_CAP(pincap))
-		printf(" EAPD");
-	if (HDA_PARAM_PIN_CAP_DP(pincap))
-		printf(" DP");
-	if (HDA_PARAM_PIN_CAP_HBR(pincap))
-		printf(" HBR");
-	printf("\n");
-	device_printf(sc->dev, "     Pin config: 0x%08x\n",
-	    w->wclass.pin.config);
-	device_printf(sc->dev, "    Pin control: 0x%08x", w->wclass.pin.ctrl);
-	if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE)
-		printf(" HP");
-	if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE)
-		printf(" IN");
-	if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE)
-		printf(" OUT");
-	if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK)
-		printf(" VREFs");
-	printf("\n");
-}
-
-static void
-hdac_dump_pin_config(struct hdac_widget *w, uint32_t conf)
-{
-	struct hdac_softc *sc = w->devinfo->codec->sc;
-
-	device_printf(sc->dev, " nid %d 0x%08x as %2d seq %2d %13s %5s "
-	    "jack %2d loc %2d color %7s misc %d%s\n",
-	    w->nid, conf,
-	    HDA_CONFIG_DEFAULTCONF_ASSOCIATION(conf),
-	    HDA_CONFIG_DEFAULTCONF_SEQUENCE(conf),
-	    HDA_DEVS[HDA_CONFIG_DEFAULTCONF_DEVICE(conf)],
-	    HDA_CONNS[HDA_CONFIG_DEFAULTCONF_CONNECTIVITY(conf)],
-	    HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE(conf),
-	    HDA_CONFIG_DEFAULTCONF_LOCATION(conf),
-	    HDA_COLORS[HDA_CONFIG_DEFAULTCONF_COLOR(conf)],
-	    HDA_CONFIG_DEFAULTCONF_MISC(conf),
-	    (w->enable == 0)?" [DISABLED]":"");
-}
-
-static void
-hdac_dump_pin_configs(struct hdac_devinfo *devinfo)
-{
-	struct hdac_widget *w;
-	int i;
-
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL)
-			continue;
-		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-			continue;
-		hdac_dump_pin_config(w, w->wclass.pin.config);
-	}
-}
-
-static void
-hdac_dump_amp(struct hdac_softc *sc, uint32_t cap, char *banner)
-{
-	device_printf(sc->dev, "     %s amp: 0x%08x\n", banner, cap);
-	device_printf(sc->dev, "                 "
-	    "mute=%d step=%d size=%d offset=%d\n",
-	    HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(cap),
-	    HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(cap),
-	    HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(cap),
-	    HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(cap));
-}
-
-static void
-hdac_dump_nodes(struct hdac_devinfo *devinfo)
-{
-	struct hdac_softc *sc = devinfo->codec->sc;
-	static char *ossname[] = SOUND_DEVICE_NAMES;
-	struct hdac_widget *w, *cw;
-	char buf[64];
-	int i, j;
-
-	device_printf(sc->dev, "\n");
-	device_printf(sc->dev, "Default Parameter\n");
-	device_printf(sc->dev, "-----------------\n");
-	hdac_dump_audio_formats(sc->dev,
-	    devinfo->function.audio.supp_stream_formats,
-	    devinfo->function.audio.supp_pcm_size_rate);
-	device_printf(sc->dev, "         IN amp: 0x%08x\n",
-	    devinfo->function.audio.inamp_cap);
-	device_printf(sc->dev, "        OUT amp: 0x%08x\n",
-	    devinfo->function.audio.outamp_cap);
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL) {
-			device_printf(sc->dev, "Ghost widget nid=%d\n", i);
-			continue;
-		}
-		device_printf(sc->dev, "\n");
-		device_printf(sc->dev, "            nid: %d%s\n", w->nid,
-		    (w->enable == 0) ? " [DISABLED]" : "");
-		device_printf(sc->dev, "           Name: %s\n", w->name);
-		device_printf(sc->dev, "     Widget cap: 0x%08x\n",
-		    w->param.widget_cap);
-		if (w->param.widget_cap & 0x0ee1) {
-			device_printf(sc->dev, "                ");
-			if (HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP(w->param.widget_cap))
-			    printf(" LRSWAP");
-			if (HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL(w->param.widget_cap))
-			    printf(" PWR");
-			if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap))
-			    printf(" DIGITAL");
-			if (HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP(w->param.widget_cap))
-			    printf(" UNSOL");
-			if (HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET(w->param.widget_cap))
-			    printf(" PROC");
-			if (HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE(w->param.widget_cap))
-			    printf(" STRIPE");
-			j = HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap);
-			if (j == 1)
-			    printf(" STEREO");
-			else if (j > 1)
-			    printf(" %dCH", j + 1);
-			printf("\n");
-		}
-		if (w->bindas != -1) {
-			device_printf(sc->dev, "    Association: %d (0x%08x)\n",
-			    w->bindas, w->bindseqmask);
-		}
-		if (w->ossmask != 0 || w->ossdev >= 0) {
-			device_printf(sc->dev, "            OSS: %s",
-			    hdac_audio_ctl_ossmixer_mask2allname(w->ossmask, buf, sizeof(buf)));
-			if (w->ossdev >= 0)
-			    printf(" (%s)", ossname[w->ossdev]);
-			printf("\n");
-		}
-		if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT ||
-		    w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) {
-			hdac_dump_audio_formats(sc->dev,
-			    w->param.supp_stream_formats,
-			    w->param.supp_pcm_size_rate);
-		} else if (w->type ==
-		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-			hdac_dump_pin(sc, w);
-		if (w->param.eapdbtl != HDAC_INVALID)
-			device_printf(sc->dev, "           EAPD: 0x%08x\n",
-			    w->param.eapdbtl);
-		if (HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP(w->param.widget_cap) &&
-		    w->param.outamp_cap != 0)
-			hdac_dump_amp(sc, w->param.outamp_cap, "Output");
-		if (HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP(w->param.widget_cap) &&
-		    w->param.inamp_cap != 0)
-			hdac_dump_amp(sc, w->param.inamp_cap, " Input");
-		if (w->nconns > 0) {
-			device_printf(sc->dev, "    connections: %d\n", w->nconns);
-			device_printf(sc->dev, "          |\n");
-		}
-		for (j = 0; j < w->nconns; j++) {
-			cw = hdac_widget_get(devinfo, w->conns[j]);
-			device_printf(sc->dev, "          + %s<- nid=%d [%s]",
-			    (w->connsenable[j] == 0)?"[DISABLED] ":"",
-			    w->conns[j], (cw == NULL) ? "GHOST!" : cw->name);
-			if (cw == NULL)
-				printf(" [UNKNOWN]");
-			else if (cw->enable == 0)
-				printf(" [DISABLED]");
-			if (w->nconns > 1 && w->selconn == j && w->type !=
-			    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)
-				printf(" (selected)");
-			printf("\n");
-		}
-	}
-
-}
-
-static void
-hdac_dump_dst_nid(struct hdac_pcm_devinfo *pdevinfo, nid_t nid, int depth)
-{
-	struct hdac_devinfo *devinfo = pdevinfo->devinfo;
-	struct hdac_widget *w, *cw;
-	char buf[64];
-	int i, printed = 0;
-
-	if (depth > HDA_PARSE_MAXDEPTH)
-		return;
-
-	w = hdac_widget_get(devinfo, nid);
-	if (w == NULL || w->enable == 0)
-		return;
-
-	if (depth == 0)
-		device_printf(pdevinfo->dev, "%*s", 4, "");
+	sc->poll_ival = min;
+	if (min == 1000000)
+		callout_stop(&sc->poll_callout);
 	else
-		device_printf(pdevinfo->dev, "%*s  + <- ", 4 + (depth - 1) * 7, "");
-	printf("nid=%d [%s]", w->nid, w->name);
-
-	if (depth > 0) {
-		if (w->ossmask == 0) {
-			printf("\n");
-			return;
-		}
-		printf(" [src: %s]", 
-		    hdac_audio_ctl_ossmixer_mask2allname(
-			w->ossmask, buf, sizeof(buf)));
-		if (w->ossdev >= 0) {
-			printf("\n");
-			return;
-		}
-	}
-	printf("\n");
-		
-	for (i = 0; i < w->nconns; i++) {
-		if (w->connsenable[i] == 0)
-			continue;
-		cw = hdac_widget_get(devinfo, w->conns[i]);
-		if (cw == NULL || cw->enable == 0 || cw->bindas == -1)
-			continue;
-		if (printed == 0) {
-			device_printf(pdevinfo->dev, "%*s  |\n", 4 + (depth) * 7, "");
-			printed = 1;
-		}
-		hdac_dump_dst_nid(pdevinfo, w->conns[i], depth + 1);
-	}
-
-}
-
-static void
-hdac_dump_dac(struct hdac_pcm_devinfo *pdevinfo)
-{
-	struct hdac_devinfo *devinfo = pdevinfo->devinfo;
-	struct hdac_softc *sc = devinfo->codec->sc;
-	struct hdac_audio_as *as;
-	struct hdac_widget *w;
-	int i, printed = 0;
-
-	if (pdevinfo->play < 0)
-		return;
-
-	as = &devinfo->function.audio.as[sc->chans[pdevinfo->play].as];
-	for (i = 0; i < 16; i++) {
-		if (as->pins[i] <= 0)
-			continue;
-		w = hdac_widget_get(devinfo, as->pins[i]);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (printed == 0) {
-			printed = 1;
-			device_printf(pdevinfo->dev, "\n");
-			device_printf(pdevinfo->dev, "Playback:\n");
-		}
-		device_printf(pdevinfo->dev, "\n");
-		hdac_dump_dst_nid(pdevinfo, as->pins[i], 0);
-	}
-}
-
-static void
-hdac_dump_adc(struct hdac_pcm_devinfo *pdevinfo)
-{
-	struct hdac_devinfo *devinfo = pdevinfo->devinfo;
-	struct hdac_softc *sc = devinfo->codec->sc;
-	struct hdac_widget *w;
-	int i;
-	int printed = 0;
-
-	if (pdevinfo->rec < 0)
-		return;
-
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT)
-			continue;
-		if (w->bindas != sc->chans[pdevinfo->rec].as)
-			continue;
-		if (printed == 0) {
-			printed = 1;
-			device_printf(pdevinfo->dev, "\n");
-			device_printf(pdevinfo->dev, "Record:\n");
-		}
-		device_printf(pdevinfo->dev, "\n");
-		hdac_dump_dst_nid(pdevinfo, i, 0);
-	}
-}
-
-static void
-hdac_dump_mix(struct hdac_pcm_devinfo *pdevinfo)
-{
-	struct hdac_devinfo *devinfo = pdevinfo->devinfo;
-	struct hdac_widget *w;
-	int i;
-	int printed = 0;
-
-	if (pdevinfo->index != 0)
-		return;
-
-	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-		w = hdac_widget_get(devinfo, i);
-		if (w == NULL || w->enable == 0)
-			continue;
-		if (w->ossdev != SOUND_MIXER_IMIX)
-			continue;
-		if (printed == 0) {
-			printed = 1;
-			device_printf(pdevinfo->dev, "\n");
-			device_printf(pdevinfo->dev, "Input Mix:\n");
-		}
-		device_printf(pdevinfo->dev, "\n");
-		hdac_dump_dst_nid(pdevinfo, i, 0);
-	}
-}
-
-static void
-hdac_dump_pcmchannels(struct hdac_pcm_devinfo *pdevinfo)
-{
-	struct hdac_softc *sc = pdevinfo->devinfo->codec->sc;
-	nid_t *nids;
-	int i;
-
-	if (pdevinfo->play >= 0) {
-		i = pdevinfo->play;
-		device_printf(pdevinfo->dev, "\n");
-		device_printf(pdevinfo->dev, "Playback:\n");
-		device_printf(pdevinfo->dev, "\n");
-		hdac_dump_audio_formats(pdevinfo->dev, sc->chans[i].supp_stream_formats,
-		    sc->chans[i].supp_pcm_size_rate);
-		device_printf(pdevinfo->dev, "            DAC:");
-		for (nids = sc->chans[i].io; *nids != -1; nids++)
-			printf(" %d", *nids);
-		printf("\n");
-	}
-	if (pdevinfo->rec >= 0) {
-		i = pdevinfo->rec;
-		device_printf(pdevinfo->dev, "\n");
-		device_printf(pdevinfo->dev, "Record:\n");
-		device_printf(pdevinfo->dev, "\n");
-		hdac_dump_audio_formats(pdevinfo->dev, sc->chans[i].supp_stream_formats,
-		    sc->chans[i].supp_pcm_size_rate);
-		device_printf(pdevinfo->dev, "            ADC:");
-		for (nids = sc->chans[i].io; *nids != -1; nids++)
-			printf(" %d", *nids);
-		printf("\n");
-	}
-}
-
-static void
-hdac_release_resources(struct hdac_softc *sc)
-{
-        int i, j;
-
-	if (sc == NULL)
-		return;
-
-	hdac_lock(sc);
-	sc->polling = 0;
-	sc->poll_ival = 0;
-	callout_stop(&sc->poll_hda);
-	callout_stop(&sc->poll_hdac);
-	callout_stop(&sc->poll_jack);
-	hdac_reset(sc, 0);
-	hdac_unlock(sc);
-	taskqueue_drain(taskqueue_thread, &sc->unsolq_task);
-	callout_drain(&sc->poll_hda);
-	callout_drain(&sc->poll_hdac);
-	callout_drain(&sc->poll_jack);
-
-	hdac_irq_free(sc);
-
-	for (i = 0; i < HDAC_CODEC_MAX; i++) {
-		if (sc->codecs[i] == NULL)
-			continue;
-		for (j = 0; j < sc->codecs[i]->num_fgs; j++) {
-			free(sc->codecs[i]->fgs[j].widget, M_HDAC);
-			if (sc->codecs[i]->fgs[j].node_type ==
-			    HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO) {
-				free(sc->codecs[i]->fgs[j].function.audio.ctl,
-				    M_HDAC);
-				free(sc->codecs[i]->fgs[j].function.audio.as,
-				    M_HDAC);
-				free(sc->codecs[i]->fgs[j].function.audio.devs,
-				    M_HDAC);
-			}
-		}
-		free(sc->codecs[i]->fgs, M_HDAC);
-		free(sc->codecs[i], M_HDAC);
-		sc->codecs[i] = NULL;
-	}
-
-	hdac_dma_free(sc, &sc->pos_dma);
-	hdac_dma_free(sc, &sc->rirb_dma);
-	hdac_dma_free(sc, &sc->corb_dma);
-	for (i = 0; i < sc->num_chans; i++) {
-    		if (sc->chans[i].blkcnt > 0)
-    			hdac_dma_free(sc, &sc->chans[i].bdl_dma);
-	}
-	free(sc->chans, M_HDAC);
-	if (sc->chan_dmat != NULL) {
-		bus_dma_tag_destroy(sc->chan_dmat);
-		sc->chan_dmat = NULL;
-	}
-	hdac_mem_free(sc);
-	snd_mtxfree(sc->lock);
-}
-
-/* This function surely going to make its way into upper level someday. */
-static void
-hdac_config_fetch(struct hdac_softc *sc, uint32_t *on, uint32_t *off)
-{
-	const char *res = NULL;
-	int i = 0, j, k, len, inv;
-
-	if (on != NULL)
-		*on = 0;
-	if (off != NULL)
-		*off = 0;
-	if (sc == NULL)
-		return;
-	if (resource_string_value(device_get_name(sc->dev),
-	    device_get_unit(sc->dev), "config", &res) != 0)
-		return;
-	if (!(res != NULL && strlen(res) > 0))
-		return;
-	HDA_BOOTVERBOSE(
-		device_printf(sc->dev, "HDA Config:");
-	);
-	for (;;) {
-		while (res[i] != '\0' &&
-		    (res[i] == ',' || isspace(res[i]) != 0))
-			i++;
-		if (res[i] == '\0') {
-			HDA_BOOTVERBOSE(
-				printf("\n");
-			);
-			return;
-		}
-		j = i;
-		while (res[j] != '\0' &&
-		    !(res[j] == ',' || isspace(res[j]) != 0))
-			j++;
-		len = j - i;
-		if (len > 2 && strncmp(res + i, "no", 2) == 0)
-			inv = 2;
-		else
-			inv = 0;
-		for (k = 0; len > inv && k < HDAC_QUIRKS_TAB_LEN; k++) {
-			if (strncmp(res + i + inv,
-			    hdac_quirks_tab[k].key, len - inv) != 0)
-				continue;
-			if (len - inv != strlen(hdac_quirks_tab[k].key))
-				continue;
-			HDA_BOOTVERBOSE(
-				printf(" %s%s", (inv != 0) ? "no" : "",
-				    hdac_quirks_tab[k].key);
-			);
-			if (inv == 0 && on != NULL)
-				*on |= hdac_quirks_tab[k].value;
-			else if (inv != 0 && off != NULL)
-				*off |= hdac_quirks_tab[k].value;
-			break;
-		}
-		i = j;
-	}
+		callout_reset(&sc->poll_callout, 1, hdac_poll_callback, sc);
 }
 
 static int
@@ -7512,11 +1409,9 @@
 	hdac_lock(sc);
 	if (val != sc->polling) {
 		if (val == 0) {
-			callout_stop(&sc->poll_hda);
-			callout_stop(&sc->poll_hdac);
+			callout_stop(&sc->poll_callout);
 			hdac_unlock(sc);
-			callout_drain(&sc->poll_hda);
-			callout_drain(&sc->poll_hdac);
+			callout_drain(&sc->poll_callout);
 			hdac_lock(sc);
 			sc->polling = 0;
 			ctl = HDAC_READ_4(&sc->mem, HDAC_INTCTL);
@@ -7526,12 +1421,8 @@
 			ctl = HDAC_READ_4(&sc->mem, HDAC_INTCTL);
 			ctl &= ~HDAC_INTCTL_GIE;
 			HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, ctl);
-			hdac_unlock(sc);
-			taskqueue_drain(taskqueue_thread, &sc->unsolq_task);
-			hdac_lock(sc);
 			sc->polling = 1;
 			hdac_poll_reinit(sc);
-			callout_reset(&sc->poll_hdac, 1, hdac_poll_callback, sc);
 		}
 	}
 	hdac_unlock(sc);
@@ -7539,202 +1430,17 @@
 	return (err);
 }
 
-static int
-sysctl_hdac_polling_interval(SYSCTL_HANDLER_ARGS)
-{
-	struct hdac_softc *sc;
-	device_t dev;
-	int err, val;
-
-	dev = oidp->oid_arg1;
-	sc = device_get_softc(dev);
-	if (sc == NULL)
-		return (EINVAL);
-	hdac_lock(sc);
-	val = ((uint64_t)sc->poll_ival * 1000) / hz;
-	hdac_unlock(sc);
-	err = sysctl_handle_int(oidp, &val, 0, req);
-
-	if (err != 0 || req->newptr == NULL)
-		return (err);
-
-	if (val < 1)
-		val = 1;
-	if (val > 5000)
-		val = 5000;
-	val = ((uint64_t)val * hz) / 1000;
-	if (val < 1)
-		val = 1;
-	if (val > (hz * 5))
-		val = hz * 5;
-
-	hdac_lock(sc);
-	sc->poll_ival = val;
-	hdac_unlock(sc);
-
-	return (err);
-}
-
-static int
-sysctl_hdac_pindump(SYSCTL_HANDLER_ARGS)
-{
-	struct hdac_softc *sc;
-	struct hdac_codec *codec;
-	struct hdac_devinfo *devinfo;
-	struct hdac_widget *w;
-	device_t dev;
-	uint32_t res, pincap, delay;
-	int codec_index, fg_index;
-	int i, err, val;
-	nid_t cad;
-
-	dev = oidp->oid_arg1;
-	sc = device_get_softc(dev);
-	if (sc == NULL)
-		return (EINVAL);
-	val = 0;
-	err = sysctl_handle_int(oidp, &val, 0, req);
-	if (err != 0 || req->newptr == NULL || val == 0)
-		return (err);
-	
-	/* XXX: Temporary. For debugging. */
-	if (val == 100) {
-		hdac_suspend(dev);
-		return (0);
-	} else if (val == 101) {
-		hdac_resume(dev);
-		return (0);
-	}
-	
-	hdac_lock(sc);
-	for (codec_index = 0; codec_index < HDAC_CODEC_MAX; codec_index++) {
-		codec = sc->codecs[codec_index];
-		if (codec == NULL)
-			continue;
-		cad = codec->cad;
-		for (fg_index = 0; fg_index < codec->num_fgs; fg_index++) {
-			devinfo = &codec->fgs[fg_index];
-			if (devinfo->node_type !=
-			    HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO)
-				continue;
-
-			device_printf(dev, "Dumping AFG cad=%d nid=%d pins:\n",
-			    codec_index, devinfo->nid);
-			for (i = devinfo->startnode; i < devinfo->endnode; i++) {
-					w = hdac_widget_get(devinfo, i);
-				if (w == NULL || w->type !=
-				    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
-					continue;
-				hdac_dump_pin_config(w, w->wclass.pin.config);
-				pincap = w->wclass.pin.cap;
-				device_printf(dev, "       Caps: %2s %3s %2s %4s %4s",
-				    HDA_PARAM_PIN_CAP_INPUT_CAP(pincap)?"IN":"",
-				    HDA_PARAM_PIN_CAP_OUTPUT_CAP(pincap)?"OUT":"",
-				    HDA_PARAM_PIN_CAP_HEADPHONE_CAP(pincap)?"HP":"",
-				    HDA_PARAM_PIN_CAP_EAPD_CAP(pincap)?"EAPD":"",
-				    HDA_PARAM_PIN_CAP_VREF_CTRL(pincap)?"VREF":"");
-				if (HDA_PARAM_PIN_CAP_IMP_SENSE_CAP(pincap) ||
-				    HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(pincap)) {
-					if (HDA_PARAM_PIN_CAP_TRIGGER_REQD(pincap)) {
-						delay = 0;
-						hdac_command(sc,
-						    HDA_CMD_SET_PIN_SENSE(cad, w->nid, 0), cad);
-						do {
-							res = hdac_command(sc,
-							    HDA_CMD_GET_PIN_SENSE(cad, w->nid), cad);
-							if (res != 0x7fffffff && res != 0xffffffff)
-								break;
-							DELAY(10);
-						} while (++delay < 10000);
-					} else {
-						delay = 0;
-						res = hdac_command(sc, HDA_CMD_GET_PIN_SENSE(cad,
-						    w->nid), cad);
-					}
-					printf(" Sense: 0x%08x", res);
-					if (delay > 0)
-						printf(" delay %dus", delay * 10);
-				}
-				printf("\n");
-			}
-			device_printf(dev,
-			    "NumGPIO=%d NumGPO=%d NumGPI=%d GPIWake=%d GPIUnsol=%d\n",
-			    HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->function.audio.gpio),
-			    HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->function.audio.gpio),
-			    HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->function.audio.gpio),
-			    HDA_PARAM_GPIO_COUNT_GPI_WAKE(devinfo->function.audio.gpio),
-			    HDA_PARAM_GPIO_COUNT_GPI_UNSOL(devinfo->function.audio.gpio));
-			if (HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->function.audio.gpio) > 0) {
-				device_printf(dev, " GPI:");
-				res = hdac_command(sc,
-				    HDA_CMD_GET_GPI_DATA(cad, devinfo->nid), cad);
-				printf(" data=0x%08x", res);
-				res = hdac_command(sc,
-				    HDA_CMD_GET_GPI_WAKE_ENABLE_MASK(cad, devinfo->nid),
-				    cad);
-				printf(" wake=0x%08x", res);
-				res = hdac_command(sc,
-				    HDA_CMD_GET_GPI_UNSOLICITED_ENABLE_MASK(cad, devinfo->nid),
-				    cad);
-				printf(" unsol=0x%08x", res);
-				res = hdac_command(sc,
-				    HDA_CMD_GET_GPI_STICKY_MASK(cad, devinfo->nid), cad);
-				printf(" sticky=0x%08x\n", res);
-			}
-			if (HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->function.audio.gpio) > 0) {
-				device_printf(dev, " GPO:");
-				res = hdac_command(sc,
-				    HDA_CMD_GET_GPO_DATA(cad, devinfo->nid), cad);
-				printf(" data=0x%08x\n", res);
-			}
-			if (HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->function.audio.gpio) > 0) {
-				device_printf(dev, "GPIO:");
-				res = hdac_command(sc,
-				    HDA_CMD_GET_GPIO_DATA(cad, devinfo->nid), cad);
-				printf(" data=0x%08x", res);
-				res = hdac_command(sc,
-				    HDA_CMD_GET_GPIO_ENABLE_MASK(cad, devinfo->nid), cad);
-				printf(" enable=0x%08x", res);
-				res = hdac_command(sc,
-				    HDA_CMD_GET_GPIO_DIRECTION(cad, devinfo->nid), cad);
-				printf(" direction=0x%08x\n", res);
-				res = hdac_command(sc,
-				    HDA_CMD_GET_GPIO_WAKE_ENABLE_MASK(cad, devinfo->nid), cad);
-				device_printf(dev, "      wake=0x%08x", res);
-				res = hdac_command(sc,
-				    HDA_CMD_GET_GPIO_UNSOLICITED_ENABLE_MASK(cad, devinfo->nid),
-				    cad);
-				printf("  unsol=0x%08x", res);
-				res = hdac_command(sc,
-				    HDA_CMD_GET_GPIO_STICKY_MASK(cad, devinfo->nid), cad);
-				printf("    sticky=0x%08x\n", res);
-			}
-		}
-	}
-	hdac_unlock(sc);
-	return (0);
-}
-
 static void
 hdac_attach2(void *arg)
 {
-	struct hdac_codec *codec;
 	struct hdac_softc *sc;
-	struct hdac_audio_ctl *ctl;
-	uint32_t quirks_on, quirks_off;
-	int codec_index, fg_index;
-	int i, dmaalloc = 0;
-	struct hdac_devinfo *devinfo;
+	device_t child;
+	uint32_t vendorid, revisionid;
+	int i;
+	uint16_t statests;
 
 	sc = (struct hdac_softc *)arg;
 
-	hdac_config_fetch(sc, &quirks_on, &quirks_off);
-
-	HDA_BOOTHVERBOSE(
-		device_printf(sc->dev, "HDA Config: on=0x%08x off=0x%08x\n",
-		    quirks_on, quirks_off);
-	);
-
 	hdac_lock(sc);
 
 	/* Remove ourselves from the config hooks */
@@ -7743,7 +1449,6 @@
 		sc->intrhook.ich_func = NULL;
 	}
 
-	/* Start the corb and rirb engines */
 	HDA_BOOTHVERBOSE(
 		device_printf(sc->dev, "Starting CORB Engine...\n");
 	);
@@ -7752,7 +1457,6 @@
 		device_printf(sc->dev, "Starting RIRB Engine...\n");
 	);
 	hdac_rirb_start(sc);
-
 	HDA_BOOTHVERBOSE(
 		device_printf(sc->dev,
 		    "Enabling controller interrupt...\n");
@@ -7762,218 +1466,60 @@
 	if (sc->polling == 0) {
 		HDAC_WRITE_4(&sc->mem, HDAC_INTCTL,
 		    HDAC_INTCTL_CIE | HDAC_INTCTL_GIE);
-	} else {
-		callout_reset(&sc->poll_hdac, 1, hdac_poll_callback, sc);
 	}
 	DELAY(1000);
 
 	HDA_BOOTHVERBOSE(
-		device_printf(sc->dev,
-		    "Scanning HDA codecs ...\n");
+		device_printf(sc->dev, "Scanning HDA codecs ...\n");
 	);
-	hdac_scan_codecs(sc);
-	
-	for (codec_index = 0; codec_index < HDAC_CODEC_MAX; codec_index++) {
-		codec = sc->codecs[codec_index];
-		if (codec == NULL)
-			continue;
-		for (fg_index = 0; fg_index < codec->num_fgs; fg_index++) {
-			devinfo = &codec->fgs[fg_index];
-			HDA_BOOTVERBOSE(
-				device_printf(sc->dev, "\n");
+	statests = HDAC_READ_2(&sc->mem, HDAC_STATESTS);
+	hdac_unlock(sc);
+	for (i = 0; i < HDAC_CODEC_MAX; i++) {
+		if (HDAC_STATESTS_SDIWAKE(statests, i)) {
+			HDA_BOOTHVERBOSE(
 				device_printf(sc->dev,
-				    "Processing %s FG cad=%d nid=%d...\n",
-				    (devinfo->node_type == HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO) ? "audio":
-				    (devinfo->node_type == HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_MODEM) ? "modem":
-				    "unknown",
-				    devinfo->codec->cad, devinfo->nid);
+				    "Found CODEC at address %d\n", i);
 			);
-			if (devinfo->node_type !=
-			    HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO) {
-				HDA_BOOTHVERBOSE(
-					device_printf(sc->dev,
-					    "Powering down...\n");
-				);
-				hdac_command(sc,
-				    HDA_CMD_SET_POWER_STATE(codec->cad,
-				    devinfo->nid, HDA_CMD_POWER_STATE_D3),
-				    codec->cad);
+			hdac_lock(sc);
+			vendorid = hdac_send_command(sc, i,
+			    HDA_CMD_GET_PARAMETER(0, 0x0, HDA_PARAM_VENDOR_ID));
+			revisionid = hdac_send_command(sc, i,
+			    HDA_CMD_GET_PARAMETER(0, 0x0, HDA_PARAM_REVISION_ID));
+			hdac_unlock(sc);
+			if (vendorid == HDA_INVALID &&
+			    revisionid == HDA_INVALID) {
+				device_printf(sc->dev,
+				    "CODEC is not responding!\n");
 				continue;
 			}
-
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Powering up...\n");
-			);
-			hdac_powerup(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Parsing audio FG...\n");
-			);
-			hdac_audio_parse(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Parsing vendor patch...\n");
-			);
-			hdac_vendor_patch_parse(devinfo);
-			devinfo->function.audio.quirks |= quirks_on;
-			devinfo->function.audio.quirks &= ~quirks_off;
-
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Parsing Ctls...\n");
-			);
-			hdac_audio_ctl_parse(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Disabling nonaudio...\n");
-			);
-			hdac_audio_disable_nonaudio(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Disabling useless...\n");
-			);
-			hdac_audio_disable_useless(devinfo);
-			HDA_BOOTVERBOSE(
-				device_printf(sc->dev, "Patched pins configuration:\n");
-				hdac_dump_pin_configs(devinfo);
-			);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Parsing pin associations...\n");
-			);
-			hdac_audio_as_parse(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Building AFG tree...\n");
-			);
-			hdac_audio_build_tree(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Disabling unassociated "
-				    "widgets...\n");
-			);
-			hdac_audio_disable_unas(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Disabling nonselected "
-				    "inputs...\n");
-			);
-			hdac_audio_disable_notselected(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Disabling useless...\n");
-			);
-			hdac_audio_disable_useless(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Disabling "
-				    "crossassociatement connections...\n");
-			);
-			hdac_audio_disable_crossas(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Disabling useless...\n");
-			);
-			hdac_audio_disable_useless(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Binding associations to channels...\n");
-			);
-			hdac_audio_bind_as(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Assigning names to signal sources...\n");
-			);
-			hdac_audio_assign_names(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Assigning mixers to the tree...\n");
-			);
-			hdac_audio_assign_mixers(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Preparing pin controls...\n");
-			);
-			hdac_audio_prepare_pin_ctrl(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "AFG commit...\n");
-		    	);
-			hdac_audio_commit(devinfo);
-		    	HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "HP switch init...\n");
-			);
-			hdac_hp_switch_init(devinfo);
-
-			if ((devinfo->function.audio.quirks & HDA_QUIRK_DMAPOS) &&
-			    dmaalloc == 0) {
-				if (hdac_dma_alloc(sc, &sc->pos_dma,
-				    (sc->num_iss + sc->num_oss + sc->num_bss) * 8) != 0) {
-					HDA_BOOTVERBOSE(
-						device_printf(sc->dev, "Failed to "
-						    "allocate DMA pos buffer "
-						    "(non-fatal)\n");
-					);
-				} else
-					dmaalloc = 1;
+			sc->codecs[i].vendor_id =
+			    HDA_PARAM_VENDOR_ID_VENDOR_ID(vendorid);
+			sc->codecs[i].device_id =
+			    HDA_PARAM_VENDOR_ID_DEVICE_ID(vendorid);
+			sc->codecs[i].revision_id =
+			    HDA_PARAM_REVISION_ID_REVISION_ID(revisionid);
+			sc->codecs[i].stepping_id =
+			    HDA_PARAM_REVISION_ID_STEPPING_ID(revisionid);
+			child = device_add_child(sc->dev, "hdacc", -1);
+			if (child == NULL) {
+				device_printf(sc->dev,
+				    "Failed to add CODEC device\n");
+				continue;
 			}
-			
-		    	HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "Creating PCM devices...\n");
-			);
-			hdac_create_pcms(devinfo);
-
-			HDA_BOOTVERBOSE(
-				if (devinfo->function.audio.quirks != 0) {
-					device_printf(sc->dev, "FG config/quirks:");
-					for (i = 0; i < HDAC_QUIRKS_TAB_LEN; i++) {
-						if ((devinfo->function.audio.quirks &
-						    hdac_quirks_tab[i].value) ==
-						    hdac_quirks_tab[i].value)
-							printf(" %s", hdac_quirks_tab[i].key);
-					}
-					printf("\n");
-				}
-
-				device_printf(sc->dev, "\n");
-				device_printf(sc->dev, "+-------------------+\n");
-				device_printf(sc->dev, "| DUMPING HDA NODES |\n");
-				device_printf(sc->dev, "+-------------------+\n");
-				hdac_dump_nodes(devinfo);
-			);
-
-			HDA_BOOTHVERBOSE(
-				device_printf(sc->dev, "\n");
-				device_printf(sc->dev, "+------------------------+\n");
-				device_printf(sc->dev, "| DUMPING HDA AMPLIFIERS |\n");
-				device_printf(sc->dev, "+------------------------+\n");
-				device_printf(sc->dev, "\n");
-				i = 0;
-				while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) {
-					device_printf(sc->dev, "%3d: nid %3d %s (%s) index %d", i,
-					    (ctl->widget != NULL) ? ctl->widget->nid : -1,
-					    (ctl->ndir == HDA_CTL_IN)?"in ":"out",
-					    (ctl->dir == HDA_CTL_IN)?"in ":"out",
-					    ctl->index);
-					if (ctl->childwidget != NULL)
-						printf(" cnid %3d", ctl->childwidget->nid);
-					else
-						printf("         ");
-					printf(" ossmask=0x%08x\n",
-					    ctl->ossmask);
-					device_printf(sc->dev, 
-					    "       mute: %d step: %3d size: %3d off: %3d%s\n",
-					    ctl->mute, ctl->step, ctl->size, ctl->offset,
-					    (ctl->enable == 0) ? " [DISABLED]" : 
-					    ((ctl->ossmask == 0) ? " [UNUSED]" : ""));
-				}
-			);
+			device_set_ivars(child, (void *)(intptr_t)i);
+			sc->codecs[i].dev = child;
 		}
 	}
-	hdac_unlock(sc);
-
-	HDA_BOOTVERBOSE(
-		device_printf(sc->dev, "\n");
-	);
-
 	bus_generic_attach(sc->dev);
 
 	SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO,
+	    "pindump", CTLTYPE_INT | CTLFLAG_RW, sc->dev, sizeof(sc->dev),
+	    sysctl_hdac_pindump, "I", "Dump pin states/data");
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO,
 	    "polling", CTLTYPE_INT | CTLFLAG_RW, sc->dev, sizeof(sc->dev),
 	    sysctl_hdac_polling, "I", "Enable polling mode");
-	SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO,
-	    "polling_interval", CTLTYPE_INT | CTLFLAG_RW, sc->dev,
-	    sizeof(sc->dev), sysctl_hdac_polling_interval, "I",
-	    "Controller/Jack Sense polling interval (1-1000 ms)");
-	SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO,
-	    "pindump", CTLTYPE_INT | CTLFLAG_RW, sc->dev, sizeof(sc->dev),
-	    sysctl_hdac_pindump, "I", "Dump pin states/data");
 }
 
 /****************************************************************************
@@ -7984,64 +1530,23 @@
 static int
 hdac_suspend(device_t dev)
 {
-	struct hdac_softc *sc;
-	struct hdac_codec *codec;
-	struct hdac_devinfo *devinfo;
-	int codec_index, fg_index, i;
+	struct hdac_softc *sc = device_get_softc(dev);
 
 	HDA_BOOTHVERBOSE(
 		device_printf(dev, "Suspend...\n");
 	);
+	bus_generic_suspend(dev);
 
-	sc = device_get_softc(dev);
 	hdac_lock(sc);
-	
-	HDA_BOOTHVERBOSE(
-		device_printf(dev, "Stop streams...\n");
-	);
-	for (i = 0; i < sc->num_chans; i++) {
-		if (sc->chans[i].flags & HDAC_CHN_RUNNING) {
-			sc->chans[i].flags |= HDAC_CHN_SUSPEND;
-			hdac_channel_stop(sc, &sc->chans[i]);
-		}
-	}
-
-	for (codec_index = 0; codec_index < HDAC_CODEC_MAX; codec_index++) {
-		codec = sc->codecs[codec_index];
-		if (codec == NULL)
-			continue;
-		for (fg_index = 0; fg_index < codec->num_fgs; fg_index++) {
-			devinfo = &codec->fgs[fg_index];
-			HDA_BOOTHVERBOSE(
-				device_printf(dev,
-				    "Power down FG"
-				    " cad=%d nid=%d to the D3 state...\n",
-				    codec->cad, devinfo->nid);
-			);
-			hdac_command(sc,
-			    HDA_CMD_SET_POWER_STATE(codec->cad,
-			    devinfo->nid, HDA_CMD_POWER_STATE_D3),
-			    codec->cad);
-		}
-	}
-
 	HDA_BOOTHVERBOSE(
 		device_printf(dev, "Reset controller...\n");
 	);
-	callout_stop(&sc->poll_hda);
-	callout_stop(&sc->poll_hdac);
-	callout_stop(&sc->poll_jack);
 	hdac_reset(sc, 0);
 	hdac_unlock(sc);
 	taskqueue_drain(taskqueue_thread, &sc->unsolq_task);
-	callout_drain(&sc->poll_hda);
-	callout_drain(&sc->poll_hdac);
-	callout_drain(&sc->poll_jack);
-
 	HDA_BOOTHVERBOSE(
 		device_printf(dev, "Suspend done\n");
 	);
-
 	return (0);
 }
 
@@ -8053,16 +1558,12 @@
 static int
 hdac_resume(device_t dev)
 {
-	struct hdac_softc *sc;
-	struct hdac_codec *codec;
-	struct hdac_devinfo *devinfo;
-	int codec_index, fg_index, i;
+	struct hdac_softc *sc = device_get_softc(dev);
+	int error;
 
 	HDA_BOOTHVERBOSE(
 		device_printf(dev, "Resume...\n");
 	);
-
-	sc = device_get_softc(dev);
 	hdac_lock(sc);
 
 	/* Quiesce everything */
@@ -8075,7 +1576,6 @@
 	hdac_corb_init(sc);
 	hdac_rirb_init(sc);
 
-	/* Start the corb and rirb engines */
 	HDA_BOOTHVERBOSE(
 		device_printf(dev, "Starting CORB Engine...\n");
 	);
@@ -8084,91 +1584,22 @@
 		device_printf(dev, "Starting RIRB Engine...\n");
 	);
 	hdac_rirb_start(sc);
-
 	HDA_BOOTHVERBOSE(
-		device_printf(dev,
-		    "Enabling controller interrupt...\n");
+		device_printf(dev, "Enabling controller interrupt...\n");
 	);
 	HDAC_WRITE_4(&sc->mem, HDAC_GCTL, HDAC_READ_4(&sc->mem, HDAC_GCTL) |
 	    HDAC_GCTL_UNSOL);
-	if (sc->polling == 0) {
-		HDAC_WRITE_4(&sc->mem, HDAC_INTCTL,
-		    HDAC_INTCTL_CIE | HDAC_INTCTL_GIE);
-	} else {
-		callout_reset(&sc->poll_hdac, 1, hdac_poll_callback, sc);
-	}
+	HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, HDAC_INTCTL_CIE | HDAC_INTCTL_GIE);
 	DELAY(1000);
-
-	for (codec_index = 0; codec_index < HDAC_CODEC_MAX; codec_index++) {
-		codec = sc->codecs[codec_index];
-		if (codec == NULL)
-			continue;
-		for (fg_index = 0; fg_index < codec->num_fgs; fg_index++) {
-			devinfo = &codec->fgs[fg_index];
-			if (devinfo->node_type !=
-			    HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO) {
-				HDA_BOOTHVERBOSE(
-					device_printf(dev,
-					    "Power down unsupported non-audio FG"
-					    " cad=%d nid=%d to the D3 state...\n",
-					    codec->cad, devinfo->nid);
-				);
-				hdac_command(sc,
-				    HDA_CMD_SET_POWER_STATE(codec->cad,
-				    devinfo->nid, HDA_CMD_POWER_STATE_D3),
-				    codec->cad);
-				continue;
-			}
-
-			HDA_BOOTHVERBOSE(
-				device_printf(dev,
-				    "Power up audio FG cad=%d nid=%d...\n",
-				    devinfo->codec->cad, devinfo->nid);
-			);
-			hdac_powerup(devinfo);
-			HDA_BOOTHVERBOSE(
-				device_printf(dev, "AFG commit...\n");
-		    	);
-			hdac_audio_commit(devinfo);
-		    	HDA_BOOTHVERBOSE(
-				device_printf(dev, "HP switch init...\n");
-			);
-			hdac_hp_switch_init(devinfo);
-
-			hdac_unlock(sc);
-			for (i = 0; i < devinfo->function.audio.num_devs; i++) {
-				struct hdac_pcm_devinfo *pdevinfo = 
-				    &devinfo->function.audio.devs[i];
-				HDA_BOOTHVERBOSE(
-					device_printf(pdevinfo->dev,
-					    "OSS mixer reinitialization...\n");
-				);
-				if (mixer_reinit(pdevinfo->dev) == -1)
-					device_printf(pdevinfo->dev,
-					    "unable to reinitialize the mixer\n");
-			}
-			hdac_lock(sc);
-		}
-	}
-
-	HDA_BOOTHVERBOSE(
-		device_printf(dev, "Start streams...\n");
-	);
-	for (i = 0; i < sc->num_chans; i++) {
-		if (sc->chans[i].flags & HDAC_CHN_SUSPEND) {
-			sc->chans[i].flags &= ~HDAC_CHN_SUSPEND;
-			hdac_channel_start(sc, &sc->chans[i]);
-		}
-	}
-
 	hdac_unlock(sc);
 
+	error = bus_generic_resume(dev);
 	HDA_BOOTHVERBOSE(
 		device_printf(dev, "Resume done\n");
 	);
+	return (error);
+}
 
-	return (0);
-}
 /****************************************************************************
  * int hdac_detach(device_t)
  *
@@ -8177,41 +1608,377 @@
 static int
 hdac_detach(device_t dev)
 {
-	struct hdac_softc *sc;
+	struct hdac_softc *sc = device_get_softc(dev);
 	device_t *devlist;
-	int i, devcount, error;
+	int cad, i, devcount, error;
 
 	if ((error = device_get_children(dev, &devlist, &devcount)) != 0)
 		return (error);
 	for (i = 0; i < devcount; i++) {
+		cad = (intptr_t)device_get_ivars(devlist[i]);
 		if ((error = device_delete_child(dev, devlist[i])) != 0) {
 			free(devlist, M_TEMP);
 			return (error);
 		}
+		sc->codecs[cad].dev = NULL;
 	}
 	free(devlist, M_TEMP);
 
-	sc = device_get_softc(dev);
-	hdac_release_resources(sc);
+	hdac_lock(sc);
+	hdac_reset(sc, 0);
+	hdac_unlock(sc);
+	taskqueue_drain(taskqueue_thread, &sc->unsolq_task);
+	hdac_irq_free(sc);
 
+	for (i = 0; i < sc->num_ss; i++)
+		hdac_dma_free(sc, &sc->streams[i].bdl);
+	free(sc->streams, M_HDAC);
+	hdac_dma_free(sc, &sc->pos_dma);
+	hdac_dma_free(sc, &sc->rirb_dma);
+	hdac_dma_free(sc, &sc->corb_dma);
+	if (sc->chan_dmat != NULL) {
+		bus_dma_tag_destroy(sc->chan_dmat);
+		sc->chan_dmat = NULL;
+	}
+	hdac_mem_free(sc);
+	snd_mtxfree(sc->lock);
 	return (0);
 }
 
+static bus_dma_tag_t
+hdac_get_dma_tag(device_t dev, device_t child)
+{
+	struct hdac_softc *sc = device_get_softc(dev);
+
+	return (sc->chan_dmat);
+}
+
 static int
 hdac_print_child(device_t dev, device_t child)
 {
-	struct hdac_pcm_devinfo *pdevinfo =
-	    (struct hdac_pcm_devinfo *)device_get_ivars(child);
 	int retval;
 
 	retval = bus_print_child_header(dev, child);
-	retval += printf(" at cad %d nid %d",
-	    pdevinfo->devinfo->codec->cad, pdevinfo->devinfo->nid);
+	retval += printf(" at cad %d",
+	    (int)(intptr_t)device_get_ivars(child));
 	retval += bus_print_child_footer(dev, child);
 
 	return (retval);
 }
 
+static int
+hdac_child_location_str(device_t dev, device_t child, char *buf,
+    size_t buflen)
+{
+
+	snprintf(buf, buflen, "cad=%d",
+	    (int)(intptr_t)device_get_ivars(child));
+	return (0);
+}
+
+static int
+hdac_child_pnpinfo_str_method(device_t dev, device_t child, char *buf,
+    size_t buflen)
+{
+	struct hdac_softc *sc = device_get_softc(dev);
+	nid_t cad = (uintptr_t)device_get_ivars(child);
+
+	snprintf(buf, buflen, "vendor=0x%04x device=0x%04x revision=0x%02x "
+	    "stepping=0x%02x",
+	    sc->codecs[cad].vendor_id, sc->codecs[cad].device_id,
+	    sc->codecs[cad].revision_id, sc->codecs[cad].stepping_id);
+	return (0);
+}
+
+static int
+hdac_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+	struct hdac_softc *sc = device_get_softc(dev);
+	nid_t cad = (uintptr_t)device_get_ivars(child);
+
+	switch (which) {
+	case HDA_IVAR_CODEC_ID:
+		*result = cad;
+		break;
+	case HDA_IVAR_VENDOR_ID:
+		*result = sc->codecs[cad].vendor_id;
+		break;
+	case HDA_IVAR_DEVICE_ID:
+		*result = sc->codecs[cad].device_id;
+		break;
+	case HDA_IVAR_REVISION_ID:
+		*result = sc->codecs[cad].revision_id;
+		break;
+	case HDA_IVAR_STEPPING_ID:
+		*result = sc->codecs[cad].stepping_id;
+		break;
+	case HDA_IVAR_SUBVENDOR_ID:
+		*result = pci_get_subvendor(dev);
+		break;
+	case HDA_IVAR_SUBDEVICE_ID:
+		*result = pci_get_subdevice(dev);
+		break;
+	case HDA_IVAR_DMA_NOCACHE:
+		*result = (sc->flags & HDAC_F_DMA_NOCACHE) != 0;
+		break;
+	default:
+		return (ENOENT);
+	}
+	return (0);
+}
+
+static struct mtx *
+hdac_get_mtx(device_t dev, device_t child)
+{
+	struct hdac_softc *sc = device_get_softc(dev);
+
+	return (sc->lock);
+}
+
+static uint32_t
+hdac_codec_command(device_t dev, device_t child, uint32_t verb)
+{
+
+	return (hdac_send_command(device_get_softc(dev),
+	    (intptr_t)device_get_ivars(child), verb));
+}
+
+static int
+hdac_find_stream(struct hdac_softc *sc, int dir, int stream)
+{
+	int i, ss;
+
+	ss = -1;
+	/* Allocate ISS/BSS first. */
+	if (dir == 0) {
+		for (i = 0; i < sc->num_iss; i++) {
+			if (sc->streams[i].stream == stream) {
+				ss = i;
+				break;
+			}
+		}
+	} else {
+		for (i = 0; i < sc->num_oss; i++) {
+			if (sc->streams[i + sc->num_iss].stream == stream) {
+				ss = i + sc->num_iss;
+				break;
+			}
+		}
+	}
+	/* Fallback to BSS. */
+	if (ss == -1) {
+		for (i = 0; i < sc->num_bss; i++) {
+			if (sc->streams[i + sc->num_iss + sc->num_oss].stream
+			    == stream) {
+				ss = i + sc->num_iss + sc->num_oss;
+				break;
+			}
+		}
+	}
+	return (ss);
+}
+
+static int
+hdac_stream_alloc(device_t dev, device_t child, int dir, int format,
+    uint32_t **dmapos)
+{
+	struct hdac_softc *sc = device_get_softc(dev);
+	int stream, ss;
+
+	/* Look for empty stream. */
+	ss = hdac_find_stream(sc, dir, 0);
+
+	/* Return if found nothing. */
+	if (ss < 0)
+		return (0);
+
+	/* Allocate stream number */
+	if (ss >= sc->num_iss + sc->num_oss)
+		stream = 15 - (ss - sc->num_iss + sc->num_oss);
+	else if (ss >= sc->num_iss)
+		stream = ss - sc->num_iss + 1;
+	else
+		stream = ss + 1;
+
+	sc->streams[ss].dev = child;
+	sc->streams[ss].dir = dir;
+	sc->streams[ss].stream = stream;
+	sc->streams[ss].format = format;
+	if (dmapos != NULL) {
+		if (sc->pos_dma.dma_vaddr != NULL)
+			*dmapos = (uint32_t *)(sc->pos_dma.dma_vaddr + ss * 8);
+		else
+			*dmapos = NULL;
+	}
+	return (stream);
+}
+
+static void
+hdac_stream_free(device_t dev, device_t child, int dir, int stream)
+{
+	struct hdac_softc *sc = device_get_softc(dev);
+	int ss;
+
+	ss = hdac_find_stream(sc, dir, stream);
+	KASSERT(ss >= 0,
+	    ("Free for not allocated stream (%d/%d)\n", dir, stream));
+	sc->streams[ss].stream = 0;
+	sc->streams[ss].dev = NULL;
+}
+
+static int
+hdac_stream_start(device_t dev, device_t child,
+    int dir, int stream, bus_addr_t buf, int blksz, int blkcnt)
+{
+	struct hdac_softc *sc = device_get_softc(dev);
+	struct hdac_bdle *bdle;
+	uint64_t addr;
+	int i, ss, off;
+	uint32_t ctl;
+
+	ss = hdac_find_stream(sc, dir, stream);
+	KASSERT(ss >= 0,
+	    ("Start for not allocated stream (%d/%d)\n", dir, stream));
+
+	addr = (uint64_t)buf;
+	bdle = (struct hdac_bdle *)sc->streams[ss].bdl.dma_vaddr;
+	for (i = 0; i < blkcnt; i++, bdle++) {
+		bdle->addrl = (uint32_t)addr;
+		bdle->addrh = (uint32_t)(addr >> 32);
+		bdle->len = blksz;
+		bdle->ioc = 1;
+		addr += blksz;
+	}
+
+	off = ss << 5;
+	HDAC_WRITE_4(&sc->mem, off + HDAC_SDCBL, blksz * blkcnt);
+	HDAC_WRITE_2(&sc->mem, off + HDAC_SDLVI, blkcnt - 1);
+	addr = sc->streams[ss].bdl.dma_paddr;
+	HDAC_WRITE_4(&sc->mem, off + HDAC_SDBDPL, (uint32_t)addr);
+	HDAC_WRITE_4(&sc->mem, off + HDAC_SDBDPU, (uint32_t)(addr >> 32));
+
+	ctl = HDAC_READ_1(&sc->mem, off + HDAC_SDCTL2);
+	if (dir)
+		ctl |= HDAC_SDCTL2_DIR;
+	else
+		ctl &= ~HDAC_SDCTL2_DIR;
+	ctl &= ~HDAC_SDCTL2_STRM_MASK;
+	ctl |= stream << HDAC_SDCTL2_STRM_SHIFT;
+	HDAC_WRITE_1(&sc->mem, off + HDAC_SDCTL2, ctl);
+
+	HDAC_WRITE_2(&sc->mem, off + HDAC_SDFMT, sc->streams[ss].format);
+
+	ctl = HDAC_READ_4(&sc->mem, HDAC_INTCTL);
+	ctl |= 1 << ss;
+	HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, ctl);
+
+	ctl = HDAC_READ_1(&sc->mem, off + HDAC_SDCTL0);
+	ctl |= HDAC_SDCTL_IOCE | HDAC_SDCTL_FEIE | HDAC_SDCTL_DEIE |
+	    HDAC_SDCTL_RUN;
+	HDAC_WRITE_1(&sc->mem, off + HDAC_SDCTL0, ctl);
+
+	sc->streams[ss].blksz = blksz;
+	sc->streams[ss].running = 1;
+	hdac_poll_reinit(sc);
+	return (0);
+}
+
+static void
+hdac_stream_stop(device_t dev, device_t child, int dir, int stream)
+{
+	struct hdac_softc *sc = device_get_softc(dev);
+	int ss, off;
+	uint32_t ctl;
+
+	ss = hdac_find_stream(sc, dir, stream);
+	KASSERT(ss >= 0,
+	    ("Stop for not allocated stream (%d/%d)\n", dir, stream));
+
+	off = ss << 5;
+	ctl = HDAC_READ_1(&sc->mem, off + HDAC_SDCTL0);
+	ctl &= ~(HDAC_SDCTL_IOCE | HDAC_SDCTL_FEIE | HDAC_SDCTL_DEIE |
+	    HDAC_SDCTL_RUN);
+	HDAC_WRITE_1(&sc->mem, off + HDAC_SDCTL0, ctl);
+
+	ctl = HDAC_READ_4(&sc->mem, HDAC_INTCTL);
+	ctl &= ~(1 << ss);
+	HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, ctl);
+
+	sc->streams[ss].running = 0;
+	hdac_poll_reinit(sc);
+}
+
+static void
+hdac_stream_reset(device_t dev, device_t child, int dir, int stream)
+{
+	struct hdac_softc *sc = device_get_softc(dev);
+	int timeout = 1000;
+	int to = timeout;
+	int ss, off;
+	uint32_t ctl;
+
+	ss = hdac_find_stream(sc, dir, stream);
+	KASSERT(ss >= 0,
+	    ("Reset for not allocated stream (%d/%d)\n", dir, stream));
+
+	off = ss << 5;
+	ctl = HDAC_READ_1(&sc->mem, off + HDAC_SDCTL0);
+	ctl |= HDAC_SDCTL_SRST;
+	HDAC_WRITE_1(&sc->mem, off + HDAC_SDCTL0, ctl);
+	do {
+		ctl = HDAC_READ_1(&sc->mem, off + HDAC_SDCTL0);
+		if (ctl & HDAC_SDCTL_SRST)
+			break;
+		DELAY(10);
+	} while (--to);
+	if (!(ctl & HDAC_SDCTL_SRST))
+		device_printf(dev, "Reset setting timeout\n");
+	ctl &= ~HDAC_SDCTL_SRST;
+	HDAC_WRITE_1(&sc->mem, off + HDAC_SDCTL0, ctl);
+	to = timeout;
+	do {
+		ctl = HDAC_READ_1(&sc->mem, off + HDAC_SDCTL0);
+		if (!(ctl & HDAC_SDCTL_SRST))
+			break;
+		DELAY(10);
+	} while (--to);
+	if (ctl & HDAC_SDCTL_SRST)
+		device_printf(dev, "Reset timeout!\n");
+}
+
+static uint32_t
+hdac_stream_getptr(device_t dev, device_t child, int dir, int stream)
+{
+	struct hdac_softc *sc = device_get_softc(dev);
+	int ss, off;
+
+	ss = hdac_find_stream(sc, dir, stream);
+	KASSERT(ss >= 0,
+	    ("Reset for not allocated stream (%d/%d)\n", dir, stream));
+
+	off = ss << 5;
+	return (HDAC_READ_4(&sc->mem, off + HDAC_SDLPIB));
+}
+
+static int
+hdac_unsol_alloc(device_t dev, device_t child, int tag)
+{
+	struct hdac_softc *sc = device_get_softc(dev);
+
+	sc->unsol_registered++;
+	hdac_poll_reinit(sc);
+	return (tag);
+}
+
+static void
+hdac_unsol_free(device_t dev, device_t child, int tag)
+{
+	struct hdac_softc *sc = device_get_softc(dev);
+
+	sc->unsol_registered--;
+	hdac_poll_reinit(sc);
+}
+
 static device_method_t hdac_methods[] = {
 	/* device interface */
 	DEVMETHOD(device_probe,		hdac_probe),
@@ -8220,7 +1987,21 @@
 	DEVMETHOD(device_suspend,	hdac_suspend),
 	DEVMETHOD(device_resume,	hdac_resume),
 	/* Bus interface */
+	DEVMETHOD(bus_get_dma_tag,	hdac_get_dma_tag),
 	DEVMETHOD(bus_print_child,	hdac_print_child),
+	DEVMETHOD(bus_child_location_str, hdac_child_location_str),
+	DEVMETHOD(bus_child_pnpinfo_str, hdac_child_pnpinfo_str_method),
+	DEVMETHOD(bus_read_ivar,	hdac_read_ivar),
+	DEVMETHOD(hdac_get_mtx,		hdac_get_mtx),
+	DEVMETHOD(hdac_codec_command,	hdac_codec_command),
+	DEVMETHOD(hdac_stream_alloc,	hdac_stream_alloc),
+	DEVMETHOD(hdac_stream_free,	hdac_stream_free),
+	DEVMETHOD(hdac_stream_start,	hdac_stream_start),
+	DEVMETHOD(hdac_stream_stop,	hdac_stream_stop),
+	DEVMETHOD(hdac_stream_reset,	hdac_stream_reset),
+	DEVMETHOD(hdac_stream_getptr,	hdac_stream_getptr),
+	DEVMETHOD(hdac_unsol_alloc,	hdac_unsol_alloc),
+	DEVMETHOD(hdac_unsol_free,	hdac_unsol_free),
 	{ 0, 0 }
 };
 
@@ -8233,148 +2014,3 @@
 static devclass_t hdac_devclass;
 
 DRIVER_MODULE(snd_hda, pci, hdac_driver, hdac_devclass, 0, 0);
-MODULE_DEPEND(snd_hda, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
-MODULE_VERSION(snd_hda, 1);
-
-static int
-hdac_pcm_probe(device_t dev)
-{
-	struct hdac_pcm_devinfo *pdevinfo =
-	    (struct hdac_pcm_devinfo *)device_get_ivars(dev);
-	char buf[128];
-
-	snprintf(buf, sizeof(buf), "HDA %s PCM #%d %s",
-	    hdac_codec_name(pdevinfo->devinfo->codec),
-	    pdevinfo->index,
-	    (pdevinfo->digital == 3)?"DisplayPort":
-	    ((pdevinfo->digital == 2)?"HDMI":
-	    ((pdevinfo->digital)?"Digital":"Analog")));
-	device_set_desc_copy(dev, buf);
-	return (0);
-}
-
-static int
-hdac_pcm_attach(device_t dev)
-{
-	struct hdac_pcm_devinfo *pdevinfo =
-	    (struct hdac_pcm_devinfo *)device_get_ivars(dev);
-	struct hdac_softc *sc = pdevinfo->devinfo->codec->sc;
-	char status[SND_STATUSLEN];
-	int i;
-
-	pdevinfo->chan_size = pcm_getbuffersize(dev,
-	    HDA_BUFSZ_MIN, HDA_BUFSZ_DEFAULT, HDA_BUFSZ_MAX);
-
-	HDA_BOOTVERBOSE(
-		device_printf(dev, "+--------------------------------------+\n");
-		device_printf(dev, "| DUMPING PCM Playback/Record Channels |\n");
-		device_printf(dev, "+--------------------------------------+\n");
-		hdac_dump_pcmchannels(pdevinfo);
-		device_printf(dev, "\n");
-		device_printf(dev, "+-------------------------------+\n");
-		device_printf(dev, "| DUMPING Playback/Record Paths |\n");
-		device_printf(dev, "+-------------------------------+\n");
-		hdac_dump_dac(pdevinfo);
-		hdac_dump_adc(pdevinfo);
-		hdac_dump_mix(pdevinfo);
-		device_printf(dev, "\n");
-		device_printf(dev, "+-------------------------+\n");
-		device_printf(dev, "| DUMPING Volume Controls |\n");
-		device_printf(dev, "+-------------------------+\n");
-		hdac_dump_ctls(pdevinfo, "Master Volume", SOUND_MASK_VOLUME);
-		hdac_dump_ctls(pdevinfo, "PCM Volume", SOUND_MASK_PCM);
-		hdac_dump_ctls(pdevinfo, "CD Volume", SOUND_MASK_CD);
-		hdac_dump_ctls(pdevinfo, "Microphone Volume", SOUND_MASK_MIC);
-		hdac_dump_ctls(pdevinfo, "Microphone2 Volume", SOUND_MASK_MONITOR);
-		hdac_dump_ctls(pdevinfo, "Line-in Volume", SOUND_MASK_LINE);
-		hdac_dump_ctls(pdevinfo, "Speaker/Beep Volume", SOUND_MASK_SPEAKER);
-		hdac_dump_ctls(pdevinfo, "Recording Level", SOUND_MASK_RECLEV);
-		hdac_dump_ctls(pdevinfo, "Input Mix Level", SOUND_MASK_IMIX);
-		hdac_dump_ctls(pdevinfo, "Input Monitoring Level", SOUND_MASK_IGAIN);
-		hdac_dump_ctls(pdevinfo, NULL, 0);
-		device_printf(dev, "\n");
-	);
-
-	if (resource_int_value(device_get_name(dev),
-	    device_get_unit(dev), "blocksize", &i) == 0 && i > 0) {
-		i &= HDA_BLK_ALIGN;
-		if (i < HDA_BLK_MIN)
-			i = HDA_BLK_MIN;
-		pdevinfo->chan_blkcnt = pdevinfo->chan_size / i;
-		i = 0;
-		while (pdevinfo->chan_blkcnt >> i)
-			i++;
-		pdevinfo->chan_blkcnt = 1 << (i - 1);
-		if (pdevinfo->chan_blkcnt < HDA_BDL_MIN)
-			pdevinfo->chan_blkcnt = HDA_BDL_MIN;
-		else if (pdevinfo->chan_blkcnt > HDA_BDL_MAX)
-			pdevinfo->chan_blkcnt = HDA_BDL_MAX;
-	} else
-		pdevinfo->chan_blkcnt = HDA_BDL_DEFAULT;
-
-	/* 
-	 * We don't register interrupt handler with snd_setup_intr
-	 * in pcm device. Mark pcm device as MPSAFE manually.
-	 */
-	pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
-
-	HDA_BOOTHVERBOSE(
-		device_printf(dev, "OSS mixer initialization...\n");
-	);
-	if (mixer_init(dev, &hdac_audio_ctl_ossmixer_class, pdevinfo) != 0)
-		device_printf(dev, "Can't register mixer\n");
-
-	HDA_BOOTHVERBOSE(
-		device_printf(dev, "Registering PCM channels...\n");
-	);
-	if (pcm_register(dev, pdevinfo, (pdevinfo->play >= 0)?1:0,
-	    (pdevinfo->rec >= 0)?1:0) != 0)
-		device_printf(dev, "Can't register PCM\n");
-
-	pdevinfo->registered++;
-
-	if (pdevinfo->play >= 0)
-		pcm_addchan(dev, PCMDIR_PLAY, &hdac_channel_class, pdevinfo);
-	if (pdevinfo->rec >= 0)
-		pcm_addchan(dev, PCMDIR_REC, &hdac_channel_class, pdevinfo);
-
-	snprintf(status, SND_STATUSLEN, "at cad %d nid %d on %s %s",
-	    pdevinfo->devinfo->codec->cad, pdevinfo->devinfo->nid,
-	    device_get_nameunit(sc->dev), PCM_KLDSTRING(snd_hda));
-	pcm_setstatus(dev, status);
-
-	return (0);
-}
-
-static int
-hdac_pcm_detach(device_t dev)
-{
-	struct hdac_pcm_devinfo *pdevinfo =
-	    (struct hdac_pcm_devinfo *)device_get_ivars(dev);
-	int err;
-
-	if (pdevinfo->registered > 0) {
-		err = pcm_unregister(dev);
-		if (err != 0)
-			return (err);
-	}
-
-	return (0);
-}
-
-static device_method_t hdac_pcm_methods[] = {
-	/* device interface */
-	DEVMETHOD(device_probe,		hdac_pcm_probe),
-	DEVMETHOD(device_attach,	hdac_pcm_attach),
-	DEVMETHOD(device_detach,	hdac_pcm_detach),
-	{ 0, 0 }
-};
-
-static driver_t hdac_pcm_driver = {
-	"pcm",
-	hdac_pcm_methods,
-	PCM_SOFTC_SIZE,
-};
-
-DRIVER_MODULE(snd_hda_pcm, hdac, hdac_pcm_driver, pcm_devclass, 0, 0);
-
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/sound/pci/hda/hdac.h
--- a/head/sys/dev/sound/pci/hda/hdac.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/sound/pci/hda/hdac.h	Mon Jan 16 14:38:30 2012 +0200
@@ -23,46 +23,552 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/sound/pci/hda/hdac.h 230130 2012-01-15 13:21:36Z mav $
  */
 
 #ifndef _HDAC_H_
 #define _HDAC_H_
 
+#include "hdac_if.h"
 
-#if 0
 /****************************************************************************
  * Miscellanious defines
  ****************************************************************************/
 
+/* Controller models */
+#define HDA_MODEL_CONSTRUCT(vendor, model)	\
+		(((uint32_t)(model) << 16) | ((vendor##_VENDORID) & 0xffff))
+
+/* Intel */
+#define INTEL_VENDORID		0x8086
+#define HDA_INTEL_CPT		HDA_MODEL_CONSTRUCT(INTEL, 0x1c20)
+#define HDA_INTEL_PATSBURG	HDA_MODEL_CONSTRUCT(INTEL, 0x1d20)
+#define HDA_INTEL_PPT1		HDA_MODEL_CONSTRUCT(INTEL, 0x1e20)
+#define HDA_INTEL_82801F	HDA_MODEL_CONSTRUCT(INTEL, 0x2668)
+#define HDA_INTEL_63XXESB	HDA_MODEL_CONSTRUCT(INTEL, 0x269a)
+#define HDA_INTEL_82801G	HDA_MODEL_CONSTRUCT(INTEL, 0x27d8)
+#define HDA_INTEL_82801H	HDA_MODEL_CONSTRUCT(INTEL, 0x284b)
+#define HDA_INTEL_82801I	HDA_MODEL_CONSTRUCT(INTEL, 0x293e)
+#define HDA_INTEL_82801JI	HDA_MODEL_CONSTRUCT(INTEL, 0x3a3e)
+#define HDA_INTEL_82801JD	HDA_MODEL_CONSTRUCT(INTEL, 0x3a6e)
+#define HDA_INTEL_PCH		HDA_MODEL_CONSTRUCT(INTEL, 0x3b56)
+#define HDA_INTEL_PCH2		HDA_MODEL_CONSTRUCT(INTEL, 0x3b57)
+#define HDA_INTEL_SCH		HDA_MODEL_CONSTRUCT(INTEL, 0x811b)
+#define HDA_INTEL_ALL		HDA_MODEL_CONSTRUCT(INTEL, 0xffff)
+
+/* Nvidia */
+#define NVIDIA_VENDORID		0x10de
+#define HDA_NVIDIA_MCP51	HDA_MODEL_CONSTRUCT(NVIDIA, 0x026c)
+#define HDA_NVIDIA_MCP55	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0371)
+#define HDA_NVIDIA_MCP61_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x03e4)
+#define HDA_NVIDIA_MCP61_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x03f0)
+#define HDA_NVIDIA_MCP65_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x044a)
+#define HDA_NVIDIA_MCP65_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x044b)
+#define HDA_NVIDIA_MCP67_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x055c)
+#define HDA_NVIDIA_MCP67_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x055d)
+#define HDA_NVIDIA_MCP78_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0774)
+#define HDA_NVIDIA_MCP78_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0775)
+#define HDA_NVIDIA_MCP78_3	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0776)
+#define HDA_NVIDIA_MCP78_4	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0777)
+#define HDA_NVIDIA_MCP73_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x07fc)
+#define HDA_NVIDIA_MCP73_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x07fd)
+#define HDA_NVIDIA_MCP79_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac0)
+#define HDA_NVIDIA_MCP79_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac1)
+#define HDA_NVIDIA_MCP79_3	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac2)
+#define HDA_NVIDIA_MCP79_4	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0ac3)
+#define HDA_NVIDIA_MCP89_1	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d94)
+#define HDA_NVIDIA_MCP89_2	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d95)
+#define HDA_NVIDIA_MCP89_3	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d96)
+#define HDA_NVIDIA_MCP89_4	HDA_MODEL_CONSTRUCT(NVIDIA, 0x0d97)
+#define HDA_NVIDIA_ALL		HDA_MODEL_CONSTRUCT(NVIDIA, 0xffff)
+
+/* ATI */
+#define ATI_VENDORID		0x1002
+#define HDA_ATI_SB450		HDA_MODEL_CONSTRUCT(ATI, 0x437b)
+#define HDA_ATI_SB600		HDA_MODEL_CONSTRUCT(ATI, 0x4383)
+#define HDA_ATI_RS600		HDA_MODEL_CONSTRUCT(ATI, 0x793b)
+#define HDA_ATI_RS690		HDA_MODEL_CONSTRUCT(ATI, 0x7919)
+#define HDA_ATI_RS780		HDA_MODEL_CONSTRUCT(ATI, 0x960f)
+#define HDA_ATI_R600		HDA_MODEL_CONSTRUCT(ATI, 0xaa00)
+#define HDA_ATI_RV630		HDA_MODEL_CONSTRUCT(ATI, 0xaa08)
+#define HDA_ATI_RV610		HDA_MODEL_CONSTRUCT(ATI, 0xaa10)
+#define HDA_ATI_RV670		HDA_MODEL_CONSTRUCT(ATI, 0xaa18)
+#define HDA_ATI_RV635		HDA_MODEL_CONSTRUCT(ATI, 0xaa20)
+#define HDA_ATI_RV620		HDA_MODEL_CONSTRUCT(ATI, 0xaa28)
+#define HDA_ATI_RV770		HDA_MODEL_CONSTRUCT(ATI, 0xaa30)
+#define HDA_ATI_RV730		HDA_MODEL_CONSTRUCT(ATI, 0xaa38)
+#define HDA_ATI_RV710		HDA_MODEL_CONSTRUCT(ATI, 0xaa40)
+#define HDA_ATI_RV740		HDA_MODEL_CONSTRUCT(ATI, 0xaa48)
+#define HDA_ATI_ALL		HDA_MODEL_CONSTRUCT(ATI, 0xffff)
+
+/* RDC */
+#define RDC_VENDORID		0x17f3
+#define HDA_RDC_M3010		HDA_MODEL_CONSTRUCT(RDC, 0x3010)
+
+/* VIA */
+#define VIA_VENDORID		0x1106
+#define HDA_VIA_VT82XX		HDA_MODEL_CONSTRUCT(VIA, 0x3288)
+#define HDA_VIA_ALL		HDA_MODEL_CONSTRUCT(VIA, 0xffff)
+
+/* SiS */
+#define SIS_VENDORID		0x1039
+#define HDA_SIS_966		HDA_MODEL_CONSTRUCT(SIS, 0x7502)
+#define HDA_SIS_ALL		HDA_MODEL_CONSTRUCT(SIS, 0xffff)
+
+/* ULI */
+#define ULI_VENDORID		0x10b9
+#define HDA_ULI_M5461		HDA_MODEL_CONSTRUCT(ULI, 0x5461)
+#define HDA_ULI_ALL		HDA_MODEL_CONSTRUCT(ULI, 0xffff)
+
+/* OEM/subvendors */
+
+/* Intel */
+#define INTEL_D101GGC_SUBVENDOR	HDA_MODEL_CONSTRUCT(INTEL, 0xd600)
+
+/* HP/Compaq */
+#define HP_VENDORID		0x103c
+#define HP_V3000_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x30b5)
+#define HP_NX7400_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x30a2)
+#define HP_NX6310_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x30aa)
+#define HP_NX6325_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x30b0)
+#define HP_XW4300_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x3013)
+#define HP_3010_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x3010)
+#define HP_DV5000_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x30a5)
+#define HP_DC7700S_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x2801)
+#define HP_DC7700_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0x2802)
+#define HP_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(HP, 0xffff)
+/* What is wrong with XN 2563 anyway? (Got the picture ?) */
+#define HP_NX6325_SUBVENDORX	0x103c30b0
+
+/* Dell */
+#define DELL_VENDORID		0x1028
+#define DELL_D630_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x01f9)
+#define DELL_D820_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x01cc)
+#define DELL_V1400_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x0227)
+#define DELL_V1500_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x0228)
+#define DELL_I1300_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x01c9)
+#define DELL_XPSM1210_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x01d7)
+#define DELL_OPLX745_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0x01da)
+#define DELL_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(DELL, 0xffff)
+
+/* Clevo */
+#define CLEVO_VENDORID		0x1558
+#define CLEVO_D900T_SUBVENDOR	HDA_MODEL_CONSTRUCT(CLEVO, 0x0900)
+#define CLEVO_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(CLEVO, 0xffff)
+
+/* Acer */
+#define ACER_VENDORID		0x1025
+#define ACER_A5050_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x010f)
+#define ACER_A4520_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x0127)
+#define ACER_A4710_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x012f)
+#define ACER_A4715_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x0133)
+#define ACER_3681WXM_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x0110)
+#define ACER_T6292_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x011b)
+#define ACER_T5320_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0x011f)
+#define ACER_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(ACER, 0xffff)
+
+/* Asus */
+#define ASUS_VENDORID		0x1043
+#define ASUS_A8X_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1153)
+#define ASUS_U5F_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1263)
+#define ASUS_W6F_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1263)
+#define ASUS_A7M_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1323)
+#define ASUS_F3JC_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1338)
+#define ASUS_G2K_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1339)
+#define ASUS_A7T_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x13c2)
+#define ASUS_W2J_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1971)
+#define ASUS_M5200_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x1993)
+#define ASUS_P5PL2_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x817f)
+#define ASUS_P1AH2_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x81cb)
+#define ASUS_M2NPVMX_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x81cb)
+#define ASUS_M2V_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x81e7)
+#define ASUS_P5BWD_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x81ec)
+#define ASUS_M2N_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0x8234)
+#define ASUS_A8NVMCSM_SUBVENDOR	HDA_MODEL_CONSTRUCT(NVIDIA, 0xcb84)
+#define ASUS_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(ASUS, 0xffff)
+
+/* IBM / Lenovo */
+#define IBM_VENDORID		0x1014
+#define IBM_M52_SUBVENDOR	HDA_MODEL_CONSTRUCT(IBM, 0x02f6)
+#define IBM_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(IBM, 0xffff)
+
+/* Lenovo */
+#define LENOVO_VENDORID		0x17aa
+#define LENOVO_3KN100_SUBVENDOR	HDA_MODEL_CONSTRUCT(LENOVO, 0x2066)
+#define LENOVO_3KN200_SUBVENDOR	HDA_MODEL_CONSTRUCT(LENOVO, 0x384e)
+#define LENOVO_B450_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x3a0d)
+#define LENOVO_TCA55_SUBVENDOR	HDA_MODEL_CONSTRUCT(LENOVO, 0x1015)
+#define LENOVO_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(LENOVO, 0xffff)
+
+/* Samsung */
+#define SAMSUNG_VENDORID	0x144d
+#define SAMSUNG_Q1_SUBVENDOR	HDA_MODEL_CONSTRUCT(SAMSUNG, 0xc027)
+#define SAMSUNG_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(SAMSUNG, 0xffff)
+
+/* Medion ? */
+#define MEDION_VENDORID			0x161f
+#define MEDION_MD95257_SUBVENDOR	HDA_MODEL_CONSTRUCT(MEDION, 0x203d)
+#define MEDION_ALL_SUBVENDOR		HDA_MODEL_CONSTRUCT(MEDION, 0xffff)
+
+/* Apple Computer Inc. */
+#define APPLE_VENDORID		0x106b
+#define APPLE_MB3_SUBVENDOR	HDA_MODEL_CONSTRUCT(APPLE, 0x00a1)
+
+/* Sony */
+#define SONY_VENDORID		0x104d
+#define SONY_S5_SUBVENDOR	HDA_MODEL_CONSTRUCT(SONY, 0x81cc)
+#define SONY_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(SONY, 0xffff)
+
+/*
+ * Apple Intel MacXXXX seems using Sigmatel codec/vendor id
+ * instead of their own, which is beyond my comprehension
+ * (see HDA_CODEC_STAC9221 below).
+ */
+#define APPLE_INTEL_MAC		0x76808384
+#define APPLE_MACBOOKPRO55	0xcb7910de
+
+/* LG Electronics */
+#define LG_VENDORID		0x1854
+#define LG_LW20_SUBVENDOR	HDA_MODEL_CONSTRUCT(LG, 0x0018)
+#define LG_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(LG, 0xffff)
+
+/* Fujitsu Siemens */
+#define FS_VENDORID		0x1734
+#define FS_PA1510_SUBVENDOR	HDA_MODEL_CONSTRUCT(FS, 0x10b8)
+#define FS_SI1848_SUBVENDOR	HDA_MODEL_CONSTRUCT(FS, 0x10cd)
+#define FS_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(FS, 0xffff)
+
+/* Fujitsu Limited */
+#define FL_VENDORID		0x10cf
+#define FL_S7020D_SUBVENDOR	HDA_MODEL_CONSTRUCT(FL, 0x1326)
+#define FL_U1010_SUBVENDOR	HDA_MODEL_CONSTRUCT(FL, 0x142d)
+#define FL_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(FL, 0xffff)
+
+/* Toshiba */
+#define TOSHIBA_VENDORID	0x1179
+#define TOSHIBA_U200_SUBVENDOR	HDA_MODEL_CONSTRUCT(TOSHIBA, 0x0001)
+#define TOSHIBA_A135_SUBVENDOR	HDA_MODEL_CONSTRUCT(TOSHIBA, 0xff01)
+#define TOSHIBA_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(TOSHIBA, 0xffff)
+
+/* Micro-Star International (MSI) */
+#define MSI_VENDORID		0x1462
+#define MSI_MS1034_SUBVENDOR	HDA_MODEL_CONSTRUCT(MSI, 0x0349)
+#define MSI_MS034A_SUBVENDOR	HDA_MODEL_CONSTRUCT(MSI, 0x034a)
+#define MSI_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(MSI, 0xffff)
+
+/* Giga-Byte Technology */
+#define GB_VENDORID		0x1458
+#define GB_G33S2H_SUBVENDOR	HDA_MODEL_CONSTRUCT(GB, 0xa022)
+#define GP_ALL_SUBVENDOR	HDA_MODEL_CONSTRUCT(GB, 0xffff)
+
+/* Uniwill ? */
+#define UNIWILL_VENDORID	0x1584
+#define UNIWILL_9075_SUBVENDOR	HDA_MODEL_CONSTRUCT(UNIWILL, 0x9075)
+#define UNIWILL_9080_SUBVENDOR	HDA_MODEL_CONSTRUCT(UNIWILL, 0x9080)
+
+/* All codecs you can eat... */
+#define HDA_CODEC_CONSTRUCT(vendor, id) \
+		(((uint32_t)(vendor##_VENDORID) << 16) | ((id) & 0xffff))
+
+/* Cirrus Logic */
+#define CIRRUSLOGIC_VENDORID	0x1013
+#define HDA_CODEC_CS4206	HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0x4206)
+#define HDA_CODEC_CS4207	HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0x4207)
+#define HDA_CODEC_CS4210	HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0x4210)
+#define HDA_CODEC_CSXXXX	HDA_CODEC_CONSTRUCT(CIRRUSLOGIC, 0xffff)
+
+/* Realtek */
+#define REALTEK_VENDORID	0x10ec
+#define HDA_CODEC_ALC221	HDA_CODEC_CONSTRUCT(REALTEK, 0x0221)
+#define HDA_CODEC_ALC260	HDA_CODEC_CONSTRUCT(REALTEK, 0x0260)
+#define HDA_CODEC_ALC262	HDA_CODEC_CONSTRUCT(REALTEK, 0x0262)
+#define HDA_CODEC_ALC267	HDA_CODEC_CONSTRUCT(REALTEK, 0x0267)
+#define HDA_CODEC_ALC268	HDA_CODEC_CONSTRUCT(REALTEK, 0x0268)
+#define HDA_CODEC_ALC269	HDA_CODEC_CONSTRUCT(REALTEK, 0x0269)
+#define HDA_CODEC_ALC270	HDA_CODEC_CONSTRUCT(REALTEK, 0x0270)
+#define HDA_CODEC_ALC272	HDA_CODEC_CONSTRUCT(REALTEK, 0x0272)
+#define HDA_CODEC_ALC273	HDA_CODEC_CONSTRUCT(REALTEK, 0x0273)
+#define HDA_CODEC_ALC275	HDA_CODEC_CONSTRUCT(REALTEK, 0x0275)
+#define HDA_CODEC_ALC276	HDA_CODEC_CONSTRUCT(REALTEK, 0x0276)
+#define HDA_CODEC_ALC660	HDA_CODEC_CONSTRUCT(REALTEK, 0x0660)
+#define HDA_CODEC_ALC662	HDA_CODEC_CONSTRUCT(REALTEK, 0x0662)
+#define HDA_CODEC_ALC663	HDA_CODEC_CONSTRUCT(REALTEK, 0x0663)
+#define HDA_CODEC_ALC665	HDA_CODEC_CONSTRUCT(REALTEK, 0x0665)
+#define HDA_CODEC_ALC861	HDA_CODEC_CONSTRUCT(REALTEK, 0x0861)
+#define HDA_CODEC_ALC861VD	HDA_CODEC_CONSTRUCT(REALTEK, 0x0862)
+#define HDA_CODEC_ALC880	HDA_CODEC_CONSTRUCT(REALTEK, 0x0880)
+#define HDA_CODEC_ALC882	HDA_CODEC_CONSTRUCT(REALTEK, 0x0882)
+#define HDA_CODEC_ALC883	HDA_CODEC_CONSTRUCT(REALTEK, 0x0883)
+#define HDA_CODEC_ALC885	HDA_CODEC_CONSTRUCT(REALTEK, 0x0885)
+#define HDA_CODEC_ALC887	HDA_CODEC_CONSTRUCT(REALTEK, 0x0887)
+#define HDA_CODEC_ALC888	HDA_CODEC_CONSTRUCT(REALTEK, 0x0888)
+#define HDA_CODEC_ALC889	HDA_CODEC_CONSTRUCT(REALTEK, 0x0889)
+#define HDA_CODEC_ALC892	HDA_CODEC_CONSTRUCT(REALTEK, 0x0892)
+#define HDA_CODEC_ALC899	HDA_CODEC_CONSTRUCT(REALTEK, 0x0899)
+#define HDA_CODEC_ALCXXXX	HDA_CODEC_CONSTRUCT(REALTEK, 0xffff)
+
+/* Analog Devices */
+#define ANALOGDEVICES_VENDORID	0x11d4
+#define HDA_CODEC_AD1884A	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x184a)
+#define HDA_CODEC_AD1882	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1882)
+#define HDA_CODEC_AD1883	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1883)
+#define HDA_CODEC_AD1884	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1884)
+#define HDA_CODEC_AD1984A	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x194a)
+#define HDA_CODEC_AD1984B	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x194b)
+#define HDA_CODEC_AD1981HD	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1981)
+#define HDA_CODEC_AD1983	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1983)
+#define HDA_CODEC_AD1984	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1984)
+#define HDA_CODEC_AD1986A	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1986)
+#define HDA_CODEC_AD1987	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1987)
+#define HDA_CODEC_AD1988	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1988)
+#define HDA_CODEC_AD1988B	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x198b)
+#define HDA_CODEC_AD1882A	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x882a)
+#define HDA_CODEC_AD1989A	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x989a)
+#define HDA_CODEC_AD1989B	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x989b)
+#define HDA_CODEC_ADXXXX	HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0xffff)
+
+/* CMedia */
+#define CMEDIA_VENDORID		0x434d
+#define HDA_CODEC_CMI9880	HDA_CODEC_CONSTRUCT(CMEDIA, 0x4980)
+#define HDA_CODEC_CMIXXXX	HDA_CODEC_CONSTRUCT(CMEDIA, 0xffff)
+
+/* Sigmatel */
+#define SIGMATEL_VENDORID	0x8384
+#define HDA_CODEC_STAC9230X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7612)
+#define HDA_CODEC_STAC9230D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7613)
+#define HDA_CODEC_STAC9229X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7614)
+#define HDA_CODEC_STAC9229D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7615)
+#define HDA_CODEC_STAC9228X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7616)
+#define HDA_CODEC_STAC9228D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7617)
+#define HDA_CODEC_STAC9227X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7618)
+#define HDA_CODEC_STAC9227D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7619)
+#define HDA_CODEC_STAC9274	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7620)
+#define HDA_CODEC_STAC9274D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7621)
+#define HDA_CODEC_STAC9273X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7622)
+#define HDA_CODEC_STAC9273D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7623)
+#define HDA_CODEC_STAC9272X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7624)
+#define HDA_CODEC_STAC9272D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7625)
+#define HDA_CODEC_STAC9271X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7626)
+#define HDA_CODEC_STAC9271D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7627)
+#define HDA_CODEC_STAC9274X5NH	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7628)
+#define HDA_CODEC_STAC9274D5NH	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7629)
+#define HDA_CODEC_STAC9250	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7634)
+#define HDA_CODEC_STAC9251	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7636)
+#define HDA_CODEC_IDT92HD700X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7638)
+#define HDA_CODEC_IDT92HD700D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7639)
+#define HDA_CODEC_IDT92HD206X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7645)
+#define HDA_CODEC_IDT92HD206D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7646)
+#define HDA_CODEC_CXD9872RDK	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7661)
+#define HDA_CODEC_STAC9872AK	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7662)
+#define HDA_CODEC_CXD9872AKD	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7664)
+#define HDA_CODEC_STAC9221	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7680)
+#define HDA_CODEC_STAC922XD	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7681)
+#define HDA_CODEC_STAC9221_A2	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7682)
+#define HDA_CODEC_STAC9221D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7683)
+#define HDA_CODEC_STAC9220	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7690)
+#define HDA_CODEC_STAC9200D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7691)
+#define HDA_CODEC_IDT92HD005	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7698)
+#define HDA_CODEC_IDT92HD005D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7699)
+#define HDA_CODEC_STAC9205X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x76a0)
+#define HDA_CODEC_STAC9205D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x76a1)
+#define HDA_CODEC_STAC9204X	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x76a2)
+#define HDA_CODEC_STAC9204D	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x76a3)
+#define HDA_CODEC_STAC9220_A2	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7880)
+#define HDA_CODEC_STAC9220_A1	HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7882)
+#define HDA_CODEC_STACXXXX	HDA_CODEC_CONSTRUCT(SIGMATEL, 0xffff)
+
+/* IDT */
+#define IDT_VENDORID		0x111d
+#define HDA_CODEC_IDT92HD75BX	HDA_CODEC_CONSTRUCT(IDT, 0x7603)
+#define HDA_CODEC_IDT92HD83C1X	HDA_CODEC_CONSTRUCT(IDT, 0x7604)
+#define HDA_CODEC_IDT92HD81B1X	HDA_CODEC_CONSTRUCT(IDT, 0x7605)
+#define HDA_CODEC_IDT92HD75B3	HDA_CODEC_CONSTRUCT(IDT, 0x7608)
+#define HDA_CODEC_IDT92HD73D1	HDA_CODEC_CONSTRUCT(IDT, 0x7674)
+#define HDA_CODEC_IDT92HD73C1	HDA_CODEC_CONSTRUCT(IDT, 0x7675)
+#define HDA_CODEC_IDT92HD73E1	HDA_CODEC_CONSTRUCT(IDT, 0x7676)
+#define HDA_CODEC_IDT92HD71B8	HDA_CODEC_CONSTRUCT(IDT, 0x76b0)
+#define HDA_CODEC_IDT92HD71B7	HDA_CODEC_CONSTRUCT(IDT, 0x76b2)
+#define HDA_CODEC_IDT92HD71B5	HDA_CODEC_CONSTRUCT(IDT, 0x76b6)
+#define HDA_CODEC_IDT92HD83C1C	HDA_CODEC_CONSTRUCT(IDT, 0x76d4)
+#define HDA_CODEC_IDT92HD81B1C	HDA_CODEC_CONSTRUCT(IDT, 0x76d5)
+#define HDA_CODEC_IDTXXXX	HDA_CODEC_CONSTRUCT(IDT, 0xffff)
+
+/* Silicon Image */
+#define SII_VENDORID	0x1095
+#define HDA_CODEC_SII1390	HDA_CODEC_CONSTRUCT(SII, 0x1390)
+#define HDA_CODEC_SII1392	HDA_CODEC_CONSTRUCT(SII, 0x1392)
+#define HDA_CODEC_SIIXXXX	HDA_CODEC_CONSTRUCT(SII, 0xffff)
+
+/* Lucent/Agere */
+#define AGERE_VENDORID	0x11c1
+#define HDA_CODEC_AGEREXXXX	HDA_CODEC_CONSTRUCT(AGERE, 0xffff)
+
+/* Conexant */
+#define CONEXANT_VENDORID	0x14f1
+#define HDA_CODEC_CX20549	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5045)
+#define HDA_CODEC_CX20551	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5047)
+#define HDA_CODEC_CX20561	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5051)
+#define HDA_CODEC_CX20582	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5066)
+#define HDA_CODEC_CX20583	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5067)
+#define HDA_CODEC_CX20584	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5068)
+#define HDA_CODEC_CX20585	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5069)
+#define HDA_CODEC_CX20588	HDA_CODEC_CONSTRUCT(CONEXANT, 0x506c)
+#define HDA_CODEC_CX20590	HDA_CODEC_CONSTRUCT(CONEXANT, 0x506e)
+#define HDA_CODEC_CX20631	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5097)
+#define HDA_CODEC_CX20632	HDA_CODEC_CONSTRUCT(CONEXANT, 0x5098)
+#define HDA_CODEC_CX20641	HDA_CODEC_CONSTRUCT(CONEXANT, 0x50a1)
+#define HDA_CODEC_CX20642	HDA_CODEC_CONSTRUCT(CONEXANT, 0x50a2)
+#define HDA_CODEC_CX20651	HDA_CODEC_CONSTRUCT(CONEXANT, 0x50ab)
+#define HDA_CODEC_CX20652	HDA_CODEC_CONSTRUCT(CONEXANT, 0x50ac)
+#define HDA_CODEC_CX20664	HDA_CODEC_CONSTRUCT(CONEXANT, 0x50b8)
+#define HDA_CODEC_CX20665	HDA_CODEC_CONSTRUCT(CONEXANT, 0x50b9)
+#define HDA_CODEC_CXXXXX	HDA_CODEC_CONSTRUCT(CONEXANT, 0xffff)
+
+/* VIA */
+#define HDA_CODEC_VT1708_8	HDA_CODEC_CONSTRUCT(VIA, 0x1708)
+#define HDA_CODEC_VT1708_9	HDA_CODEC_CONSTRUCT(VIA, 0x1709)
+#define HDA_CODEC_VT1708_A	HDA_CODEC_CONSTRUCT(VIA, 0x170a)
+#define HDA_CODEC_VT1708_B	HDA_CODEC_CONSTRUCT(VIA, 0x170b)
+#define HDA_CODEC_VT1709_0	HDA_CODEC_CONSTRUCT(VIA, 0xe710)
+#define HDA_CODEC_VT1709_1	HDA_CODEC_CONSTRUCT(VIA, 0xe711)
+#define HDA_CODEC_VT1709_2	HDA_CODEC_CONSTRUCT(VIA, 0xe712)
+#define HDA_CODEC_VT1709_3	HDA_CODEC_CONSTRUCT(VIA, 0xe713)
+#define HDA_CODEC_VT1709_4	HDA_CODEC_CONSTRUCT(VIA, 0xe714)
+#define HDA_CODEC_VT1709_5	HDA_CODEC_CONSTRUCT(VIA, 0xe715)
+#define HDA_CODEC_VT1709_6	HDA_CODEC_CONSTRUCT(VIA, 0xe716)
+#define HDA_CODEC_VT1709_7	HDA_CODEC_CONSTRUCT(VIA, 0xe717)
+#define HDA_CODEC_VT1708B_0	HDA_CODEC_CONSTRUCT(VIA, 0xe720)
+#define HDA_CODEC_VT1708B_1	HDA_CODEC_CONSTRUCT(VIA, 0xe721)
+#define HDA_CODEC_VT1708B_2	HDA_CODEC_CONSTRUCT(VIA, 0xe722)
+#define HDA_CODEC_VT1708B_3	HDA_CODEC_CONSTRUCT(VIA, 0xe723)
+#define HDA_CODEC_VT1708B_4	HDA_CODEC_CONSTRUCT(VIA, 0xe724)
+#define HDA_CODEC_VT1708B_5	HDA_CODEC_CONSTRUCT(VIA, 0xe725)
+#define HDA_CODEC_VT1708B_6	HDA_CODEC_CONSTRUCT(VIA, 0xe726)
+#define HDA_CODEC_VT1708B_7	HDA_CODEC_CONSTRUCT(VIA, 0xe727)
+#define HDA_CODEC_VT1708S_0	HDA_CODEC_CONSTRUCT(VIA, 0x0397)
+#define HDA_CODEC_VT1708S_1	HDA_CODEC_CONSTRUCT(VIA, 0x1397)
+#define HDA_CODEC_VT1708S_2	HDA_CODEC_CONSTRUCT(VIA, 0x2397)
+#define HDA_CODEC_VT1708S_3	HDA_CODEC_CONSTRUCT(VIA, 0x3397)
+#define HDA_CODEC_VT1708S_4	HDA_CODEC_CONSTRUCT(VIA, 0x4397)
+#define HDA_CODEC_VT1708S_5	HDA_CODEC_CONSTRUCT(VIA, 0x5397)
+#define HDA_CODEC_VT1708S_6	HDA_CODEC_CONSTRUCT(VIA, 0x6397)
+#define HDA_CODEC_VT1708S_7	HDA_CODEC_CONSTRUCT(VIA, 0x7397)
+#define HDA_CODEC_VT1702_0	HDA_CODEC_CONSTRUCT(VIA, 0x0398)
+#define HDA_CODEC_VT1702_1	HDA_CODEC_CONSTRUCT(VIA, 0x1398)
+#define HDA_CODEC_VT1702_2	HDA_CODEC_CONSTRUCT(VIA, 0x2398)
+#define HDA_CODEC_VT1702_3	HDA_CODEC_CONSTRUCT(VIA, 0x3398)
+#define HDA_CODEC_VT1702_4	HDA_CODEC_CONSTRUCT(VIA, 0x4398)
+#define HDA_CODEC_VT1702_5	HDA_CODEC_CONSTRUCT(VIA, 0x5398)
+#define HDA_CODEC_VT1702_6	HDA_CODEC_CONSTRUCT(VIA, 0x6398)
+#define HDA_CODEC_VT1702_7	HDA_CODEC_CONSTRUCT(VIA, 0x7398)
+#define HDA_CODEC_VT1716S_0	HDA_CODEC_CONSTRUCT(VIA, 0x0433)
+#define HDA_CODEC_VT1716S_1	HDA_CODEC_CONSTRUCT(VIA, 0xa721)
+#define HDA_CODEC_VT1718S_0	HDA_CODEC_CONSTRUCT(VIA, 0x0428)
+#define HDA_CODEC_VT1718S_1	HDA_CODEC_CONSTRUCT(VIA, 0x4428)
+#define HDA_CODEC_VT1802_0	HDA_CODEC_CONSTRUCT(VIA, 0x0446)
+#define HDA_CODEC_VT1802_1	HDA_CODEC_CONSTRUCT(VIA, 0x8446)
+#define HDA_CODEC_VT1812	HDA_CODEC_CONSTRUCT(VIA, 0x0448)
+#define HDA_CODEC_VT1818S	HDA_CODEC_CONSTRUCT(VIA, 0x0440)
+#define HDA_CODEC_VT1828S	HDA_CODEC_CONSTRUCT(VIA, 0x4441)
+#define HDA_CODEC_VT2002P_0	HDA_CODEC_CONSTRUCT(VIA, 0x0438)
+#define HDA_CODEC_VT2002P_1	HDA_CODEC_CONSTRUCT(VIA, 0x4438)
+#define HDA_CODEC_VT2020	HDA_CODEC_CONSTRUCT(VIA, 0x0441)
+#define HDA_CODEC_VTXXXX	HDA_CODEC_CONSTRUCT(VIA, 0xffff)
+
+/* ATI */
+#define HDA_CODEC_ATIRS600_1	HDA_CODEC_CONSTRUCT(ATI, 0x793c)
+#define HDA_CODEC_ATIRS600_2	HDA_CODEC_CONSTRUCT(ATI, 0x7919)
+#define HDA_CODEC_ATIRS690	HDA_CODEC_CONSTRUCT(ATI, 0x791a)
+#define HDA_CODEC_ATIR6XX	HDA_CODEC_CONSTRUCT(ATI, 0xaa01)
+#define HDA_CODEC_ATIXXXX	HDA_CODEC_CONSTRUCT(ATI, 0xffff)
+
+/* NVIDIA */
+#define HDA_CODEC_NVIDIAMCP78	HDA_CODEC_CONSTRUCT(NVIDIA, 0x0002)
+#define HDA_CODEC_NVIDIAMCP78_2	HDA_CODEC_CONSTRUCT(NVIDIA, 0x0006)
+#define HDA_CODEC_NVIDIAMCP7A	HDA_CODEC_CONSTRUCT(NVIDIA, 0x0007)
+#define HDA_CODEC_NVIDIAGT220	HDA_CODEC_CONSTRUCT(NVIDIA, 0x000a)
+#define HDA_CODEC_NVIDIAGT21X	HDA_CODEC_CONSTRUCT(NVIDIA, 0x000b)
+#define HDA_CODEC_NVIDIAMCP89	HDA_CODEC_CONSTRUCT(NVIDIA, 0x000c)
+#define HDA_CODEC_NVIDIAGT240	HDA_CODEC_CONSTRUCT(NVIDIA, 0x000d)
+#define HDA_CODEC_NVIDIAMCP67	HDA_CODEC_CONSTRUCT(NVIDIA, 0x0067)
+#define HDA_CODEC_NVIDIAMCP73	HDA_CODEC_CONSTRUCT(NVIDIA, 0x8001)
+#define HDA_CODEC_NVIDIAXXXX	HDA_CODEC_CONSTRUCT(NVIDIA, 0xffff)
+
+/* INTEL */
+#define HDA_CODEC_INTELIP	HDA_CODEC_CONSTRUCT(INTEL, 0x0054)
+#define HDA_CODEC_INTELBL	HDA_CODEC_CONSTRUCT(INTEL, 0x2801)
+#define HDA_CODEC_INTELCA	HDA_CODEC_CONSTRUCT(INTEL, 0x2802)
+#define HDA_CODEC_INTELEL	HDA_CODEC_CONSTRUCT(INTEL, 0x2803)
+#define HDA_CODEC_INTELIP2	HDA_CODEC_CONSTRUCT(INTEL, 0x2804)
+#define HDA_CODEC_INTELCPT	HDA_CODEC_CONSTRUCT(INTEL, 0x2805)
+#define HDA_CODEC_INTELPPT	HDA_CODEC_CONSTRUCT(INTEL, 0x2806)
+#define HDA_CODEC_INTELCL	HDA_CODEC_CONSTRUCT(INTEL, 0x29fb)
+#define HDA_CODEC_INTELXXXX	HDA_CODEC_CONSTRUCT(INTEL, 0xffff)
+
 /****************************************************************************
  * Helper Macros
  ****************************************************************************/
 
+#define HDA_DMA_ALIGNMENT	128
+#define HDA_GPIO_MAX		8
+
+#define HDA_DEV_MATCH(fl, v)	((fl) == (v) || \
+				(fl) == 0xffffffff || \
+				(((fl) & 0xffff0000) == 0xffff0000 && \
+				((fl) & 0x0000ffff) == ((v) & 0x0000ffff)) || \
+				(((fl) & 0x0000ffff) == 0x0000ffff && \
+				((fl) & 0xffff0000) == ((v) & 0xffff0000)))
+#define HDA_MATCH_ALL		0xffffffff
+#define HDA_INVALID		0xffffffff
+
+#define HDA_BOOTVERBOSE(stmt)	do {			\
+	if (bootverbose != 0 || snd_verbose > 3) {	\
+		stmt					\
+	}						\
+} while (0)
+
+#define HDA_BOOTHVERBOSE(stmt)	do {			\
+	if (snd_verbose > 3) {				\
+		stmt					\
+	}						\
+} while (0)
+
+#define hda_command(dev, verb)					\
+    HDAC_CODEC_COMMAND(device_get_parent(dev), (dev), (verb))
+
+typedef int nid_t;
+
 /****************************************************************************
  * Simplified Accessors for HDA devices
  ****************************************************************************/
+
 enum hdac_device_ivars {
-    HDAC_IVAR_CODEC_ID,
-    HDAC_IVAR_NODE_ID,
-    HDAC_IVAR_VENDOR_ID,
-    HDAC_IVAR_DEVICE_ID,
-    HDAC_IVAR_REVISION_ID,
-    HDAC_IVAR_STEPPING_ID,
-    HDAC_IVAR_NODE_TYPE,
+    HDA_IVAR_CODEC_ID,
+    HDA_IVAR_NODE_ID,
+    HDA_IVAR_VENDOR_ID,
+    HDA_IVAR_DEVICE_ID,
+    HDA_IVAR_REVISION_ID,
+    HDA_IVAR_STEPPING_ID,
+    HDA_IVAR_SUBVENDOR_ID,
+    HDA_IVAR_SUBDEVICE_ID,
+    HDA_IVAR_SUBSYSTEM_ID,
+    HDA_IVAR_NODE_TYPE,
+    HDA_IVAR_DMA_NOCACHE,
 };
 
-#define HDAC_ACCESSOR(var, ivar, type)					\
-    __BUS_ACCESSOR(hdac, var, HDAC, ivar, type)
+#define HDA_ACCESSOR(var, ivar, type)					\
+    __BUS_ACCESSOR(hda, var, HDA, ivar, type)
 
-HDAC_ACCESSOR(codec_id,		CODEC_ID,	uint8_t);
-HDAC_ACCESSOR(node_id,		NODE_ID,	uint8_t);
-HDAC_ACCESSOR(vendor_id,	VENDOR_ID,	uint16_t);
-HDAC_ACCESSOR(device_id,	DEVICE_ID,	uint16_t);
-HDAC_ACCESSOR(revision_id,	REVISION_ID,	uint8_t);
-HDAC_ACCESSOR(stepping_id,	STEPPING_ID,	uint8_t);
-HDAC_ACCESSOR(node_type,	NODE_TYPE,	uint8_t);
-#endif
+HDA_ACCESSOR(codec_id,		CODEC_ID,	uint8_t);
+HDA_ACCESSOR(node_id,		NODE_ID,	uint8_t);
+HDA_ACCESSOR(vendor_id,		VENDOR_ID,	uint16_t);
+HDA_ACCESSOR(device_id,		DEVICE_ID,	uint16_t);
+HDA_ACCESSOR(revision_id,	REVISION_ID,	uint8_t);
+HDA_ACCESSOR(stepping_id,	STEPPING_ID,	uint8_t);
+HDA_ACCESSOR(subvendor_id,	SUBVENDOR_ID,	uint16_t);
+HDA_ACCESSOR(subdevice_id,	SUBDEVICE_ID,	uint16_t);
+HDA_ACCESSOR(node_type,		NODE_TYPE,	uint8_t);
+HDA_ACCESSOR(dma_nocache,	DMA_NOCACHE,	uint8_t);
 
 #define PCIS_MULTIMEDIA_HDA    0x03
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/sound/pci/hda/hdac_if.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/sound/pci/hda/hdac_if.m	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,114 @@
+# Copyright (c) 2012 Alexander Motin <mav at FreeBSD.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer,
+#    without modification, immediately at the beginning of the file.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# $FreeBSD: head/sys/dev/sound/pci/hda/hdac_if.m 230130 2012-01-15 13:21:36Z mav $
+
+#include <sys/rman.h>
+
+INTERFACE hdac;
+
+METHOD struct mtx * get_mtx {
+    device_t    dev;
+    device_t    child;
+};
+
+METHOD uint32_t codec_command {
+    device_t    dev;
+    device_t    child;
+    uint32_t    verb;
+};
+
+METHOD int stream_alloc {
+    device_t    dev;
+    device_t    child;
+    int         dir;
+    int         format;
+    uint32_t    **dmapos;
+};
+
+METHOD void stream_free {
+    device_t    dev;
+    device_t    child;
+    int         dir;
+    int         stream;
+};
+
+METHOD int stream_start {
+    device_t    dev;
+    device_t    child;
+    int         dir;
+    int         stream;
+    bus_addr_t  buf;
+    int         blksz;
+    int         blkcnt;
+};
+
+METHOD void stream_stop {
+    device_t    dev;
+    device_t    child;
+    int         dir;
+    int         stream;
+};
+
+METHOD void stream_reset {
+    device_t    dev;
+    device_t    child;
+    int         dir;
+    int         stream;
+};
+
+METHOD uint32_t stream_getptr {
+    device_t    dev;
+    device_t    child;
+    int         dir;
+    int         stream;
+};
+
+METHOD void stream_intr {
+    device_t    dev;
+    int         dir;
+    int         stream;
+};
+
+METHOD int unsol_alloc {
+    device_t    dev;
+    device_t    child;
+    int         wanted;
+};
+
+METHOD void unsol_free {
+    device_t    dev;
+    device_t    child;
+    int         tag;
+};
+
+METHOD void unsol_intr {
+    device_t    dev;
+    uint32_t    resp;
+};
+
+METHOD void pindump {
+    device_t    dev;
+};
+
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/sound/pci/hda/hdac_private.h
--- a/head/sys/dev/sound/pci/hda/hdac_private.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/sound/pci/hda/hdac_private.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2006 Stephane E. Potvin <sepotvin at videotron.ca>
+ * Copyright (c) 2008-2012 Alexander Motin <mav at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,21 +24,17 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/sound/pci/hda/hdac_private.h 230130 2012-01-15 13:21:36Z mav $
  */
 
 #ifndef _HDAC_PRIVATE_H_
 #define _HDAC_PRIVATE_H_
 
-
 /****************************************************************************
  * Miscellaneous defines
  ****************************************************************************/
-#define HDAC_DMA_ALIGNMENT	128
 #define HDAC_CODEC_MAX		16
 
-#define HDAC_MTX_NAME		"hdac driver mutex"
-
 /****************************************************************************
  * Helper Macros
  ****************************************************************************/
@@ -82,7 +79,6 @@
 #define HDAC_BSDBDPL(sc, n)	(_HDAC_BSDBDPL((n), (sc)->num_iss, (sc)->num_oss))
 #define HDAC_BSDBDPU(sc, n)	(_HDAC_BSDBDPU((n), (sc)->num_iss, (sc)->num_oss))
 
-
 /****************************************************************************
  * Custom hdac malloc type
  ****************************************************************************/
@@ -145,22 +141,6 @@
     (((response_ex) & HDAC_RIRB_RESPONSE_EX_SDATA_IN_MASK) >>		\
     HDAC_RIRB_RESPONSE_EX_SDATA_IN_OFFSET)
 
-/****************************************************************************
- * struct hdac_command_list
- *
- * This structure holds the list of verbs that are to be sent to the codec
- * via the corb and the responses received via the rirb. It's allocated by
- * the codec driver and is owned by it.
- ****************************************************************************/
-struct hdac_command_list {
-	int		num_commands;
-	uint32_t	*verbs;
-	uint32_t	*responses;
-};
-
-typedef int nid_t;
-
-struct hdac_softc;
 struct hdac_bdle {
 	volatile uint32_t addrl;
 	volatile uint32_t addrh;
@@ -168,181 +148,36 @@
 	volatile uint32_t ioc;
 } __packed;
 
-#define HDA_MAX_CONNS	32
-#define HDA_MAX_NAMELEN	32
-
-struct hdac_widget {
-	nid_t nid;
-	int type;
-	int enable;
-	int nconns, selconn;
-	int waspin;
-	uint32_t pflags;
-	int bindas;
-	int bindseqmask;
-	int ossdev;
-	uint32_t ossmask;
-	nid_t conns[HDA_MAX_CONNS];
-	u_char connsenable[HDA_MAX_CONNS];
-	char name[HDA_MAX_NAMELEN];
-	struct hdac_devinfo *devinfo;
-	struct {
-		uint32_t widget_cap;
-		uint32_t outamp_cap;
-		uint32_t inamp_cap;
-		uint32_t supp_stream_formats;
-		uint32_t supp_pcm_size_rate;
-		uint32_t eapdbtl;
-	} param;
-	union {
-		struct {
-			uint32_t config;
-			uint32_t cap;
-			uint32_t ctrl;
-		} pin;
-	} wclass;
+struct hdac_stream {
+	device_t	dev;
+	struct hdac_dma	bdl;
+	int		dir;
+	int		stream;
+	int		blksz;
+	int		running;
+	uint16_t	format;
 };
 
-struct hdac_audio_ctl {
-	struct hdac_widget *widget, *childwidget;
-	int enable;
-	int index, dir, ndir;
-	int mute, step, size, offset;
-	int left, right, forcemute;
-	uint32_t muted;
-	uint32_t ossmask, possmask;
-};
-
-/* Association is a group of pins bound for some special function. */
-struct hdac_audio_as {
-	u_char enable;
-	u_char index;
-	u_char dir;
-	u_char pincnt;
-	u_char fakeredir;
-	u_char digital;
-	uint16_t pinset;
-	nid_t hpredir;
-	nid_t pins[16];
-	nid_t dacs[16];
-	int chan;
-};
-
-struct hdac_pcm_devinfo {
-	device_t dev;
-	struct hdac_devinfo *devinfo;
-	int	index;
-	int	registered;
-	int	play, rec;
-	u_char	left[SOUND_MIXER_NRDEVICES];
-	u_char	right[SOUND_MIXER_NRDEVICES];
-	int	chan_size;
-	int	chan_blkcnt;
-	u_char	digital;
-};
-
-/****************************************************************************
- * struct hdac_devinfo
- *
- * Holds all the parameters of a given codec function group. This is stored
- * in the ivar of each child of the hdac bus
- ****************************************************************************/
-struct hdac_devinfo {
-	uint8_t node_type;
-	nid_t nid;
-	nid_t startnode, endnode;
-	int nodecnt;
-	struct hdac_codec *codec;
-	struct hdac_widget *widget;
-	union {
-		struct {
-			uint32_t outamp_cap;
-			uint32_t inamp_cap;
-			uint32_t supp_stream_formats;
-			uint32_t supp_pcm_size_rate;
-			int ctlcnt, ascnt;
-			struct hdac_audio_ctl *ctl;
-			struct hdac_audio_as *as;
-			uint32_t quirks;
-			uint32_t gpio;
-			struct hdac_pcm_devinfo *devs;
-			int num_devs;
-		} audio;
-		/* XXX undefined: modem, hdmi. */
-	} function;
-};
-
-#define HDAC_CHN_RUNNING	0x00000001
-#define HDAC_CHN_SUSPEND	0x00000002
-
-struct hdac_chan {
-	struct snd_dbuf *b;
-	struct pcm_channel *c;
-	struct pcmchan_caps caps;
-	struct hdac_devinfo *devinfo;
-	struct hdac_pcm_devinfo *pdevinfo;
-	struct hdac_dma	bdl_dma;
-	uint32_t spd, fmt, fmtlist[16], pcmrates[16];
-	uint32_t supp_stream_formats, supp_pcm_size_rate;
-	uint32_t ptr, prevptr, blkcnt, blksz;
-	uint32_t *dmapos;
-	uint32_t flags;
-	int dir;
-	int off;
-	int sid;
-	int bit16, bit32;
-	int as;
-	nid_t io[16];
-};
-
-/****************************************************************************
- * struct hdac_codec
- *
- ****************************************************************************/
-struct hdac_codec {
-	int	verbs_sent;
-	int	responses_received;
-	nid_t	cad;
-	uint16_t vendor_id;
-	uint16_t device_id;
-	uint8_t revision_id;
-	uint8_t stepping_id;
-	struct hdac_command_list *commands;
-	struct hdac_softc *sc;
-	struct hdac_devinfo *fgs;
-	int	num_fgs;
-};
-
-/****************************************************************************
- * struct hdac_softc
- *
- * This structure holds the current state of the hdac driver.
- ****************************************************************************/
-
-#define HDAC_F_DMA_NOCACHE	0x00000001
-#define HDAC_F_MSI		0x00000002
-
 struct hdac_softc {
 	device_t	dev;
-	device_t	hdabus;
 	struct mtx	*lock;
 
 	struct intr_config_hook intrhook;
 
 	struct hdac_mem	mem;
 	struct hdac_irq	irq;
-	uint32_t pci_subvendor;
 
+	uint32_t	quirks_on;
+	uint32_t	quirks_off;
 	uint32_t	flags;
+#define HDAC_F_DMA_NOCACHE	0x00000001
 
-	struct hdac_chan	*chans;
-	int		num_chans;
 	int		num_iss;
 	int		num_oss;
 	int		num_bss;
+	int		num_ss;
 	int		num_sdo;
 	int		support_64bit;
-	int		streamcnt;
 
 	int		corb_size;
 	struct hdac_dma corb_dma;
@@ -356,18 +191,13 @@
 
 	bus_dma_tag_t		chan_dmat;
 
-	/*
-	 * Polling
-	 */
+	/* Polling */
 	int			polling;
-	int			poll_ticks;
 	int			poll_ival;
-	struct callout		poll_hda;
-	struct callout		poll_hdac;
-	struct callout		poll_jack;
+	struct callout		poll_callout;
 
+	int			unsol_registered;
 	struct task		unsolq_task;
-
 #define HDAC_UNSOLQ_MAX		64
 #define HDAC_UNSOLQ_READY	0
 #define HDAC_UNSOLQ_BUSY	1
@@ -376,13 +206,17 @@
 	int		unsolq_st;
 	uint32_t	unsolq[HDAC_UNSOLQ_MAX];
 
-	struct hdac_codec *codecs[HDAC_CODEC_MAX];
+	struct hdac_stream	*streams;
+
+	struct {
+		device_t	dev;
+		uint16_t	vendor_id;
+		uint16_t	device_id;
+		uint8_t		revision_id;
+		uint8_t		stepping_id;
+		int		pending;
+		uint32_t	response;
+	} codecs[HDAC_CODEC_MAX];
 };
 
-/****************************************************************************
- * struct hdac_command flags
- ****************************************************************************/
-#define HDAC_COMMAND_FLAG_WAITOK	0x0000
-#define HDAC_COMMAND_FLAG_NOWAIT	0x0001
-
 #endif
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/sound/pci/hda/hdac_reg.h
--- a/head/sys/dev/sound/pci/hda/hdac_reg.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/sound/pci/hda/hdac_reg.h	Mon Jan 16 14:38:30 2012 +0200
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/sound/pci/hda/hdac_reg.h 230130 2012-01-15 13:21:36Z mav $
  */
 
 #ifndef _HDAC_REG_H_
@@ -254,10 +254,10 @@
 #define HDAC_SDCTL_IOCE			0x000004
 #define HDAC_SDCTL_FEIE			0x000008
 #define HDAC_SDCTL_DEIE			0x000010
-#define HDAC_SDCTL_STRIPE_MASK		0x030000
-#define HDAC_SDCTL_STRIPE_SHIFT		16
-#define HDAC_SDCTL_TP			0x040000
-#define HDAC_SDCTL_DIR			0x080000
+#define HDAC_SDCTL2_STRIPE_MASK		0x03
+#define HDAC_SDCTL2_STRIPE_SHIFT	0
+#define HDAC_SDCTL2_TP			0x04
+#define HDAC_SDCTL2_DIR			0x08
 #define HDAC_SDCTL2_STRM_MASK		0xf0
 #define HDAC_SDCTL2_STRM_SHIFT		4
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/sound/pci/hda/hdacc.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/dev/sound/pci/hda/hdacc.c	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,662 @@
+/*-
+ * Copyright (c) 2006 Stephane E. Potvin <sepotvin at videotron.ca>
+ * Copyright (c) 2006 Ariff Abdullah <ariff at FreeBSD.org>
+ * Copyright (c) 2008-2012 Alexander Motin <mav at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Intel High Definition Audio (CODEC) driver for FreeBSD.
+ */
+
+#ifdef HAVE_KERNEL_OPTION_HEADERS
+#include "opt_snd.h"
+#endif
+
+#include <dev/sound/pcm/sound.h>
+
+#include <sys/ctype.h>
+
+#include <dev/sound/pci/hda/hda_reg.h>
+#include <dev/sound/pci/hda/hdac.h>
+
+SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hda/hdacc.c 230130 2012-01-15 13:21:36Z mav $");
+
+struct hdacc_fg {
+	device_t	dev;
+	nid_t		nid;
+	uint8_t		type;
+	uint32_t	subsystem_id;
+};
+
+struct hdacc_softc {
+	device_t	dev;
+	struct mtx	*lock;
+	nid_t		cad;
+	device_t	streams[2][16];
+	device_t	tags[64];
+	int		fgcnt;
+	struct hdacc_fg	*fgs;
+};
+
+#define hdacc_lock(codec)	snd_mtxlock((codec)->lock)
+#define hdacc_unlock(codec)	snd_mtxunlock((codec)->lock)
+#define hdacc_lockassert(codec)	snd_mtxassert((codec)->lock)
+#define hdacc_lockowned(codec)	mtx_owned((codec)->lock)
+
+MALLOC_DEFINE(M_HDACC, "hdacc", "HDA CODEC");
+
+/* CODECs */
+static const struct {
+	uint32_t id;
+	uint16_t revid;
+	char *name;
+} hdacc_codecs[] = {
+	{ HDA_CODEC_CS4206, 0,		"Cirrus Logic CS4206" },
+	{ HDA_CODEC_CS4207, 0,		"Cirrus Logic CS4207" },
+	{ HDA_CODEC_CS4210, 0,		"Cirrus Logic CS4210" },
+	{ HDA_CODEC_ALC221, 0,		"Realtek ALC221" },
+	{ HDA_CODEC_ALC260, 0,		"Realtek ALC260" },
+	{ HDA_CODEC_ALC262, 0,		"Realtek ALC262" },
+	{ HDA_CODEC_ALC267, 0,		"Realtek ALC267" },
+	{ HDA_CODEC_ALC268, 0,		"Realtek ALC268" },
+	{ HDA_CODEC_ALC269, 0,		"Realtek ALC269" },
+	{ HDA_CODEC_ALC270, 0,		"Realtek ALC270" },
+	{ HDA_CODEC_ALC272, 0,		"Realtek ALC272" },
+	{ HDA_CODEC_ALC273, 0,		"Realtek ALC273" },
+	{ HDA_CODEC_ALC275, 0,		"Realtek ALC275" },
+	{ HDA_CODEC_ALC276, 0,		"Realtek ALC276" },
+	{ HDA_CODEC_ALC660, 0,		"Realtek ALC660-VD" },
+	{ HDA_CODEC_ALC662, 0x0002,	"Realtek ALC662 rev2" },
+	{ HDA_CODEC_ALC662, 0,		"Realtek ALC662" },
+	{ HDA_CODEC_ALC663, 0,		"Realtek ALC663" },
+	{ HDA_CODEC_ALC665, 0,		"Realtek ALC665" },
+	{ HDA_CODEC_ALC861, 0x0340,	"Realtek ALC660" },
+	{ HDA_CODEC_ALC861, 0,		"Realtek ALC861" },
+	{ HDA_CODEC_ALC861VD, 0,	"Realtek ALC861-VD" },
+	{ HDA_CODEC_ALC880, 0,		"Realtek ALC880" },
+	{ HDA_CODEC_ALC882, 0,		"Realtek ALC882" },
+	{ HDA_CODEC_ALC883, 0,		"Realtek ALC883" },
+	{ HDA_CODEC_ALC885, 0x0101,	"Realtek ALC889A" },
+	{ HDA_CODEC_ALC885, 0x0103,	"Realtek ALC889A" },
+	{ HDA_CODEC_ALC885, 0,		"Realtek ALC885" },
+	{ HDA_CODEC_ALC887, 0,		"Realtek ALC887" },
+	{ HDA_CODEC_ALC888, 0x0101,	"Realtek ALC1200" },
+	{ HDA_CODEC_ALC888, 0,		"Realtek ALC888" },
+	{ HDA_CODEC_ALC889, 0,		"Realtek ALC889" },
+	{ HDA_CODEC_ALC892, 0,		"Realtek ALC892" },
+	{ HDA_CODEC_ALC899, 0,		"Realtek ALC899" },
+	{ HDA_CODEC_AD1882, 0,		"Analog Devices AD1882" },
+	{ HDA_CODEC_AD1882A, 0,		"Analog Devices AD1882A" },
+	{ HDA_CODEC_AD1883, 0,		"Analog Devices AD1883" },
+	{ HDA_CODEC_AD1884, 0,		"Analog Devices AD1884" },
+	{ HDA_CODEC_AD1884A, 0,		"Analog Devices AD1884A" },
+	{ HDA_CODEC_AD1981HD, 0,	"Analog Devices AD1981HD" },
+	{ HDA_CODEC_AD1983, 0,		"Analog Devices AD1983" },
+	{ HDA_CODEC_AD1984, 0,		"Analog Devices AD1984" },
+	{ HDA_CODEC_AD1984A, 0,		"Analog Devices AD1984A" },
+	{ HDA_CODEC_AD1984B, 0,		"Analog Devices AD1984B" },
+	{ HDA_CODEC_AD1986A, 0,		"Analog Devices AD1986A" },
+	{ HDA_CODEC_AD1987, 0,		"Analog Devices AD1987" },
+	{ HDA_CODEC_AD1988, 0,		"Analog Devices AD1988A" },
+	{ HDA_CODEC_AD1988B, 0,		"Analog Devices AD1988B" },
+	{ HDA_CODEC_AD1989A, 0,		"Analog Devices AD1989A" },
+	{ HDA_CODEC_AD1989B, 0,		"Analog Devices AD1989B" },
+	{ HDA_CODEC_CMI9880, 0,		"CMedia CMI9880" },
+	{ HDA_CODEC_CXD9872RDK, 0,	"Sigmatel CXD9872RD/K" },
+	{ HDA_CODEC_CXD9872AKD, 0,	"Sigmatel CXD9872AKD" },
+	{ HDA_CODEC_STAC9200D, 0,	"Sigmatel STAC9200D" },
+	{ HDA_CODEC_STAC9204X, 0,	"Sigmatel STAC9204X" },
+	{ HDA_CODEC_STAC9204D, 0,	"Sigmatel STAC9204D" },
+	{ HDA_CODEC_STAC9205X, 0,	"Sigmatel STAC9205X" },
+	{ HDA_CODEC_STAC9205D, 0,	"Sigmatel STAC9205D" },
+	{ HDA_CODEC_STAC9220, 0,	"Sigmatel STAC9220" },
+	{ HDA_CODEC_STAC9220_A1, 0,	"Sigmatel STAC9220_A1" },
+	{ HDA_CODEC_STAC9220_A2, 0,	"Sigmatel STAC9220_A2" },
+	{ HDA_CODEC_STAC9221, 0,	"Sigmatel STAC9221" },
+	{ HDA_CODEC_STAC9221_A2, 0,	"Sigmatel STAC9221_A2" },
+	{ HDA_CODEC_STAC9221D, 0,	"Sigmatel STAC9221D" },
+	{ HDA_CODEC_STAC922XD, 0,	"Sigmatel STAC9220D/9223D" },
+	{ HDA_CODEC_STAC9227X, 0,	"Sigmatel STAC9227X" },
+	{ HDA_CODEC_STAC9227D, 0,	"Sigmatel STAC9227D" },
+	{ HDA_CODEC_STAC9228X, 0,	"Sigmatel STAC9228X" },
+	{ HDA_CODEC_STAC9228D, 0,	"Sigmatel STAC9228D" },
+	{ HDA_CODEC_STAC9229X, 0,	"Sigmatel STAC9229X" },
+	{ HDA_CODEC_STAC9229D, 0,	"Sigmatel STAC9229D" },
+	{ HDA_CODEC_STAC9230X, 0,	"Sigmatel STAC9230X" },
+	{ HDA_CODEC_STAC9230D, 0,	"Sigmatel STAC9230D" },
+	{ HDA_CODEC_STAC9250, 0, 	"Sigmatel STAC9250" },
+	{ HDA_CODEC_STAC9251, 0, 	"Sigmatel STAC9251" },
+	{ HDA_CODEC_STAC9271X, 0,	"Sigmatel STAC9271X" },
+	{ HDA_CODEC_STAC9271D, 0,	"Sigmatel STAC9271D" },
+	{ HDA_CODEC_STAC9272X, 0,	"Sigmatel STAC9272X" },
+	{ HDA_CODEC_STAC9272D, 0,	"Sigmatel STAC9272D" },
+	{ HDA_CODEC_STAC9273X, 0,	"Sigmatel STAC9273X" },
+	{ HDA_CODEC_STAC9273D, 0,	"Sigmatel STAC9273D" },
+	{ HDA_CODEC_STAC9274, 0, 	"Sigmatel STAC9274" },
+	{ HDA_CODEC_STAC9274D, 0,	"Sigmatel STAC9274D" },
+	{ HDA_CODEC_STAC9274X5NH, 0,	"Sigmatel STAC9274X5NH" },
+	{ HDA_CODEC_STAC9274D5NH, 0,	"Sigmatel STAC9274D5NH" },
+	{ HDA_CODEC_STAC9872AK, 0,	"Sigmatel STAC9872AK" },
+	{ HDA_CODEC_IDT92HD005, 0,	"IDT 92HD005" },
+	{ HDA_CODEC_IDT92HD005D, 0,	"IDT 92HD005D" },
+	{ HDA_CODEC_IDT92HD206X, 0,	"IDT 92HD206X" },
+	{ HDA_CODEC_IDT92HD206D, 0,	"IDT 92HD206D" },
+	{ HDA_CODEC_IDT92HD700X, 0,	"IDT 92HD700X" },
+	{ HDA_CODEC_IDT92HD700D, 0,	"IDT 92HD700D" },
+	{ HDA_CODEC_IDT92HD71B5, 0,	"IDT 92HD71B5" },
+	{ HDA_CODEC_IDT92HD71B7, 0,	"IDT 92HD71B7" },
+	{ HDA_CODEC_IDT92HD71B8, 0,	"IDT 92HD71B8" },
+	{ HDA_CODEC_IDT92HD73C1, 0,	"IDT 92HD73C1" },
+	{ HDA_CODEC_IDT92HD73D1, 0,	"IDT 92HD73D1" },
+	{ HDA_CODEC_IDT92HD73E1, 0,	"IDT 92HD73E1" },
+	{ HDA_CODEC_IDT92HD75B3, 0,	"IDT 92HD75B3" },
+	{ HDA_CODEC_IDT92HD75BX, 0,	"IDT 92HD75BX" },
+	{ HDA_CODEC_IDT92HD81B1C, 0,	"IDT 92HD81B1C" },
+	{ HDA_CODEC_IDT92HD81B1X, 0,	"IDT 92HD81B1X" },
+	{ HDA_CODEC_IDT92HD83C1C, 0,	"IDT 92HD83C1C" },
+	{ HDA_CODEC_IDT92HD83C1X, 0,	"IDT 92HD83C1X" },
+	{ HDA_CODEC_CX20549, 0,		"Conexant CX20549 (Venice)" },
+	{ HDA_CODEC_CX20551, 0,		"Conexant CX20551 (Waikiki)" },
+	{ HDA_CODEC_CX20561, 0,		"Conexant CX20561 (Hermosa)" },
+	{ HDA_CODEC_CX20582, 0,		"Conexant CX20582 (Pebble)" },
+	{ HDA_CODEC_CX20583, 0,		"Conexant CX20583 (Pebble HSF)" },
+	{ HDA_CODEC_CX20584, 0,		"Conexant CX20584" },
+	{ HDA_CODEC_CX20585, 0,		"Conexant CX20585" },
+	{ HDA_CODEC_CX20588, 0,		"Conexant CX20588" },
+	{ HDA_CODEC_CX20590, 0,		"Conexant CX20590" },
+	{ HDA_CODEC_CX20631, 0,		"Conexant CX20631" },
+	{ HDA_CODEC_CX20632, 0,		"Conexant CX20632" },
+	{ HDA_CODEC_CX20641, 0,		"Conexant CX20641" },
+	{ HDA_CODEC_CX20642, 0,		"Conexant CX20642" },
+	{ HDA_CODEC_CX20651, 0,		"Conexant CX20651" },
+	{ HDA_CODEC_CX20652, 0,		"Conexant CX20652" },
+	{ HDA_CODEC_CX20664, 0,		"Conexant CX20664" },
+	{ HDA_CODEC_CX20665, 0,		"Conexant CX20665" },
+	{ HDA_CODEC_VT1708_8, 0,	"VIA VT1708_8" },
+	{ HDA_CODEC_VT1708_9, 0,	"VIA VT1708_9" },
+	{ HDA_CODEC_VT1708_A, 0,	"VIA VT1708_A" },
+	{ HDA_CODEC_VT1708_B, 0,	"VIA VT1708_B" },
+	{ HDA_CODEC_VT1709_0, 0,	"VIA VT1709_0" },
+	{ HDA_CODEC_VT1709_1, 0,	"VIA VT1709_1" },
+	{ HDA_CODEC_VT1709_2, 0,	"VIA VT1709_2" },
+	{ HDA_CODEC_VT1709_3, 0,	"VIA VT1709_3" },
+	{ HDA_CODEC_VT1709_4, 0,	"VIA VT1709_4" },
+	{ HDA_CODEC_VT1709_5, 0,	"VIA VT1709_5" },
+	{ HDA_CODEC_VT1709_6, 0,	"VIA VT1709_6" },
+	{ HDA_CODEC_VT1709_7, 0,	"VIA VT1709_7" },
+	{ HDA_CODEC_VT1708B_0, 0,	"VIA VT1708B_0" },
+	{ HDA_CODEC_VT1708B_1, 0,	"VIA VT1708B_1" },
+	{ HDA_CODEC_VT1708B_2, 0,	"VIA VT1708B_2" },
+	{ HDA_CODEC_VT1708B_3, 0,	"VIA VT1708B_3" },
+	{ HDA_CODEC_VT1708B_4, 0,	"VIA VT1708B_4" },
+	{ HDA_CODEC_VT1708B_5, 0,	"VIA VT1708B_5" },
+	{ HDA_CODEC_VT1708B_6, 0,	"VIA VT1708B_6" },
+	{ HDA_CODEC_VT1708B_7, 0,	"VIA VT1708B_7" },
+	{ HDA_CODEC_VT1708S_0, 0,	"VIA VT1708S_0" },
+	{ HDA_CODEC_VT1708S_1, 0,	"VIA VT1708S_1" },
+	{ HDA_CODEC_VT1708S_2, 0,	"VIA VT1708S_2" },
+	{ HDA_CODEC_VT1708S_3, 0,	"VIA VT1708S_3" },
+	{ HDA_CODEC_VT1708S_4, 0,	"VIA VT1708S_4" },
+	{ HDA_CODEC_VT1708S_5, 0,	"VIA VT1708S_5" },
+	{ HDA_CODEC_VT1708S_6, 0,	"VIA VT1708S_6" },
+	{ HDA_CODEC_VT1708S_7, 0,	"VIA VT1708S_7" },
+	{ HDA_CODEC_VT1702_0, 0,	"VIA VT1702_0" },
+	{ HDA_CODEC_VT1702_1, 0,	"VIA VT1702_1" },
+	{ HDA_CODEC_VT1702_2, 0,	"VIA VT1702_2" },
+	{ HDA_CODEC_VT1702_3, 0,	"VIA VT1702_3" },
+	{ HDA_CODEC_VT1702_4, 0,	"VIA VT1702_4" },
+	{ HDA_CODEC_VT1702_5, 0,	"VIA VT1702_5" },
+	{ HDA_CODEC_VT1702_6, 0,	"VIA VT1702_6" },
+	{ HDA_CODEC_VT1702_7, 0,	"VIA VT1702_7" },
+	{ HDA_CODEC_VT1716S_0, 0,	"VIA VT1716S_0" },
+	{ HDA_CODEC_VT1716S_1, 0,	"VIA VT1716S_1" },
+	{ HDA_CODEC_VT1718S_0, 0,	"VIA VT1718S_0" },
+	{ HDA_CODEC_VT1718S_1, 0,	"VIA VT1718S_1" },
+	{ HDA_CODEC_VT1802_0, 0,	"VIA VT1802_0" },
+	{ HDA_CODEC_VT1802_1, 0,	"VIA VT1802_1" },
+	{ HDA_CODEC_VT1812, 0,		"VIA VT1812" },
+	{ HDA_CODEC_VT1818S, 0,		"VIA VT1818S" },
+	{ HDA_CODEC_VT1828S, 0,		"VIA VT1828S" },
+	{ HDA_CODEC_VT2002P_0, 0,	"VIA VT2002P_0" },
+	{ HDA_CODEC_VT2002P_1, 0,	"VIA VT2002P_1" },
+	{ HDA_CODEC_VT2020, 0,		"VIA VT2020" },
+	{ HDA_CODEC_ATIRS600_1, 0,	"ATI RS600" },
+	{ HDA_CODEC_ATIRS600_2, 0,	"ATI RS600" },
+	{ HDA_CODEC_ATIRS690, 0,	"ATI RS690/780" },
+	{ HDA_CODEC_ATIR6XX, 0,		"ATI R6xx" },
+	{ HDA_CODEC_NVIDIAMCP67, 0,	"NVIDIA MCP67" },
+	{ HDA_CODEC_NVIDIAMCP73, 0,	"NVIDIA MCP73" },
+	{ HDA_CODEC_NVIDIAMCP78, 0,	"NVIDIA MCP78" },
+	{ HDA_CODEC_NVIDIAMCP78_2, 0,	"NVIDIA MCP78" },
+	{ HDA_CODEC_NVIDIAMCP7A, 0,	"NVIDIA MCP7A" },
+	{ HDA_CODEC_NVIDIAGT220, 0,	"NVIDIA GT220" },
+	{ HDA_CODEC_NVIDIAGT21X, 0,	"NVIDIA GT21x" },
+	{ HDA_CODEC_NVIDIAMCP89, 0,	"NVIDIA MCP89" },
+	{ HDA_CODEC_NVIDIAGT240, 0,	"NVIDIA GT240" },
+	{ HDA_CODEC_INTELIP, 0,		"Intel Ibex Peak" },
+	{ HDA_CODEC_INTELBL, 0,		"Intel Bearlake" },
+	{ HDA_CODEC_INTELCA, 0,		"Intel Cantiga" },
+	{ HDA_CODEC_INTELEL, 0,		"Intel Eaglelake" },
+	{ HDA_CODEC_INTELIP2, 0,	"Intel Ibex Peak" },
+	{ HDA_CODEC_INTELCPT, 0,	"Intel Cougar Point" },
+	{ HDA_CODEC_INTELPPT, 0,	"Intel Panther Point" },
+	{ HDA_CODEC_INTELCL, 0,		"Intel Crestline" },
+	{ HDA_CODEC_SII1390, 0,		"Silicon Image SiI1390" },
+	{ HDA_CODEC_SII1392, 0,		"Silicon Image SiI1392" },
+	/* Unknown CODECs */
+	{ HDA_CODEC_ALCXXXX, 0,		"Realtek (Unknown)" },
+	{ HDA_CODEC_ADXXXX, 0,		"Analog Devices (Unknown)" },
+	{ HDA_CODEC_CSXXXX, 0,		"Cirrus Logic (Unknown)" },
+	{ HDA_CODEC_CMIXXXX, 0,		"CMedia (Unknown)" },
+	{ HDA_CODEC_STACXXXX, 0,	"Sigmatel (Unknown)" },
+	{ HDA_CODEC_SIIXXXX, 0,		"Silicon Image (Unknown)" },
+	{ HDA_CODEC_AGEREXXXX, 0,	"Lucent/Agere Systems (Unknown)" },
+	{ HDA_CODEC_CXXXXX, 0,		"Conexant (Unknown)" },
+	{ HDA_CODEC_VTXXXX, 0,		"VIA (Unknown)" },
+	{ HDA_CODEC_ATIXXXX, 0,		"ATI (Unknown)" },
+	{ HDA_CODEC_NVIDIAXXXX, 0,	"NVIDIA (Unknown)" },
+	{ HDA_CODEC_INTELXXXX, 0,	"Intel (Unknown)" },
+	{ HDA_CODEC_IDTXXXX, 0,		"IDT (Unknown)" },
+};
+#define HDACC_CODECS_LEN	(sizeof(hdacc_codecs) / sizeof(hdacc_codecs[0]))
+
+
+/****************************************************************************
+ * Function prototypes
+ ****************************************************************************/
+
+static char *
+hdacc_codec_name(uint32_t id, uint16_t revid)
+{
+	int i;
+
+	for (i = 0; i < HDACC_CODECS_LEN; i++) {
+		if (!HDA_DEV_MATCH(hdacc_codecs[i].id, id))
+			continue;
+		if (hdacc_codecs[i].revid != 0 &&
+		    hdacc_codecs[i].revid != revid)
+			continue;
+		return (hdacc_codecs[i].name);
+	}
+
+	return ((id == 0x00000000) ? "NULL CODEC" : "Unknown CODEC");
+}
+
+static int
+hdacc_suspend(device_t dev)
+{
+
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Suspend...\n");
+	);
+	bus_generic_suspend(dev);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Suspend done\n");
+	);
+	return (0);
+}
+
+static int
+hdacc_resume(device_t dev)
+{
+
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Resume...\n");
+	);
+	bus_generic_resume(dev);
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Resume done\n");
+	);
+	return (0);
+}
+
+static int
+hdacc_probe(device_t dev)
+{
+	uint32_t id, revid;
+	char buf[128];
+
+	id = ((uint32_t)hda_get_vendor_id(dev) << 16) + hda_get_device_id(dev);
+	revid = ((uint32_t)hda_get_revision_id(dev) << 8) + hda_get_stepping_id(dev);
+	snprintf(buf, sizeof(buf), "%s HDA CODEC", hdacc_codec_name(id, revid));
+	device_set_desc_copy(dev, buf);
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+hdacc_attach(device_t dev)
+{
+	struct hdacc_softc *codec = device_get_softc(dev);
+	device_t child;
+	int cad = (intptr_t)device_get_ivars(dev);
+	uint32_t subnode;
+	int startnode;
+	int endnode;
+	int i, n;
+
+	codec->lock = HDAC_GET_MTX(device_get_parent(dev), dev);
+	codec->dev = dev;
+	codec->cad = cad;
+
+	hdacc_lock(codec);
+	subnode = hda_command(dev,
+	    HDA_CMD_GET_PARAMETER(0, 0x0, HDA_PARAM_SUB_NODE_COUNT));
+	hdacc_unlock(codec);
+	if (subnode == HDA_INVALID)
+		return (EIO);
+	codec->fgcnt = HDA_PARAM_SUB_NODE_COUNT_TOTAL(subnode);
+	startnode = HDA_PARAM_SUB_NODE_COUNT_START(subnode);
+	endnode = startnode + codec->fgcnt;
+
+	HDA_BOOTVERBOSE(
+		device_printf(dev,
+		    "Root Node at nid=0: %d subnodes %d-%d\n",
+		    HDA_PARAM_SUB_NODE_COUNT_TOTAL(subnode),
+		    startnode, endnode - 1);
+	);
+
+	codec->fgs = malloc(sizeof(struct hdacc_fg) * codec->fgcnt,
+	    M_HDACC, M_ZERO | M_WAITOK);
+	for (i = startnode, n = 0; i < endnode; i++, n++) {
+		codec->fgs[n].nid = i;
+		hdacc_lock(codec);
+		codec->fgs[n].type =
+		    HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE(hda_command(dev,
+		    HDA_CMD_GET_PARAMETER(0, i, HDA_PARAM_FCT_GRP_TYPE)));
+		codec->fgs[n].subsystem_id = hda_command(dev,
+		    HDA_CMD_GET_SUBSYSTEM_ID(0, i));
+		hdacc_unlock(codec);
+		codec->fgs[n].dev = child = device_add_child(dev, NULL, -1);
+		if (child == NULL) {
+			device_printf(dev, "Failed to add function device\n");
+			continue;
+		}
+		device_set_ivars(child, &codec->fgs[n]);
+	}
+
+	bus_generic_attach(dev);
+
+	return (0);
+}
+
+static int
+hdacc_detach(device_t dev)
+{
+
+	return (device_delete_children(dev));
+}
+
+static int
+hdacc_child_location_str(device_t dev, device_t child, char *buf,
+    size_t buflen)
+{
+	struct hdacc_fg *fg = device_get_ivars(child);
+
+	snprintf(buf, buflen, "nid=%d", fg->nid);
+	return (0);
+}
+
+static int
+hdacc_child_pnpinfo_str_method(device_t dev, device_t child, char *buf,
+    size_t buflen)
+{
+	struct hdacc_fg *fg = device_get_ivars(child);
+
+	snprintf(buf, buflen, "type=0x%02x subsystem=0x%08x",
+	    fg->type, fg->subsystem_id);
+	return (0);
+}
+
+static int
+hdacc_print_child(device_t dev, device_t child)
+{
+	struct hdacc_fg *fg = device_get_ivars(child);
+	int retval;
+
+	retval = bus_print_child_header(dev, child);
+	retval += printf(" at nid %d", fg->nid);
+	retval += bus_print_child_footer(dev, child);
+
+	return (retval);
+}
+
+static void
+hdacc_probe_nomatch(device_t dev, device_t child)
+{
+	struct hdacc_softc *codec = device_get_softc(dev);
+	struct hdacc_fg *fg = device_get_ivars(child);
+
+	device_printf(child, "<%s %s Function Group> at nid %d on %s "
+	    "(no driver attached)\n",
+	    device_get_desc(dev),
+	    fg->type == HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO ? "Audio" :
+	    (fg->type == HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_MODEM ? "Modem" :
+	    "Unknown"), fg->nid, device_get_nameunit(dev));
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "Power down FG nid=%d to the D3 state...\n",
+		    fg->nid);
+	);
+	hdacc_lock(codec);
+	hda_command(dev, HDA_CMD_SET_POWER_STATE(0,
+	    fg->nid, HDA_CMD_POWER_STATE_D3));
+	hdacc_unlock(codec);
+}
+
+static int
+hdacc_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+	struct hdacc_fg *fg = device_get_ivars(child);
+
+	switch (which) {
+	case HDA_IVAR_NODE_ID:
+		*result = fg->nid;
+		break;
+	case HDA_IVAR_NODE_TYPE:
+		*result = fg->type;
+		break;
+	case HDA_IVAR_SUBSYSTEM_ID:
+		*result = fg->subsystem_id;
+		break;
+	default:
+		return(BUS_READ_IVAR(device_get_parent(dev), dev,
+		    which, result));
+	}
+	return (0);
+}
+
+static struct mtx *
+hdacc_get_mtx(device_t dev, device_t child)
+{
+	struct hdacc_softc *codec = device_get_softc(dev);
+
+	return (codec->lock);
+}
+
+static uint32_t
+hdacc_codec_command(device_t dev, device_t child, uint32_t verb)
+{
+
+	return (HDAC_CODEC_COMMAND(device_get_parent(dev), dev, verb));
+}
+
+static int
+hdacc_stream_alloc(device_t dev, device_t child, int dir, int format,
+    uint32_t **dmapos)
+{
+	struct hdacc_softc *codec = device_get_softc(dev);
+	int stream;
+
+	stream = HDAC_STREAM_ALLOC(device_get_parent(dev), dev,
+	    dir, format, dmapos);
+	if (stream > 0)
+		codec->streams[dir][stream] = child;
+	return (stream);
+}
+
+static void
+hdacc_stream_free(device_t dev, device_t child, int dir, int stream)
+{
+	struct hdacc_softc *codec = device_get_softc(dev);
+
+	codec->streams[dir][stream] = NULL;
+	HDAC_STREAM_FREE(device_get_parent(dev), dev, dir, stream);
+}
+
+static int
+hdacc_stream_start(device_t dev, device_t child,
+    int dir, int stream, bus_addr_t buf, int blksz, int blkcnt)
+{
+
+	return (HDAC_STREAM_START(device_get_parent(dev), dev,
+	    dir, stream, buf, blksz, blkcnt));
+}
+
+static void
+hdacc_stream_stop(device_t dev, device_t child, int dir, int stream)
+{
+
+	HDAC_STREAM_STOP(device_get_parent(dev), dev, dir, stream);
+}
+
+static void
+hdacc_stream_reset(device_t dev, device_t child, int dir, int stream)
+{
+
+	HDAC_STREAM_RESET(device_get_parent(dev), dev, dir, stream);
+}
+
+static uint32_t
+hdacc_stream_getptr(device_t dev, device_t child, int dir, int stream)
+{
+
+	return (HDAC_STREAM_GETPTR(device_get_parent(dev), dev, dir, stream));
+}
+
+static void
+hdacc_stream_intr(device_t dev, int dir, int stream)
+{
+	struct hdacc_softc *codec = device_get_softc(dev);
+	device_t child;
+
+	if ((child = codec->streams[dir][stream]) != NULL);
+		HDAC_STREAM_INTR(child, dir, stream);
+}
+
+static int
+hdacc_unsol_alloc(device_t dev, device_t child, int wanted)
+{
+	struct hdacc_softc *codec = device_get_softc(dev);
+	int tag;
+
+	wanted &= 0x3f;
+	tag = wanted;
+	do {
+		if (codec->tags[tag] == NULL) {
+			codec->tags[tag] = child;
+			HDAC_UNSOL_ALLOC(device_get_parent(dev), dev, tag);
+			return (tag);
+		}
+		tag++;
+		tag &= 0x3f;
+	} while (tag != wanted);
+	return (-1);
+}
+
+static void
+hdacc_unsol_free(device_t dev, device_t child, int tag)
+{
+	struct hdacc_softc *codec = device_get_softc(dev);
+
+	KASSERT(tag >= 0 && tag <= 0x3f, ("Wrong tag value %d\n", tag));
+	codec->tags[tag] = NULL;
+	HDAC_UNSOL_FREE(device_get_parent(dev), dev, tag);
+}
+
+static void
+hdacc_unsol_intr(device_t dev, uint32_t resp)
+{
+	struct hdacc_softc *codec = device_get_softc(dev);
+	device_t child;
+	int tag;
+
+	tag = resp >> 26;
+	if ((child = codec->tags[tag]) != NULL)
+		HDAC_UNSOL_INTR(child, resp);
+	else
+		device_printf(codec->dev, "Unexpected unsolicited "
+		    "response with tag %d: %08x\n", tag, resp);
+}
+
+static void
+hdacc_pindump(device_t dev)
+{
+	device_t *devlist;
+	int devcount, i;
+
+	if (device_get_children(dev, &devlist, &devcount) != 0)
+		return;
+	for (i = 0; i < devcount; i++)
+		HDAC_PINDUMP(devlist[i]);
+	free(devlist, M_TEMP);
+}
+
+static device_method_t hdacc_methods[] = {
+	/* device interface */
+	DEVMETHOD(device_probe,		hdacc_probe),
+	DEVMETHOD(device_attach,	hdacc_attach),
+	DEVMETHOD(device_detach,	hdacc_detach),
+	DEVMETHOD(device_suspend,	hdacc_suspend),
+	DEVMETHOD(device_resume,	hdacc_resume),
+	/* Bus interface */
+	DEVMETHOD(bus_child_location_str, hdacc_child_location_str),
+	DEVMETHOD(bus_child_pnpinfo_str, hdacc_child_pnpinfo_str_method),
+	DEVMETHOD(bus_print_child,	hdacc_print_child),
+	DEVMETHOD(bus_probe_nomatch,	hdacc_probe_nomatch),
+	DEVMETHOD(bus_read_ivar,	hdacc_read_ivar),
+	DEVMETHOD(hdac_get_mtx,		hdacc_get_mtx),
+	DEVMETHOD(hdac_codec_command,	hdacc_codec_command),
+	DEVMETHOD(hdac_stream_alloc,	hdacc_stream_alloc),
+	DEVMETHOD(hdac_stream_free,	hdacc_stream_free),
+	DEVMETHOD(hdac_stream_start,	hdacc_stream_start),
+	DEVMETHOD(hdac_stream_stop,	hdacc_stream_stop),
+	DEVMETHOD(hdac_stream_reset,	hdacc_stream_reset),
+	DEVMETHOD(hdac_stream_getptr,	hdacc_stream_getptr),
+	DEVMETHOD(hdac_stream_intr,	hdacc_stream_intr),
+	DEVMETHOD(hdac_unsol_alloc,	hdacc_unsol_alloc),
+	DEVMETHOD(hdac_unsol_free,	hdacc_unsol_free),
+	DEVMETHOD(hdac_unsol_intr,	hdacc_unsol_intr),
+	DEVMETHOD(hdac_pindump,		hdacc_pindump),
+	{ 0, 0 }
+};
+
+static driver_t hdacc_driver = {
+	"hdacc",
+	hdacc_methods,
+	sizeof(struct hdacc_softc),
+};
+
+static devclass_t hdacc_devclass;
+
+DRIVER_MODULE(snd_hda, hdac, hdacc_driver, hdacc_devclass, 0, 0);
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/syscons/blank/blank_saver.c
--- a/head/sys/dev/syscons/blank/blank_saver.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/syscons/blank/blank_saver.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1995-1998 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/syscons/blank/blank_saver.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/syscons/fade/fade_saver.c
--- a/head/sys/dev/syscons/fade/fade_saver.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/syscons/fade/fade_saver.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1995-1998 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/syscons/fade/fade_saver.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/syscons/green/green_saver.c
--- a/head/sys/dev/syscons/green/green_saver.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/syscons/green/green_saver.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1995-1998 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/syscons/green/green_saver.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/syscons/logo/logo_saver.c
--- a/head/sys/dev/syscons/logo/logo_saver.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/syscons/logo/logo_saver.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
+ * Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/syscons/logo/logo_saver.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/syscons/rain/rain_saver.c
--- a/head/sys/dev/syscons/rain/rain_saver.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/syscons/rain/rain_saver.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
+ * Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/syscons/rain/rain_saver.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/syscons/schistory.c
--- a/head/sys/dev/syscons/schistory.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/syscons/schistory.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 1999 Kazutaka YOKOTA <yokota at zodiac.mech.utsunomiya-u.ac.jp>
- * Copyright (c) 1992-1998 Søren Schmidt
+ * Copyright (c) 1992-1998 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/syscons/schistory.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_syscons.h"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/syscons/snake/snake_saver.c
--- a/head/sys/dev/syscons/snake/snake_saver.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/syscons/snake/snake_saver.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1995-1998 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/syscons/snake/snake_saver.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/syscons/star/star_saver.c
--- a/head/sys/dev/syscons/star/star_saver.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/syscons/star/star_saver.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1995-1998 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/syscons/star/star_saver.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/syscons/syscons.c
--- a/head/sys/dev/syscons/syscons.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/syscons/syscons.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1992-1998 Søren Schmidt
+ * Copyright (c) 1992-1998 Søren Schmidt
  * All rights reserved.
  *
  * This code is derived from software contributed to The DragonFly Project
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/syscons/syscons.c 228767 2011-12-21 12:21:22Z avg $");
+__FBSDID("$FreeBSD: head/sys/dev/syscons/syscons.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_compat.h"
 #include "opt_syscons.h"
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/syscons/syscons.h
--- a/head/sys/dev/syscons/syscons.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/syscons/syscons.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1995-1998 Søren Schmidt
+ * Copyright (c) 1995-1998 Søren Schmidt
  * All rights reserved.
  *
  * This code is derived from software contributed to The DragonFly Project
@@ -28,7 +28,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/dev/syscons/syscons.h 228644 2011-12-17 15:57:39Z avg $
+ * $FreeBSD: head/sys/dev/syscons/syscons.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #ifndef _DEV_SYSCONS_SYSCONS_H_
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/syscons/warp/warp_saver.c
--- a/head/sys/dev/syscons/warp/warp_saver.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/syscons/warp/warp_saver.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
+ * Copyright (c) 1998 Dag-Erling Coïdan Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/dev/syscons/warp/warp_saver.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/tws/tws.c
--- a/head/sys/dev/tws/tws.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/tws/tws.c	Mon Jan 16 14:38:30 2012 +0200
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/tws/tws.c 229416 2012-01-03 20:17:35Z delphij $");
+__FBSDID("$FreeBSD: head/sys/dev/tws/tws.c 230200 2012-01-16 06:00:44Z delphij $");
 
 #include <dev/tws/tws.h>
 #include <dev/tws/tws_services.h>
@@ -685,7 +685,7 @@
     {
         if (bus_dmamap_create(sc->data_tag, 0, &sc->reqs[i].dma_map)) {
             /* log a ENOMEM failure msg here */
-	    mtx_unlock(&sc->q_lock);
+            mtx_unlock(&sc->q_lock);
             return(FAILURE);
         } 
         sc->reqs[i].cmd_pkt =  &cmd_buf[i];
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/usb/controller/xhci.c
--- a/head/sys/dev/usb/controller/xhci.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/usb/controller/xhci.c	Mon Jan 16 14:38:30 2012 +0200
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/controller/xhci.c 229086 2011-12-31 13:34:42Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/controller/xhci.c 230090 2012-01-13 22:19:14Z hselasky $");
 
 #include <sys/stdint.h>
 #include <sys/stddef.h>
@@ -2211,9 +2211,10 @@
 	struct usb_device *hubdev;
 	uint32_t temp;
 	uint32_t route;
+	uint32_t rh_port;
 	uint8_t is_hub;
 	uint8_t index;
-	uint8_t rh_port;
+	uint8_t depth;
 
 	index = udev->controller_slot_id;
 
@@ -2235,6 +2236,8 @@
 		if (hubdev->parent_hub == NULL)
 			break;
 
+		depth = hubdev->parent_hub->depth;
+
 		/*
 		 * NOTE: HS/FS/LS devices and the SS root HUB can have
 		 * more than 15 ports
@@ -2242,17 +2245,18 @@
 
 		rh_port = hubdev->port_no;
 
-		if (hubdev->parent_hub->parent_hub == NULL)
+		if (depth == 0)
 			break;
 
-		route *= 16;
-
 		if (rh_port > 15)
-			route |= 15;
-		else
-			route |= rh_port;
+			rh_port = 15;
+
+		if (depth < 6)
+			route |= rh_port << (4 * (depth - 1));
 	}
 
+	DPRINTF("Route=0x%08x\n", route);
+
 	temp = XHCI_SCTX_0_ROUTE_SET(route);
 
 	switch (sc->sc_hw.devs[index].state) {
@@ -2260,7 +2264,7 @@
 		temp |= XHCI_SCTX_0_CTX_NUM_SET(XHCI_MAX_ENDPOINTS - 1);
 		break;
 	default:
-		temp = XHCI_SCTX_0_CTX_NUM_SET(1);
+		temp |= XHCI_SCTX_0_CTX_NUM_SET(1);
 		break;
 	}
 
@@ -3063,6 +3067,7 @@
 		case UHF_C_PORT_CONFIG_ERROR:
 			XWRITE4(sc, oper, port, v | XHCI_PS_CEC);
 			break;
+		case UHF_C_PORT_SUSPEND:
 		case UHF_C_PORT_LINK_STATE:
 			XWRITE4(sc, oper, port, v | XHCI_PS_PLC);
 			break;
@@ -3189,8 +3194,13 @@
 			i |= UPS_OVERCURRENT_INDICATOR;
 		if (v & XHCI_PS_PR)
 			i |= UPS_RESET;
-		if (v & XHCI_PS_PP)
+		if (v & XHCI_PS_PP) {
+			/*
+			 * The USB 3.0 RH is using the
+			 * USB 2.0's power bit
+			 */
 			i |= UPS_PORT_POWER;
+		}
 		USETW(sc->sc_hub_desc.ps.wPortStatus, i);
 
 		i = 0;
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/usb/serial/ucycom.c
--- a/head/sys/dev/usb/serial/ucycom.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/usb/serial/ucycom.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,8 +1,8 @@
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/serial/ucycom.c 223486 2011-06-24 02:30:02Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/serial/ucycom.c 230132 2012-01-15 13:23:18Z uqs $");
 
 /*-
- * Copyright (c) 2004 Dag-Erling Coïdan Smørgrav
+ * Copyright (c) 2004 Dag-Erling Coïdan Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/usb/serial/uftdi.c
--- a/head/sys/dev/usb/serial/uftdi.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/usb/serial/uftdi.c	Mon Jan 16 14:38:30 2012 +0200
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/serial/uftdi.c 227461 2011-11-12 08:16:45Z hselasky $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/serial/uftdi.c 230179 2012-01-15 23:00:33Z kientzle $");
 
 /*
  * NOTE: all function names beginning like "uftdi_cfg_" can only
@@ -217,6 +217,7 @@
 	UFTDI_DEV(FTDI, SERIAL_8U100AX, SIO),
 	UFTDI_DEV(FTDI, SERIAL_2232C, 8U232AM),
 	UFTDI_DEV(FTDI, SERIAL_2232D, 8U232AM),
+	UFTDI_DEV(FTDI, BEAGLEBONE, 8U232AM),
 	UFTDI_DEV(FTDI, SERIAL_4232H, 8U232AM),
 	UFTDI_DEV(FTDI, SERIAL_8U232AM, 8U232AM),
 	UFTDI_DEV(FTDI, SERIAL_8U232AM4, 8U232AM),
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/usb/serial/usb_serial.c
--- a/head/sys/dev/usb/serial/usb_serial.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/usb/serial/usb_serial.c	Mon Jan 16 14:38:30 2012 +0200
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/dev/usb/serial/usb_serial.c 228631 2011-12-17 15:08:43Z avg $");
+__FBSDID("$FreeBSD: head/sys/dev/usb/serial/usb_serial.c 230209 2012-01-16 10:42:43Z hselasky $");
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -248,10 +248,16 @@
 		return (EINVAL);
 	}
 
+	/* allocate a uniq unit number */
 	ssc->sc_unit = ucom_unit_alloc();
 	if (ssc->sc_unit == -1)
 		return (ENOMEM);
 
+	/* generate TTY name string */
+	snprintf(ssc->sc_ttyname, sizeof(ssc->sc_ttyname),
+	    UCOM_TTY_PREFIX "%d", ssc->sc_unit);
+
+	/* create USB request handling process */
 	error = usb_proc_create(&ssc->sc_tq, mtx, "ucom", USB_PRI_MED);
 	if (error) {
 		ucom_unit_free(ssc->sc_unit);
@@ -292,6 +298,16 @@
 	if (ssc->sc_subunits == 0)
 		return;		/* not initialized */
 
+	if (ssc->sc_sysctl_ttyname != NULL) {
+		sysctl_remove_oid(ssc->sc_sysctl_ttyname, 1, 0);
+		ssc->sc_sysctl_ttyname = NULL;
+	}
+
+	if (ssc->sc_sysctl_ttyports != NULL) {
+		sysctl_remove_oid(ssc->sc_sysctl_ttyports, 1, 0);
+		ssc->sc_sysctl_ttyports = NULL;
+	}
+
 	usb_proc_drain(&ssc->sc_tq);
 
 	for (subunit = 0; subunit < ssc->sc_subunits; subunit++) {
@@ -413,19 +429,36 @@
 void
 ucom_set_pnpinfo_usb(struct ucom_super_softc *ssc, device_t dev)
 {
-    char buf[64];
-    uint8_t iface_index;
-    struct usb_attach_arg *uaa;
+	char buf[64];
+	uint8_t iface_index;
+	struct usb_attach_arg *uaa;
 
-    snprintf(buf, sizeof(buf), "ttyname=%s%d ttyports=%d",
-	     UCOM_TTY_PREFIX, ssc->sc_unit, ssc->sc_subunits);
+	snprintf(buf, sizeof(buf), "ttyname=" UCOM_TTY_PREFIX
+	    "%d ttyports=%d", ssc->sc_unit, ssc->sc_subunits);
 
-    /* Store the PNP info in the first interface for the dev */
-    uaa = device_get_ivars(dev);
-    iface_index = uaa->info.bIfaceIndex;
+	/* Store the PNP info in the first interface for the device */
+	uaa = device_get_ivars(dev);
+	iface_index = uaa->info.bIfaceIndex;
     
-    if (usbd_set_pnpinfo(uaa->device, iface_index, buf) != 0)
-	device_printf(dev, "Could not set PNP info\n");
+	if (usbd_set_pnpinfo(uaa->device, iface_index, buf) != 0)
+		device_printf(dev, "Could not set PNP info\n");
+
+	/*
+	 * The following information is also replicated in the PNP-info
+	 * string which is registered above:
+	 */
+	if (ssc->sc_sysctl_ttyname == NULL) {
+		ssc->sc_sysctl_ttyname = SYSCTL_ADD_STRING(NULL,
+		    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+		    OID_AUTO, "ttyname", CTLFLAG_RD, ssc->sc_ttyname, 0,
+		    "TTY device basename");
+	}
+	if (ssc->sc_sysctl_ttyports == NULL) {
+		ssc->sc_sysctl_ttyports = SYSCTL_ADD_INT(NULL,
+		    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+		    OID_AUTO, "ttyports", CTLFLAG_RD,
+		    NULL, ssc->sc_subunits, "Number of ports");
+	}
 }
 
 static void
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/usb/serial/usb_serial.h
--- a/head/sys/dev/usb/serial/usb_serial.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/usb/serial/usb_serial.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*	$NetBSD: ucomvar.h,v 1.9 2001/01/23 21:56:17 augustss Exp $	*/
-/*	$FreeBSD$	*/
+/*	$FreeBSD: head/sys/dev/usb/serial/usb_serial.h 230209 2012-01-16 10:42:43Z hselasky $	*/
 
 /*-
  * Copyright (c) 2001-2002, Shunsuke Akiyama <akiyama at jp.FreeBSD.org>.
@@ -70,6 +70,7 @@
 #include <sys/tty.h>
 #include <sys/serial.h>
 #include <sys/fcntl.h>
+#include <sys/sysctl.h>
 
 /* Module interface related macros */
 #define	UCOM_MODVER	1
@@ -132,8 +133,11 @@
 
 struct ucom_super_softc {
 	struct usb_process sc_tq;
-	uint32_t sc_unit;
-	uint32_t sc_subunits;
+	int sc_unit;
+	int sc_subunits;
+	struct sysctl_oid *sc_sysctl_ttyname;
+	struct sysctl_oid *sc_sysctl_ttyports;
+	char sc_ttyname[16];
 };
 
 struct ucom_softc {
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/usb/usb.h
--- a/head/sys/dev/usb/usb.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/usb/usb.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/usb/usb.h 227401 2011-11-09 18:48:36Z hselasky $ */
+/* $FreeBSD: head/sys/dev/usb/usb.h 230032 2012-01-12 21:21:20Z hselasky $ */
 /*-
  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
  * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
@@ -688,6 +688,7 @@
 #define	UPS_PORT_LS_LOOPBACK	0x0B
 #define	UPS_PORT_LS_RESUME	0x0F
 #define	UPS_PORT_POWER			0x0100
+#define	UPS_PORT_POWER_SS		0x0200	/* super-speed only */
 #define	UPS_LOW_SPEED			0x0200
 #define	UPS_HIGH_SPEED			0x0400
 #define	UPS_OTHER_SPEED			0x0600	/* currently FreeBSD specific */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/usb/usb_hub.c
--- a/head/sys/dev/usb/usb_hub.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/usb/usb_hub.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/usb/usb_hub.c 228758 2011-12-21 08:46:08Z hselasky $ */
+/* $FreeBSD: head/sys/dev/usb/usb_hub.c 230091 2012-01-13 22:26:13Z hselasky $ */
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
  * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
@@ -327,6 +327,7 @@
 	enum usb_dev_speed speed;
 	enum usb_hc_mode mode;
 	usb_error_t err;
+	uint16_t power_mask;
 	uint8_t timeout;
 
 	DPRINTF("reattaching port %d\n", portno);
@@ -369,10 +370,27 @@
 	}
 	/* check if there is no power on the port and print a warning */
 
-	if (!(sc->sc_st.port_status & UPS_PORT_POWER)) {
+	switch (udev->speed) {
+	case USB_SPEED_HIGH:
+	case USB_SPEED_FULL:
+	case USB_SPEED_LOW:
+		power_mask = UPS_PORT_POWER;
+		break;
+	case USB_SPEED_SUPER:
+		if (udev->parent_hub == NULL)
+			power_mask = UPS_PORT_POWER;
+		else
+			power_mask = UPS_PORT_POWER_SS;
+		break;
+	default:
+		power_mask = 0;
+		break;
+	}
+	if (!(sc->sc_st.port_status & power_mask)) {
 		DPRINTF("WARNING: strange, connected port %d "
 		    "has no power\n", portno);
 	}
+
 	/* check if the device is in Host Mode */
 
 	if (!(sc->sc_st.port_status & UPS_PORT_MODE_DEVICE)) {
@@ -609,13 +627,15 @@
 		}
 	} else {
 		switch (UPS_PORT_LINK_STATE_GET(sc->sc_st.port_status)) {
-		case UPS_PORT_LS_U0:
-		case UPS_PORT_LS_U1:
-		case UPS_PORT_LS_RESUME:
+		case UPS_PORT_LS_U3:
+			is_suspend = 1;
+			break;
+		case UPS_PORT_LS_SS_INA:
+			usbd_req_warm_reset_port(udev, NULL, portno);
 			is_suspend = 0;
 			break;
 		default:
-			is_suspend = 1;
+			is_suspend = 0;
 			break;
 		}
 	}
@@ -632,8 +652,7 @@
 		 */
 		if (is_suspend == 0)
 			usb_dev_resume_peer(child);
-		else if ((child->flags.usb_mode == USB_MODE_DEVICE) ||
-		    (usb_device_20_compatible(child) == 0))
+		else if (child->flags.usb_mode == USB_MODE_DEVICE)
 			usb_dev_suspend_peer(child);
 	}
 done:
@@ -775,7 +794,8 @@
 				break;
 			}
 		}
-		if (sc->sc_st.port_change & (UPS_C_SUSPEND | UPS_C_PORT_LINK_STATE)) {
+		if (sc->sc_st.port_change & (UPS_C_SUSPEND |
+		    UPS_C_PORT_LINK_STATE)) {
 			err = uhub_suspend_resume_port(sc, portno);
 			if (err) {
 				/* most likely the HUB is gone */
@@ -2068,7 +2088,6 @@
 	    (udev->pwr_save.write_refs != 0) ||
 	    ((udev->pwr_save.read_refs != 0) &&
 	    (udev->flags.usb_mode == USB_MODE_HOST) &&
-	    (usb_device_20_compatible(udev) != 0) &&
 	    (usb_peer_can_wakeup(udev) == 0)));
 }
 
@@ -2248,6 +2267,14 @@
 			DPRINTFN(0, "Resuming port failed\n");
 			return;
 		}
+	} else {
+		/* resume current port (Valid in Host and Device Mode) */
+		err = usbd_req_set_port_link_state(udev->parent_hub,
+		    NULL, udev->port_no, UPS_PORT_LS_U0);
+		if (err) {
+			DPRINTFN(0, "Resuming port failed\n");
+			return;
+		}
 	}
 
 	/* resume settle time */
@@ -2289,8 +2316,7 @@
 	usbd_sr_unlock(udev);
 
 	/* check if peer has wakeup capability */
-	if (usb_peer_can_wakeup(udev) &&
-	    usb_device_20_compatible(udev)) {
+	if (usb_peer_can_wakeup(udev)) {
 		/* clear remote wakeup */
 		err = usbd_req_clear_device_feature(udev,
 		    NULL, UF_DEVICE_REMOTE_WAKEUP);
@@ -2351,8 +2377,7 @@
 		}
 	}
 
-	if (usb_peer_can_wakeup(udev) &&
-	    usb_device_20_compatible(udev)) {
+	if (usb_peer_can_wakeup(udev)) {
 		/*
 		 * This request needs to be done before we set
 		 * "udev->flags.self_suspended":
@@ -2384,8 +2409,7 @@
 	USB_BUS_UNLOCK(udev->bus);
 
 	if (err != 0) {
-		if (usb_peer_can_wakeup(udev) &&
-		    usb_device_20_compatible(udev)) {
+		if (usb_peer_can_wakeup(udev)) {
 			/* allow device to do remote wakeup */
 			err = usbd_req_clear_device_feature(udev,
 			    NULL, UF_DEVICE_REMOTE_WAKEUP);
@@ -2441,6 +2465,14 @@
 			DPRINTFN(0, "Suspending port failed\n");
 			return;
 		}
+	} else {
+		/* suspend current port */
+		err = usbd_req_set_port_link_state(udev->parent_hub,
+		    NULL, udev->port_no, UPS_PORT_LS_U3);
+		if (err) {
+			DPRINTFN(0, "Suspending port failed\n");
+			return;
+		}
 	}
 
 	udev = udev->parent_hub;
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/usb/usb_request.c
--- a/head/sys/dev/usb/usb_request.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/usb/usb_request.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/usb/usb_request.c 227461 2011-11-12 08:16:45Z hselasky $ */
+/* $FreeBSD: head/sys/dev/usb/usb_request.c 230091 2012-01-13 22:26:13Z hselasky $ */
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
  * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
@@ -795,12 +795,17 @@
 	struct usb_port_status ps;
 	usb_error_t err;
 	uint16_t n;
+	uint16_t status;
+	uint16_t change;
 
 #ifdef USB_DEBUG
 	uint16_t pr_poll_delay;
 	uint16_t pr_recovery_delay;
 
 #endif
+
+	DPRINTF("\n");
+
 	/* clear any leftover port reset changes first */
 	usbd_req_clear_port_feature(
 	    udev, mtx, port, UHF_C_PORT_RESET);
@@ -827,9 +832,6 @@
 #endif
 	n = 0;
 	while (1) {
-		uint16_t status;
-		uint16_t change;
-
 #ifdef USB_DEBUG
 		/* wait for the device to recover from reset */
 		usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_poll_delay));
@@ -840,9 +842,9 @@
 		n += USB_PORT_RESET_DELAY;
 #endif
 		err = usbd_req_get_port_status(udev, mtx, &ps, port);
-		if (err) {
+		if (err)
 			goto done;
-		}
+
 		status = UGETW(ps.wPortStatus);
 		change = UGETW(ps.wPortChange);
 
@@ -872,9 +874,9 @@
 	/* clear port reset first */
 	err = usbd_req_clear_port_feature(
 	    udev, mtx, port, UHF_C_PORT_RESET);
-	if (err) {
+	if (err)
 		goto done;
-	}
+
 	/* check for timeout */
 	if (n == 0) {
 		err = USB_ERR_TIMEOUT;
@@ -908,21 +910,50 @@
  *       disabled.
  *------------------------------------------------------------------------*/
 usb_error_t
-usbd_req_warm_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
+usbd_req_warm_reset_port(struct usb_device *udev, struct mtx *mtx,
+    uint8_t port)
 {
 	struct usb_port_status ps;
 	usb_error_t err;
 	uint16_t n;
+	uint16_t status;
+	uint16_t change;
 
 #ifdef USB_DEBUG
 	uint16_t pr_poll_delay;
 	uint16_t pr_recovery_delay;
 
 #endif
-	err = usbd_req_set_port_feature(udev, mtx, port, UHF_BH_PORT_RESET);
-	if (err) {
+
+	DPRINTF("\n");
+
+	err = usbd_req_get_port_status(udev, mtx, &ps, port);
+	if (err)
 		goto done;
+
+	status = UGETW(ps.wPortStatus);
+
+	switch (UPS_PORT_LINK_STATE_GET(status)) {
+	case UPS_PORT_LS_U3:
+	case UPS_PORT_LS_COMP_MODE:
+	case UPS_PORT_LS_LOOPBACK:
+	case UPS_PORT_LS_SS_INA:
+		break;
+	default:
+		DPRINTF("Wrong state for warm reset\n");
+		return (0);
 	}
+
+	/* clear any leftover warm port reset changes first */
+	usbd_req_clear_port_feature(udev, mtx,
+	    port, UHF_C_BH_PORT_RESET);
+
+	/* set warm port reset */
+	err = usbd_req_set_port_feature(udev, mtx,
+	    port, UHF_BH_PORT_RESET);
+	if (err)
+		goto done;
+
 #ifdef USB_DEBUG
 	/* range check input parameters */
 	pr_poll_delay = usb_pr_poll_delay;
@@ -948,17 +979,20 @@
 		n += USB_PORT_RESET_DELAY;
 #endif
 		err = usbd_req_get_port_status(udev, mtx, &ps, port);
-		if (err) {
+		if (err)
 			goto done;
-		}
+
+		status = UGETW(ps.wPortStatus);
+		change = UGETW(ps.wPortChange);
+
 		/* if the device disappeared, just give up */
-		if (!(UGETW(ps.wPortStatus) & UPS_CURRENT_CONNECT_STATUS)) {
+		if (!(status & UPS_CURRENT_CONNECT_STATUS))
 			goto done;
-		}
+
 		/* check if reset is complete */
-		if (UGETW(ps.wPortChange) & UPS_C_BH_PORT_RESET) {
+		if (change & UPS_C_BH_PORT_RESET)
 			break;
-		}
+
 		/* check for timeout */
 		if (n > 1000) {
 			n = 0;
@@ -969,9 +1003,9 @@
 	/* clear port reset first */
 	err = usbd_req_clear_port_feature(
 	    udev, mtx, port, UHF_C_BH_PORT_RESET);
-	if (err) {
+	if (err)
 		goto done;
-	}
+
 	/* check for timeout */
 	if (n == 0) {
 		err = USB_ERR_TIMEOUT;
@@ -2014,6 +2048,10 @@
 		}
 	}
 
+	/* Try to warm reset first */
+	if (parent_hub->speed == USB_SPEED_SUPER)
+		usbd_req_warm_reset_port(parent_hub, mtx, udev->port_no);
+
 	/* Try to reset the parent HUB port. */
 	err = usbd_req_reset_port(parent_hub, mtx, udev->port_no);
 	if (err) {
@@ -2174,3 +2212,27 @@
 	USETW(req.wLength, 0);
 	return (usbd_do_request(udev, mtx, &req, 0));
 }
+
+/*------------------------------------------------------------------------*
+ *	usbd_req_set_port_link_state
+ *
+ * USB 3.0 specific request
+ *
+ * Returns:
+ *    0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+usb_error_t
+usbd_req_set_port_link_state(struct usb_device *udev, struct mtx *mtx,
+    uint8_t port, uint8_t link_state)
+{
+	struct usb_device_request req;
+
+	req.bmRequestType = UT_WRITE_CLASS_OTHER;
+	req.bRequest = UR_SET_FEATURE;
+	USETW(req.wValue, UHF_PORT_LINK_STATE);
+	req.wIndex[0] = port;
+	req.wIndex[1] = link_state;
+	USETW(req.wLength, 0);
+	return (usbd_do_request(udev, mtx, &req, 0));
+}
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/usb/usb_request.h
--- a/head/sys/dev/usb/usb_request.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/usb/usb_request.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,4 +1,4 @@
-/* $FreeBSD: head/sys/dev/usb/usb_request.h 222786 2011-06-06 21:45:09Z hselasky $ */
+/* $FreeBSD: head/sys/dev/usb/usb_request.h 230032 2012-01-12 21:21:20Z hselasky $ */
 /*-
  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
  *
@@ -89,5 +89,7 @@
 		    uint8_t port);
 usb_error_t usbd_req_clear_tt_buffer(struct usb_device *udev, struct mtx *mtx,
 		    uint8_t port, uint8_t addr, uint8_t type, uint8_t endpoint);
+usb_error_t usbd_req_set_port_link_state(struct usb_device *udev,
+		    struct mtx *mtx, uint8_t port, uint8_t link_state);
 
 #endif					/* _USB_REQUEST_H_ */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/usb/usbdevs
--- a/head/sys/dev/usb/usbdevs	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/usb/usbdevs	Mon Jan 16 14:38:30 2012 +0200
@@ -1,4 +1,4 @@
-$FreeBSD: head/sys/dev/usb/usbdevs 228637 2011-12-17 15:38:16Z kevlo $
+$FreeBSD: head/sys/dev/usb/usbdevs 230179 2012-01-15 23:00:33Z kientzle $
 /* $NetBSD: usbdevs,v 1.392 2004/12/29 08:38:44 imp Exp $ */
 
 /*-
@@ -1604,6 +1604,7 @@
 product FTDI SERIAL_8U232AM4	0x6004	8U232AM Serial
 product FTDI SERIAL_2232C	0x6010	FT2232C Dual port Serial
 product FTDI SERIAL_2232D	0x9e90	FT2232D Dual port Serial
+product FTDI BEAGLEBONE		0xA6D0  BeagleBone
 product FTDI SERIAL_4232H	0x6011	FT4232H Quad port Serial
 /* Gude Analog- und Digitalsysteme products also uses FTDI's id: */
 product FTDI TACTRIX_OPENPORT_13M 0xcc48 OpenPort 1.3 Mitsubishi
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/vxge/include/vxgehal-ll.h
--- a/head/sys/dev/vxge/include/vxgehal-ll.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/vxge/include/vxgehal-ll.h	Mon Jan 16 14:38:30 2012 +0200
@@ -28,7 +28,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
-/*$FreeBSD: head/sys/dev/vxge/include/vxgehal-ll.h 226436 2011-10-16 14:30:28Z eadler $*/
+/*$FreeBSD: head/sys/dev/vxge/include/vxgehal-ll.h 230135 2012-01-15 13:23:54Z uqs $*/
 
 #ifndef	VXGE_HAL_LL_H
 #define	VXGE_HAL_LL_H
@@ -367,23 +367,23 @@
  *		configuration mismatch.
  * @VXGE_HAL_RING_T_CODE_L3_L4_CKSUM_MISMATCH: Layer 3 and Layer 4 checksum
  *		presentation configuration mismatch.
- * @VXGE_HAL_RING_T_CODE_L3_PKT_ERR: Layer 3 error¸unparseable packet,
+ * @VXGE_HAL_RING_T_CODE_L3_PKT_ERR: Layer 3 error: unparseable packet,
  *		such as unknown IPv6 header.
- * @VXGE_HAL_RING_T_CODE_L2_FRM_ERR: Layer 2 error¸frame integrity
+ * @VXGE_HAL_RING_T_CODE_L2_FRM_ERR: Layer 2 error: frame integrity
  *		error, such as FCS or ECC).
- * @VXGE_HAL_RING_T_CODE_BUF_SIZE_ERR: Buffer size error¸the RxD buffer(
- *		s) were not appropriately sized and data loss occurred.
- * @VXGE_HAL_RING_T_CODE_INT_ECC_ERR: Internal ECC error¸RxD corrupted.
- * @VXGE_HAL_RING_T_CODE_BENIGN_OVFLOW: Benign overflow¸the contents of
+ * @VXGE_HAL_RING_T_CODE_BUF_SIZE_ERR: Buffer size error: the RxD buffer(s)
+ * 		were not appropriately sized and data loss occurred.
+ * @VXGE_HAL_RING_T_CODE_INT_ECC_ERR: Internal ECC error: RxD corrupted.
+ * @VXGE_HAL_RING_T_CODE_BENIGN_OVFLOW: Benign overflow: the contents of
  *		Segment1 exceeded the capacity of Buffer1 and the remainder
  *		was placed in Buffer2. Segment2 now starts in Buffer3.
  *		No data loss or errors occurred.
- * @VXGE_HAL_RING_T_CODE_ZERO_LEN_BUFF: Buffer size 0¸one of the RxDs
+ * @VXGE_HAL_RING_T_CODE_ZERO_LEN_BUFF: Buffer size 0: one of the RxDs
  *		assigned buffers has a size of 0 bytes.
- * @VXGE_HAL_RING_T_CODE_FRM_DROP: Frame dropped¸either due to
+ * @VXGE_HAL_RING_T_CODE_FRM_DROP: Frame dropped: either due to
  *		VPath Reset or because of a VPIN mismatch.
  * @VXGE_HAL_RING_T_CODE_UNUSED: Unused
- * @VXGE_HAL_RING_T_CODE_MULTI_ERR: Multiple errors¸more than one
+ * @VXGE_HAL_RING_T_CODE_MULTI_ERR: Multiple errors: more than one
  *		transfer code condition occurred.
  *
  * Transfer codes returned by adapter.
@@ -2535,7 +2535,7 @@
  * descriptor.
  * @vpath_handle: virtual path handle.
  * @txdlh: Descriptor handle.
- * @frag_idx: Index of the data buffer in the caller's scatter-gather list¤
+ * @frag_idx: Index of the data buffer in the caller's scatter-gather list
  *	   (of buffers).
  * @dma_pointer: DMA address of the data buffer referenced by @frag_idx.
  * @size: Size of the data buffer (in bytes).
@@ -2560,7 +2560,7 @@
  * in fifo descriptor.
  * @vpath_handle: Virtual path handle.
  * @txdlh: Descriptor handle.
- * @frag_idx: Index of the data buffer in the caller's scatter-gather list¤
+ * @frag_idx: Index of the data buffer in the caller's scatter-gather list
  *	   (of buffers).
  * @vaddr: Virtual address of the data buffer.
  * @dma_pointer: DMA address of the data buffer referenced by @frag_idx.
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/dev/xen/xenpci/evtchn.c
--- a/head/sys/dev/xen/xenpci/evtchn.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/dev/xen/xenpci/evtchn.c	Mon Jan 16 14:38:30 2012 +0200
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/xen/xenpci/evtchn.c 230183 2012-01-16 02:38:45Z cperciva $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -52,7 +52,7 @@
 #include <dev/xen/xenpci/xenpcivar.h>
 
 #if defined(__i386__)
-#define	__ffs(word)	ffs(word)
+#define	__ffs(word)	(ffs(word) - 1)
 #elif defined(__amd64__)
 static inline unsigned long __ffs(unsigned long word)
 {
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/nfsserver/nfs_nfsdstate.c
--- a/head/sys/fs/nfsserver/nfs_nfsdstate.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/nfsserver/nfs_nfsdstate.c	Mon Jan 16 14:38:30 2012 +0200
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/fs/nfsserver/nfs_nfsdstate.c 224086 2011-07-16 08:51:09Z zack $");
+__FBSDID("$FreeBSD: head/sys/fs/nfsserver/nfs_nfsdstate.c 230100 2012-01-14 04:04:58Z rmacklem $");
 
 #ifndef APPLEKEXT
 #include <fs/nfs/nfsport.h>
@@ -315,7 +315,7 @@
 		for (i = 0; i < NFSSTATEHASHSIZE; i++) {
 			LIST_NEWHEAD(&new_clp->lc_stateid[i],
 			    &clp->lc_stateid[i], ls_hash);
-			LIST_FOREACH(tstp, &new_clp->lc_stateid[i], ls_list)
+			LIST_FOREACH(tstp, &new_clp->lc_stateid[i], ls_hash)
 				tstp->ls_clp = new_clp;
 		}
 		LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp,
@@ -369,7 +369,7 @@
 	for (i = 0; i < NFSSTATEHASHSIZE; i++) {
 		LIST_NEWHEAD(&new_clp->lc_stateid[i], &clp->lc_stateid[i],
 		    ls_hash);
-		LIST_FOREACH(tstp, &new_clp->lc_stateid[i], ls_list)
+		LIST_FOREACH(tstp, &new_clp->lc_stateid[i], ls_hash)
 			tstp->ls_clp = new_clp;
 	}
 	LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp,
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/procfs/procfs.c
--- a/head/sys/fs/procfs/procfs.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/procfs/procfs.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2001 Dag-Erling Smørgrav
+ * Copyright (c) 2001 Dag-Erling Smørgrav
  * Copyright (c) 1993 Jan-Simon Pendry
  * Copyright (c) 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -37,7 +37,7 @@
  *
  *	@(#)procfs_vfsops.c	8.7 (Berkeley) 5/10/95
  *
- * $FreeBSD: head/sys/fs/procfs/procfs.c 224915 2011-08-16 20:13:17Z kib $
+ * $FreeBSD: head/sys/fs/procfs/procfs.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <sys/param.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/procfs/procfs_ioctl.c
--- a/head/sys/fs/procfs/procfs_ioctl.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/procfs/procfs_ioctl.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
+ * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *      $FreeBSD: head/sys/fs/procfs/procfs_ioctl.c 225617 2011-09-16 13:58:51Z kmacy $
+ *      $FreeBSD: head/sys/fs/procfs/procfs_ioctl.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include "opt_compat.h"
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/procfs/procfs_status.c
--- a/head/sys/fs/procfs/procfs_status.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/procfs/procfs_status.c	Mon Jan 16 14:38:30 2012 +0200
@@ -34,7 +34,7 @@
  *
  * From:
  *	$Id: procfs_status.c,v 3.1 1993/12/15 09:40:17 jsp Exp $
- * $FreeBSD: head/sys/fs/procfs/procfs_status.c 227834 2011-11-22 20:43:03Z trociny $
+ * $FreeBSD: head/sys/fs/procfs/procfs_status.c 230145 2012-01-15 18:47:24Z trociny $
  */
 
 #include <sys/param.h>
@@ -193,5 +193,5 @@
 
 	PROC_UNLOCK(p);
 
-	return (proc_getargv(td, p, sb, ARG_MAX));
+	return (proc_getargv(td, p, sb));
 }
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/pseudofs/pseudofs.c
--- a/head/sys/fs/pseudofs/pseudofs.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/pseudofs/pseudofs.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
+ * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/fs/pseudofs/pseudofs.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_pseudofs.h"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/pseudofs/pseudofs.h
--- a/head/sys/fs/pseudofs/pseudofs.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/pseudofs/pseudofs.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
+ * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *      $FreeBSD$
+ *      $FreeBSD: head/sys/fs/pseudofs/pseudofs.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #ifndef _PSEUDOFS_H_INCLUDED
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/pseudofs/pseudofs_fileno.c
--- a/head/sys/fs/pseudofs/pseudofs_fileno.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/pseudofs/pseudofs_fileno.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
+ * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/fs/pseudofs/pseudofs_fileno.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_pseudofs.h"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/pseudofs/pseudofs_internal.h
--- a/head/sys/fs/pseudofs/pseudofs_internal.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/pseudofs/pseudofs_internal.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
+ * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *      $FreeBSD$
+ *      $FreeBSD: head/sys/fs/pseudofs/pseudofs_internal.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #ifndef _PSEUDOFS_INTERNAL_H_INCLUDED
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/pseudofs/pseudofs_vncache.c
--- a/head/sys/fs/pseudofs/pseudofs_vncache.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/pseudofs/pseudofs_vncache.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
+ * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/fs/pseudofs/pseudofs_vncache.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/fs/pseudofs/pseudofs_vncache.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_pseudofs.h"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/pseudofs/pseudofs_vnops.c
--- a/head/sys/fs/pseudofs/pseudofs_vnops.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/pseudofs/pseudofs_vnops.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
+ * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/fs/pseudofs/pseudofs_vnops.c 229694 2012-01-06 10:12:59Z jh $");
+__FBSDID("$FreeBSD: head/sys/fs/pseudofs/pseudofs_vnops.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_pseudofs.h"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/tmpfs/tmpfs.h
--- a/head/sys/fs/tmpfs/tmpfs.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/tmpfs/tmpfs.h	Mon Jan 16 14:38:30 2012 +0200
@@ -29,7 +29,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/fs/tmpfs/tmpfs.h 227802 2011-11-21 20:26:22Z delphij $
+ * $FreeBSD: head/sys/fs/tmpfs/tmpfs.h 230180 2012-01-16 00:26:49Z alc $
  */
 
 #ifndef _FS_TMPFS_TMPFS_H_
@@ -436,7 +436,7 @@
 int	tmpfs_dir_getdents(struct tmpfs_node *, struct uio *, off_t *);
 int	tmpfs_dir_whiteout_add(struct vnode *, struct componentname *);
 void	tmpfs_dir_whiteout_remove(struct vnode *, struct componentname *);
-int	tmpfs_reg_resize(struct vnode *, off_t);
+int	tmpfs_reg_resize(struct vnode *, off_t, boolean_t);
 int	tmpfs_chflags(struct vnode *, int, struct ucred *, struct thread *);
 int	tmpfs_chmod(struct vnode *, mode_t, struct ucred *, struct thread *);
 int	tmpfs_chown(struct vnode *, uid_t, gid_t, struct ucred *,
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/tmpfs/tmpfs_subr.c
--- a/head/sys/fs/tmpfs/tmpfs_subr.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/tmpfs/tmpfs_subr.c	Mon Jan 16 14:38:30 2012 +0200
@@ -34,7 +34,7 @@
  * Efficient memory file system supporting functions.
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/fs/tmpfs/tmpfs_subr.c 229821 2012-01-08 20:09:26Z alc $");
+__FBSDID("$FreeBSD: head/sys/fs/tmpfs/tmpfs_subr.c 230180 2012-01-16 00:26:49Z alc $");
 
 #include <sys/param.h>
 #include <sys/namei.h>
@@ -882,7 +882,7 @@
  * Returns zero on success or an appropriate error code on failure.
  */
 int
-tmpfs_reg_resize(struct vnode *vp, off_t newsize)
+tmpfs_reg_resize(struct vnode *vp, off_t newsize, boolean_t ignerr)
 {
 	struct tmpfs_mount *tmp;
 	struct tmpfs_node *node;
@@ -929,6 +929,7 @@
 					vm_page_sleep(m, "tmfssz");
 					goto retry;
 				}
+				MPASS(m->valid == VM_PAGE_BITS_ALL);
 			} else if (vm_pager_has_page(uobj, idx, NULL, NULL)) {
 				m = vm_page_alloc(uobj, idx, VM_ALLOC_NORMAL);
 				if (m == NULL) {
@@ -951,13 +952,16 @@
 				} else {
 					vm_page_free(m);
 					vm_page_unlock(m);
-					VM_OBJECT_UNLOCK(uobj);
-					return (EIO);
+					if (ignerr)
+						m = NULL;
+					else {
+						VM_OBJECT_UNLOCK(uobj);
+						return (EIO);
+					}
 				}
 			}
 			if (m != NULL) {
 				pmap_zero_page_area(m, base, PAGE_SIZE - base);
-				MPASS(m->valid == VM_PAGE_BITS_ALL);
 				vm_page_dirty(m);
 				vm_pager_page_unswapped(m);
 			}
@@ -1351,7 +1355,7 @@
 	if (length > VFS_TO_TMPFS(vp->v_mount)->tm_maxfilesize)
 		return (EFBIG);
 
-	error = tmpfs_reg_resize(vp, length);
+	error = tmpfs_reg_resize(vp, length, FALSE);
 	if (error == 0) {
 		node->tn_status |= TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED;
 	}
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/tmpfs/tmpfs_vfsops.c
--- a/head/sys/fs/tmpfs/tmpfs_vfsops.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/tmpfs/tmpfs_vfsops.c	Mon Jan 16 14:38:30 2012 +0200
@@ -41,7 +41,7 @@
  * allocate and release resources.
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/fs/tmpfs/tmpfs_vfsops.c 227310 2011-11-07 16:21:50Z marcel $");
+__FBSDID("$FreeBSD: head/sys/fs/tmpfs/tmpfs_vfsops.c 230208 2012-01-16 10:25:22Z kevlo $");
 
 #include <sys/param.h>
 #include <sys/limits.h>
@@ -150,10 +150,8 @@
 		return (EINVAL);
 
 	if (mp->mnt_flag & MNT_UPDATE) {
-		/* XXX: There is no support yet to update file system
-		 * settings.  Should be added. */
-
-		return EOPNOTSUPP;
+		if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0))
+			return (0);
 	}
 
 	vn_lock(mp->mnt_vnodecovered, LK_SHARED | LK_RETRY);
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/fs/tmpfs/tmpfs_vnops.c
--- a/head/sys/fs/tmpfs/tmpfs_vnops.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/fs/tmpfs/tmpfs_vnops.c	Mon Jan 16 14:38:30 2012 +0200
@@ -34,7 +34,7 @@
  * tmpfs vnode interface.
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/fs/tmpfs/tmpfs_vnops.c 229363 2012-01-03 03:29:01Z alc $");
+__FBSDID("$FreeBSD: head/sys/fs/tmpfs/tmpfs_vnops.c 230180 2012-01-16 00:26:49Z alc $");
 
 #include <sys/param.h>
 #include <sys/fcntl.h>
@@ -437,18 +437,20 @@
     vm_offset_t offset, size_t tlen, struct uio *uio)
 {
 	vm_page_t	m;
-	int		error;
+	int		error, rv;
 
 	VM_OBJECT_LOCK(tobj);
-	vm_object_pip_add(tobj, 1);
 	m = vm_page_grab(tobj, idx, VM_ALLOC_WIRED |
 	    VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
 	if (m->valid != VM_PAGE_BITS_ALL) {
 		if (vm_pager_has_page(tobj, idx, NULL, NULL)) {
-			error = vm_pager_get_pages(tobj, &m, 1, 0);
-			if (error != 0) {
-				printf("tmpfs get pages from pager error [read]\n");
-				goto out;
+			rv = vm_pager_get_pages(tobj, &m, 1, 0);
+			if (rv != VM_PAGER_OK) {
+				vm_page_lock(m);
+				vm_page_free(m);
+				vm_page_unlock(m);
+				VM_OBJECT_UNLOCK(tobj);
+				return (EIO);
 			}
 		} else
 			vm_page_zero_invalid(m, TRUE);
@@ -456,12 +458,10 @@
 	VM_OBJECT_UNLOCK(tobj);
 	error = uiomove_fromphys(&m, offset, tlen, uio);
 	VM_OBJECT_LOCK(tobj);
-out:
 	vm_page_lock(m);
 	vm_page_unwire(m, TRUE);
 	vm_page_unlock(m);
 	vm_page_wakeup(m);
-	vm_object_pip_subtract(tobj, 1);
 	VM_OBJECT_UNLOCK(tobj);
 
 	return (error);
@@ -624,7 +624,7 @@
 	vm_offset_t	offset;
 	off_t		addr;
 	size_t		tlen;
-	int		error;
+	int		error, rv;
 
 	error = 0;
 	
@@ -664,14 +664,16 @@
 	}
 nocache:
 	VM_OBJECT_LOCK(tobj);
-	vm_object_pip_add(tobj, 1);
 	tpg = vm_page_grab(tobj, idx, VM_ALLOC_WIRED |
 	    VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
 	if (tpg->valid != VM_PAGE_BITS_ALL) {
 		if (vm_pager_has_page(tobj, idx, NULL, NULL)) {
-			error = vm_pager_get_pages(tobj, &tpg, 1, 0);
-			if (error != 0) {
-				printf("tmpfs get pages from pager error [write]\n");
+			rv = vm_pager_get_pages(tobj, &tpg, 1, 0);
+			if (rv != VM_PAGER_OK) {
+				vm_page_lock(tpg);
+				vm_page_free(tpg);
+				vm_page_unlock(tpg);
+				error = EIO;
 				goto out;
 			}
 		} else
@@ -685,9 +687,6 @@
 		pmap_copy_page(vpg, tpg);
 	}
 	VM_OBJECT_LOCK(tobj);
-out:
-	if (vobj != NULL)
-		VM_OBJECT_LOCK(vobj);
 	if (error == 0) {
 		KASSERT(tpg->valid == VM_PAGE_BITS_ALL,
 		    ("parts of tpg invalid"));
@@ -697,12 +696,13 @@
 	vm_page_unwire(tpg, TRUE);
 	vm_page_unlock(tpg);
 	vm_page_wakeup(tpg);
-	if (vpg != NULL)
+out:
+	VM_OBJECT_UNLOCK(tobj);
+	if (vpg != NULL) {
+		VM_OBJECT_LOCK(vobj);
 		vm_page_wakeup(vpg);
-	if (vobj != NULL)
 		VM_OBJECT_UNLOCK(vobj);
-	vm_object_pip_subtract(tobj, 1);
-	VM_OBJECT_UNLOCK(tobj);
+	}
 
 	return	(error);
 }
@@ -747,7 +747,8 @@
 
 	extended = uio->uio_offset + uio->uio_resid > node->tn_size;
 	if (extended) {
-		error = tmpfs_reg_resize(vp, uio->uio_offset + uio->uio_resid);
+		error = tmpfs_reg_resize(vp, uio->uio_offset + uio->uio_resid,
+		    FALSE);
 		if (error != 0)
 			goto out;
 	}
@@ -773,7 +774,7 @@
 	}
 
 	if (error != 0)
-		(void)tmpfs_reg_resize(vp, oldsize);
+		(void)tmpfs_reg_resize(vp, oldsize, TRUE);
 
 out:
 	MPASS(IMPLIES(error == 0, uio->uio_resid == 0));
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/geom/part/g_part_ebr.c
--- a/head/sys/geom/part/g_part_ebr.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/geom/part/g_part_ebr.c	Mon Jan 16 14:38:30 2012 +0200
@@ -27,7 +27,7 @@
 #include "opt_geom.h"
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/part/g_part_ebr.c 223594 2011-06-27 12:42:48Z ae $");
+__FBSDID("$FreeBSD: head/sys/geom/part/g_part_ebr.c 230064 2012-01-13 18:32:56Z truckman $");
 
 #include <sys/param.h>
 #include <sys/bio.h>
@@ -333,9 +333,10 @@
 {
 	struct g_part_ebr_entry *entry;
 
-	/* Allow dumping to a FreeBSD partition only. */
+	/* Allow dumping to a FreeBSD partition or Linux swap partition only. */
 	entry = (struct g_part_ebr_entry *)baseentry;
-	return ((entry->ent.dp_typ == DOSPTYP_386BSD) ? 1 : 0);
+	return ((entry->ent.dp_typ == DOSPTYP_386BSD ||
+	    entry->ent.dp_typ == DOSPTYP_LINSWP) ? 1 : 0);
 }
 
 #if defined(GEOM_PART_EBR_COMPAT)
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/geom/part/g_part_mbr.c
--- a/head/sys/geom/part/g_part_mbr.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/geom/part/g_part_mbr.c	Mon Jan 16 14:38:30 2012 +0200
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/geom/part/g_part_mbr.c 223587 2011-06-27 10:42:06Z ae $");
+__FBSDID("$FreeBSD: head/sys/geom/part/g_part_mbr.c 230064 2012-01-13 18:32:56Z truckman $");
 
 #include <sys/param.h>
 #include <sys/bio.h>
@@ -304,9 +304,10 @@
 {
 	struct g_part_mbr_entry *entry;
 
-	/* Allow dumping to a FreeBSD partition only. */
+	/* Allow dumping to a FreeBSD partition or Linux swap partition only. */
 	entry = (struct g_part_mbr_entry *)baseentry;
-	return ((entry->ent.dp_typ == DOSPTYP_386BSD) ? 1 : 0);
+	return ((entry->ent.dp_typ == DOSPTYP_386BSD ||
+	    entry->ent.dp_typ == DOSPTYP_LINSWP) ? 1 : 0);
 }
 
 static int
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/gnu/fs/reiserfs/reiserfs_fs.h
--- a/head/sys/gnu/fs/reiserfs/reiserfs_fs.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/gnu/fs/reiserfs/reiserfs_fs.h	Mon Jan 16 14:38:30 2012 +0200
@@ -2,9 +2,9 @@
  * Copyright 2000 Hans Reiser
  * See README for licensing and copyright details
  * 
- * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
+ * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
  * 
- * $FreeBSD$
+ * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_fs.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #ifndef _GNU_REISERFS_REISERFS_FS_H
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/gnu/fs/reiserfs/reiserfs_fs_i.h
--- a/head/sys/gnu/fs/reiserfs/reiserfs_fs_i.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/gnu/fs/reiserfs/reiserfs_fs_i.h	Mon Jan 16 14:38:30 2012 +0200
@@ -2,9 +2,9 @@
  * Copyright 2000 Hans Reiser
  * See README for licensing and copyright details
  * 
- * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
+ * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
  * 
- * $FreeBSD$
+ * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_fs_i.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #ifndef _GNU_REISERFS_REISERFS_FS_I_H
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/gnu/fs/reiserfs/reiserfs_fs_sb.h
--- a/head/sys/gnu/fs/reiserfs/reiserfs_fs_sb.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/gnu/fs/reiserfs/reiserfs_fs_sb.h	Mon Jan 16 14:38:30 2012 +0200
@@ -2,9 +2,9 @@
  * Copyright 2000 Hans Reiser
  * See README for licensing and copyright details
  * 
- * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
+ * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
  * 
- * $FreeBSD$
+ * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_fs_sb.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #ifndef _GNU_REISERFS_REISERFS_FS_SB_H
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/gnu/fs/reiserfs/reiserfs_hashes.c
--- a/head/sys/gnu/fs/reiserfs/reiserfs_hashes.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/gnu/fs/reiserfs/reiserfs_hashes.c	Mon Jan 16 14:38:30 2012 +0200
@@ -2,9 +2,9 @@
  * Copyright 2000 Hans Reiser
  * See README for licensing and copyright details
  * 
- * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
+ * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
  * 
- * $FreeBSD$
+ * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_hashes.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <gnu/fs/reiserfs/reiserfs_fs.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/gnu/fs/reiserfs/reiserfs_inode.c
--- a/head/sys/gnu/fs/reiserfs/reiserfs_inode.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/gnu/fs/reiserfs/reiserfs_inode.c	Mon Jan 16 14:38:30 2012 +0200
@@ -2,9 +2,9 @@
  * Copyright 2000 Hans Reiser
  * See README for licensing and copyright details
  * 
- * Ported to FreeBSD by Jean-Sébastien Pédron <dumbbell at FreeBSD.org>
+ * Ported to FreeBSD by Jean-Sébastien Pédron <dumbbell at FreeBSD.org>
  * 
- * $FreeBSD$
+ * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_inode.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <gnu/fs/reiserfs/reiserfs_fs.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/gnu/fs/reiserfs/reiserfs_item_ops.c
--- a/head/sys/gnu/fs/reiserfs/reiserfs_item_ops.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/gnu/fs/reiserfs/reiserfs_item_ops.c	Mon Jan 16 14:38:30 2012 +0200
@@ -2,9 +2,9 @@
  * Copyright 2000 Hans Reiser
  * See README for licensing and copyright details
  * 
- * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
+ * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
  * 
- * $FreeBSD$
+ * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_item_ops.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <gnu/fs/reiserfs/reiserfs_fs.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/gnu/fs/reiserfs/reiserfs_mount.h
--- a/head/sys/gnu/fs/reiserfs/reiserfs_mount.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/gnu/fs/reiserfs/reiserfs_mount.h	Mon Jan 16 14:38:30 2012 +0200
@@ -2,9 +2,9 @@
  * Copyright 2000 Hans Reiser
  * See README for licensing and copyright details
  * 
- * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
+ * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
  * 
- * $FreeBSD$
+ * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_mount.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #ifndef _GNU_REISERFS_REISERFS_MOUNT_H
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/gnu/fs/reiserfs/reiserfs_namei.c
--- a/head/sys/gnu/fs/reiserfs/reiserfs_namei.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/gnu/fs/reiserfs/reiserfs_namei.c	Mon Jan 16 14:38:30 2012 +0200
@@ -2,9 +2,9 @@
  * Copyright 2000 Hans Reiser
  * See README for licensing and copyright details
  * 
- * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
+ * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
  * 
- * $FreeBSD$
+ * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_namei.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <gnu/fs/reiserfs/reiserfs_fs.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/gnu/fs/reiserfs/reiserfs_prints.c
--- a/head/sys/gnu/fs/reiserfs/reiserfs_prints.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/gnu/fs/reiserfs/reiserfs_prints.c	Mon Jan 16 14:38:30 2012 +0200
@@ -2,9 +2,9 @@
  * Copyright 2000 Hans Reiser
  * See README for licensing and copyright details
  * 
- * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
+ * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
  * 
- * $FreeBSD$
+ * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_prints.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <gnu/fs/reiserfs/reiserfs_fs.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/gnu/fs/reiserfs/reiserfs_stree.c
--- a/head/sys/gnu/fs/reiserfs/reiserfs_stree.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/gnu/fs/reiserfs/reiserfs_stree.c	Mon Jan 16 14:38:30 2012 +0200
@@ -2,9 +2,9 @@
  * Copyright 2000 Hans Reiser
  * See README for licensing and copyright details
  * 
- * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
+ * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
  * 
- * $FreeBSD$
+ * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_stree.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <gnu/fs/reiserfs/reiserfs_fs.h>
@@ -321,7 +321,7 @@
 }
 
 #if 0
-/* XXX Il ne semble pas y avoir de compteur de référence dans struct buf */
+/* XXX Il ne semble pas y avoir de compteur de référence dans struct buf */
 inline void
 decrement_bcount(struct buf *p_s_bp)
 {
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/gnu/fs/reiserfs/reiserfs_vfsops.c
--- a/head/sys/gnu/fs/reiserfs/reiserfs_vfsops.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/gnu/fs/reiserfs/reiserfs_vfsops.c	Mon Jan 16 14:38:30 2012 +0200
@@ -2,9 +2,9 @@
  * Copyright 2000 Hans Reiser
  * See README for licensing and copyright details
  * 
- * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
+ * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
  * 
- * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_vfsops.c 222167 2011-05-22 01:07:54Z rmacklem $
+ * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_vfsops.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <gnu/fs/reiserfs/reiserfs_fs.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/gnu/fs/reiserfs/reiserfs_vnops.c
--- a/head/sys/gnu/fs/reiserfs/reiserfs_vnops.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/gnu/fs/reiserfs/reiserfs_vnops.c	Mon Jan 16 14:38:30 2012 +0200
@@ -2,9 +2,9 @@
  * Copyright 2000 Hans Reiser
  * See README for licensing and copyright details
  * 
- * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
+ * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron at club-internet.fr>
  * 
- * $FreeBSD$
+ * $FreeBSD: head/sys/gnu/fs/reiserfs/reiserfs_vnops.c 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #include <gnu/fs/reiserfs/reiserfs_fs.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/i386/conf/XENHVM
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/i386/conf/XENHVM	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,24 @@
+#
+# XENHVM -- Xen HVM kernel configuration file for FreeBSD/i386
+#
+# $FreeBSD: head/sys/i386/conf/XENHVM 230185 2012-01-16 02:42:41Z cperciva $
+#
+include		GENERIC
+ident		XENHVM
+
+makeoptions	MODULES_OVERRIDE=""
+
+#
+# Adaptive locks rely on a lock-free pointer read to determine the run state
+# of the thread holding a lock when under contention; under a virtualisation
+# system, the thread run state may not accurately reflect whether the thread
+# (or rather its host VCPU) is actually executing.  As such, disable this
+# optimisation.
+#
+options 	NO_ADAPTIVE_MUTEXES
+options 	NO_ADAPTIVE_RWLOCKS
+options 	NO_ADAPTIVE_SX
+
+# Xen HVM support
+options 	XENHVM
+device		xenpci
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/i386/ibcs2/coff.h
--- a/head/sys/i386/ibcs2/coff.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/i386/ibcs2/coff.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 1994 Sean Eric Fagan
- * Copyright (c) 1994 Søren Schmidt
+ * Copyright (c) 1994 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/i386/ibcs2/coff.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #ifndef _COFF_H
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/i386/ibcs2/ibcs2_isc.c
--- a/head/sys/i386/ibcs2/ibcs2_isc.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/i386/ibcs2/ibcs2_isc.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1994 Søren Schmidt
+ * Copyright (c) 1994 Søren Schmidt
  * Copyright (c) 1994 Sean Eric Fagan
  * Copyright (c) 1995 Steven Wallace
  * All rights reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/i386/ibcs2/ibcs2_isc.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/lock.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/i386/ibcs2/ibcs2_sysi86.c
--- a/head/sys/i386/ibcs2/ibcs2_sysi86.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/i386/ibcs2/ibcs2_sysi86.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1994 Søren Schmidt
+ * Copyright (c) 1994 Søren Schmidt
  * Copyright (c) 1995 Steven Wallace
  * All rights reserved.
  *
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/i386/ibcs2/ibcs2_sysi86.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/lock.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/i386/ibcs2/ibcs2_xenix.c
--- a/head/sys/i386/ibcs2/ibcs2_xenix.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/i386/ibcs2/ibcs2_xenix.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 1994 Sean Eric Fagan
- * Copyright (c) 1994 Søren Schmidt
+ * Copyright (c) 1994 Søren Schmidt
  * Copyright (c) 1995 Steven Wallace
  * All rights reserved.
  *
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/i386/ibcs2/ibcs2_xenix.c 225617 2011-09-16 13:58:51Z kmacy $");
+__FBSDID("$FreeBSD: head/sys/i386/ibcs2/ibcs2_xenix.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/i386/ibcs2/imgact_coff.c
--- a/head/sys/i386/ibcs2/imgact_coff.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/i386/ibcs2/imgact_coff.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 1994 Sean Eric Fagan
- * Copyright (c) 1994 Søren Schmidt
+ * Copyright (c) 1994 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/i386/ibcs2/imgact_coff.c 224613 2011-08-02 18:12:19Z kib $");
+__FBSDID("$FreeBSD: head/sys/i386/ibcs2/imgact_coff.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/i386/include/pcaudioio.h
--- a/head/sys/i386/include/pcaudioio.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/i386/include/pcaudioio.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1994 Søren Schmidt
+ * Copyright (c) 1994 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/i386/include/pcaudioio.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #ifndef	_MACHINE_PCAUDIOIO_H_
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/i386/linux/imgact_linux.c
--- a/head/sys/i386/linux/imgact_linux.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/i386/linux/imgact_linux.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1994-1996 Søren Schmidt
+ * Copyright (c) 1994-1996 Søren Schmidt
  * All rights reserved.
  *
  * Based heavily on /sys/kern/imgact_aout.c which is:
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/i386/linux/imgact_linux.c 220373 2011-04-05 20:23:59Z trasz $");
+__FBSDID("$FreeBSD: head/sys/i386/linux/imgact_linux.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/i386/linux/linux.h
--- a/head/sys/i386/linux/linux.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/i386/linux/linux.h	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1994-1996 Søren Schmidt
+ * Copyright (c) 1994-1996 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/i386/linux/linux.h 228957 2011-12-29 15:34:59Z jhb $
+ * $FreeBSD: head/sys/i386/linux/linux.h 230132 2012-01-15 13:23:18Z uqs $
  */
 
 #ifndef _I386_LINUX_H_
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/i386/linux/linux_dummy.c
--- a/head/sys/i386/linux/linux_dummy.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/i386/linux/linux_dummy.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1994-1995 Søren Schmidt
+ * Copyright (c) 1994-1995 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/i386/linux/linux_dummy.c 228957 2011-12-29 15:34:59Z jhb $");
+__FBSDID("$FreeBSD: head/sys/i386/linux/linux_dummy.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/i386/linux/linux_sysvec.c
--- a/head/sys/i386/linux/linux_sysvec.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/i386/linux/linux_sysvec.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1994-1996 Søren Schmidt
+ * Copyright (c) 1994-1996 Søren Schmidt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/i386/linux/linux_sysvec.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/kern/imgact_elf.c
--- a/head/sys/kern/imgact_elf.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/kern/imgact_elf.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2000 David O'Brien
- * Copyright (c) 1995-1996 Søren Schmidt
+ * Copyright (c) 1995-1996 Søren Schmidt
  * Copyright (c) 1996 Peter Wemm
  * All rights reserved.
  *
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/kern/imgact_elf.c 226388 2011-10-15 12:35:18Z kib $");
+__FBSDID("$FreeBSD: head/sys/kern/imgact_elf.c 230132 2012-01-15 13:23:18Z uqs $");
 
 #include "opt_capsicum.h"
 #include "opt_compat.h"
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/kern/kern_jail.c
--- a/head/sys/kern/kern_jail.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/kern/kern_jail.c	Mon Jan 16 14:38:30 2012 +0200
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/kern/kern_jail.c 227309 2011-11-07 15:43:11Z ed $");
+__FBSDID("$FreeBSD: head/sys/kern/kern_jail.c 230143 2012-01-15 18:08:15Z mm $");
 
 #include "opt_compat.h"
 #include "opt_ddb.h"
@@ -531,6 +531,7 @@
 	int gotchildmax, gotenforce, gothid, gotslevel;
 	int fi, jid, jsys, len, level;
 	int childmax, slevel, vfslocked;
+	int fullpath_disabled;
 #if defined(INET) || defined(INET6)
 	int ii, ij;
 #endif
@@ -880,6 +881,7 @@
 	}
 #endif
 
+	fullpath_disabled = 0;
 	root = NULL;
 	error = vfs_getopt(opts, "path", (void **)&path, &len);
 	if (error == ENOENT)
@@ -897,30 +899,40 @@
 			error = EINVAL;
 			goto done_free;
 		}
-		if (len < 2 || (len == 2 && path[0] == '/'))
-			path = NULL;
-		else {
+		NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE, UIO_SYSSPACE,
+		    path, td);
+		error = namei(&nd);
+		if (error)
+			goto done_free;
+		vfslocked = NDHASGIANT(&nd);
+		root = nd.ni_vp;
+		NDFREE(&nd, NDF_ONLY_PNBUF);
+		error = vn_path_to_global_path(td, root, path, MAXPATHLEN);
+		if (error == ENODEV) {
+			/* proceed if sysctl debug.disablefullpath == 1 */
+			fullpath_disabled = 1;
+			if (len < 2 || (len == 2 && path[0] == '/'))
+				path = NULL;
+		} else if (error != 0) {
+			/* exit on other errors */
+			VFS_UNLOCK_GIANT(vfslocked);
+			goto done_free;
+		}
+		if (root->v_type != VDIR) {
+			error = ENOTDIR;
+			vput(root);
+			VFS_UNLOCK_GIANT(vfslocked);
+			goto done_free;
+		}
+		VOP_UNLOCK(root, 0);
+		VFS_UNLOCK_GIANT(vfslocked);
+		if (fullpath_disabled) {
 			/* Leave room for a real-root full pathname. */
 			if (len + (path[0] == '/' && strcmp(mypr->pr_path, "/")
 			    ? strlen(mypr->pr_path) : 0) > MAXPATHLEN) {
 				error = ENAMETOOLONG;
 				goto done_free;
 			}
-			NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW, UIO_SYSSPACE,
-			    path, td);
-			error = namei(&nd);
-			if (error)
-				goto done_free;
-			vfslocked = NDHASGIANT(&nd);
-			root = nd.ni_vp;
-			NDFREE(&nd, NDF_ONLY_PNBUF);
-			if (root->v_type != VDIR) {
-				error = ENOTDIR;
-				vrele(root);
-				VFS_UNLOCK_GIANT(vfslocked);
-				goto done_free;
-			}
-			VFS_UNLOCK_GIANT(vfslocked);
 		}
 	}
 
@@ -1583,7 +1595,8 @@
 	}
 	if (path != NULL) {
 		/* Try to keep a real-rooted full pathname. */
-		if (path[0] == '/' && strcmp(mypr->pr_path, "/"))
+		if (fullpath_disabled && path[0] == '/' &&
+		    strcmp(mypr->pr_path, "/"))
 			snprintf(pr->pr_path, sizeof(pr->pr_path), "%s%s",
 			    mypr->pr_path, path);
 		else
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/kern/kern_proc.c
--- a/head/sys/kern/kern_proc.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/kern/kern_proc.c	Mon Jan 16 14:38:30 2012 +0200
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/kern/kern_proc.c 228666 2011-12-17 22:18:26Z trociny $");
+__FBSDID("$FreeBSD: head/sys/kern/kern_proc.c 230145 2012-01-15 18:47:24Z trociny $");
 
 #include "opt_compat.h"
 #include "opt_ddb.h"
@@ -1631,20 +1631,19 @@
 
 static int
 get_ps_strings(struct thread *td, struct proc *p, struct sbuf *sb,
-    enum proc_vector_type type, size_t nchr)
+    enum proc_vector_type type)
 {
-	size_t done, len, vsize;
+	size_t done, len, nchr, vsize;
 	int error, i;
 	char **proc_vector, *sptr;
 	char pss_string[GET_PS_STRINGS_CHUNK_SZ];
 
 	PROC_ASSERT_HELD(p);
 
-	 /*
-	  * We are not going to read more than 2 * (PATH_MAX + ARG_MAX) bytes.
-	  */
-	if (nchr > 2 * (PATH_MAX + ARG_MAX))
-		nchr = 2 * (PATH_MAX + ARG_MAX);
+	/*
+	 * We are not going to read more than 2 * (PATH_MAX + ARG_MAX) bytes.
+	 */
+	nchr = 2 * (PATH_MAX + ARG_MAX);
 
 	error = get_proc_vector(td, p, &proc_vector, &vsize, type);
 	if (error != 0)
@@ -1679,17 +1678,17 @@
 }
 
 int
-proc_getargv(struct thread *td, struct proc *p, struct sbuf *sb, size_t nchr)
+proc_getargv(struct thread *td, struct proc *p, struct sbuf *sb)
 {
 
-	return (get_ps_strings(curthread, p, sb, PROC_ARG, nchr));
+	return (get_ps_strings(curthread, p, sb, PROC_ARG));
 }
 
 int
-proc_getenvv(struct thread *td, struct proc *p, struct sbuf *sb, size_t nchr)
+proc_getenvv(struct thread *td, struct proc *p, struct sbuf *sb)
 {
 
-	return (get_ps_strings(curthread, p, sb, PROC_ENV, nchr));
+	return (get_ps_strings(curthread, p, sb, PROC_ENV));
 }
 
 /*
@@ -1728,7 +1727,7 @@
 		_PHOLD(p);
 		PROC_UNLOCK(p);
 		sbuf_new_for_sysctl(&sb, NULL, GET_PS_STRINGS_CHUNK_SZ, req);
-		error = proc_getargv(curthread, p, &sb, req->oldlen);
+		error = proc_getargv(curthread, p, &sb);
 		error2 = sbuf_finish(&sb);
 		PRELE(p);
 		sbuf_delete(&sb);
@@ -1780,7 +1779,7 @@
 	}
 
 	sbuf_new_for_sysctl(&sb, NULL, GET_PS_STRINGS_CHUNK_SZ, req);
-	error = proc_getenvv(curthread, p, &sb, req->oldlen);
+	error = proc_getenvv(curthread, p, &sb);
 	error2 = sbuf_finish(&sb);
 	PRELE(p);
 	sbuf_delete(&sb);
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/kern/kern_umtx.c
--- a/head/sys/kern/kern_umtx.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/kern/kern_umtx.c	Mon Jan 16 14:38:30 2012 +0200
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/kern/kern_umtx.c 228219 2011-12-03 12:30:58Z pho $");
+__FBSDID("$FreeBSD: head/sys/kern/kern_umtx.c 230194 2012-01-16 04:39:10Z davidxu $");
 
 #include "opt_compat.h"
 #include <sys/param.h>
@@ -2804,9 +2804,8 @@
 	umtxq_insert(uq);
 	umtxq_unlock(&uq->uq_key);
 
-	if (fuword32(__DEVOLATILE(uint32_t *, &sem->_has_waiters)) == 0)
-		casuword32(__DEVOLATILE(uint32_t *, &sem->_has_waiters), 0, 1);
-
+	casuword32(__DEVOLATILE(uint32_t *, &sem->_has_waiters), 0, 1);
+	rmb();
 	count = fuword32(__DEVOLATILE(uint32_t *, &sem->_count));
 	if (count != 0) {
 		umtxq_lock(&uq->uq_key);
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/kern/link_elf_obj.c
--- a/head/sys/kern/link_elf_obj.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/kern/link_elf_obj.c	Mon Jan 16 14:38:30 2012 +0200
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/kern/link_elf_obj.c 220730 2011-04-16 16:20:51Z dchagin $");
+__FBSDID("$FreeBSD: head/sys/kern/link_elf_obj.c 230097 2012-01-14 00:36:07Z gonzo $");
 
 #include "opt_ddb.h"
 
@@ -684,7 +684,11 @@
 	 * location of code and data in the kernel's address space, request a
 	 * mapping that is above the kernel.  
 	 */
+#ifdef __amd64__
 	mapbase = KERNBASE;
+#else
+	mapbase = VM_MIN_KERNEL_ADDRESS;
+#endif
 	error = vm_map_find(kernel_map, ef->object, 0, &mapbase,
 	    round_page(mapsize), TRUE, VM_PROT_ALL, VM_PROT_ALL, FALSE);
 	if (error) {
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/kern/subr_bus.c
--- a/head/sys/kern/subr_bus.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/kern/subr_bus.c	Mon Jan 16 14:38:30 2012 +0200
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/kern/subr_bus.c 228211 2011-12-02 22:03:27Z marius $");
+__FBSDID("$FreeBSD: head/sys/kern/subr_bus.c 230125 2012-01-15 07:09:18Z eadler $");
 
 #include "opt_bus.h"
 
@@ -2030,9 +2030,15 @@
 			if (!hasclass) {
 				if (device_set_devclass(child,
 				    dl->driver->name) != 0) {
+					char const * devname =
+					    device_get_name(child);
+					if (devname == NULL)
+						devname = "(unknown)";
 					printf("driver bug: Unable to set "
-					    "devclass (devname: %s)\n",
-					    device_get_name(child));
+					    "devclass (class: %s "
+					    "devname: %s)\n",
+					    dl->driver->name,
+					    devname);
 					(void)device_set_driver(child, NULL);
 					continue;
 				}
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/kern/vfs_cache.c
--- a/head/sys/kern/vfs_cache.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/kern/vfs_cache.c	Mon Jan 16 14:38:30 2012 +0200
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/kern/vfs_cache.c 228433 2011-12-12 10:05:13Z avg $");
+__FBSDID("$FreeBSD: head/sys/kern/vfs_cache.c 230143 2012-01-15 18:08:15Z mm $");
 
 #include "opt_kdtrace.h"
 #include "opt_ktrace.h"
@@ -45,6 +45,7 @@
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
+#include <sys/fcntl.h>
 #include <sys/mount.h>
 #include <sys/namei.h>
 #include <sys/proc.h>
@@ -1278,3 +1279,76 @@
 	buf[l] = '\0';
 	return (0);
 }
+
+/*
+ * This function updates path string to vnode's full global path
+ * and checks the size of the new path string against the pathlen argument.
+ *
+ * Requires a locked, referenced vnode and GIANT lock held.
+ * Vnode is re-locked on success or ENODEV, otherwise unlocked.
+ *
+ * If sysctl debug.disablefullpath is set, ENODEV is returned,
+ * vnode is left locked and path remain untouched.
+ *
+ * If vp is a directory, the call to vn_fullpath_global() always succeeds
+ * because it falls back to the ".." lookup if the namecache lookup fails.
+ */
+int
+vn_path_to_global_path(struct thread *td, struct vnode *vp, char *path,
+    u_int pathlen)
+{
+	struct nameidata nd;
+	struct vnode *vp1;
+	char *rpath, *fbuf;
+	int error, vfslocked;
+
+	VFS_ASSERT_GIANT(vp->v_mount);
+	ASSERT_VOP_ELOCKED(vp, __func__);
+
+	/* Return ENODEV if sysctl debug.disablefullpath==1 */
+	if (disablefullpath)
+		return (ENODEV);
+
+	/* Construct global filesystem path from vp. */
+	VOP_UNLOCK(vp, 0);
+	error = vn_fullpath_global(td, vp, &rpath, &fbuf);
+
+	if (error != 0) {
+		vrele(vp);
+		return (error);
+	}
+
+	if (strlen(rpath) >= pathlen) {
+		vrele(vp);
+		error = ENAMETOOLONG;
+		goto out;
+	}
+
+	/*
+	 * Re-lookup the vnode by path to detect a possible rename.
+	 * As a side effect, the vnode is relocked.
+	 * If vnode was renamed, return ENOENT.
+	 */
+	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
+	    UIO_SYSSPACE, path, td);
+	error = namei(&nd);
+	if (error != 0) {
+		vrele(vp);
+		goto out;
+	}
+	vfslocked = NDHASGIANT(&nd);
+	NDFREE(&nd, NDF_ONLY_PNBUF);
+	vp1 = nd.ni_vp;
+	vrele(vp);
+	if (vp1 == vp)
+		strcpy(path, rpath);
+	else {
+		vput(vp1);
+		error = ENOENT;
+	}
+	VFS_UNLOCK_GIANT(vfslocked);
+
+out:
+	free(fbuf, M_TEMP);
+	return (error);
+}
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/kern/vfs_mount.c
--- a/head/sys/kern/vfs_mount.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/kern/vfs_mount.c	Mon Jan 16 14:38:30 2012 +0200
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/kern/vfs_mount.c 227333 2011-11-08 10:18:07Z attilio $");
+__FBSDID("$FreeBSD: head/sys/kern/vfs_mount.c 230129 2012-01-15 12:08:20Z mm $");
 
 #include "opt_vfs_allow_nonmpsafe.h"
 
@@ -1085,11 +1085,14 @@
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	vp = nd.ni_vp;
 	if ((fsflags & MNT_UPDATE) == 0) {
-		error = vfs_domount_first(td, vfsp, fspath, vp, fsflags,
-		    optlist);
-	} else {
+		error = vn_path_to_global_path(td, vp, fspath, MNAMELEN);
+		/* debug.disablefullpath == 1 results in ENODEV */
+		if (error == 0 || error == ENODEV) {
+			error = vfs_domount_first(td, vfsp, fspath, vp,
+			    fsflags, optlist);
+		}
+	} else
 		error = vfs_domount_update(td, vp, fsflags, optlist);
-	}
 	mtx_unlock(&Giant);
 
 	ASSERT_VI_UNLOCKED(vp, __func__);
@@ -1119,9 +1122,10 @@
 		int flags;
 	} */ *uap;
 {
+	struct nameidata nd;
 	struct mount *mp;
 	char *pathbuf;
-	int error, id0, id1;
+	int error, id0, id1, vfslocked;
 
 	AUDIT_ARG_VALUE(uap->flags);
 	if (jailed(td->td_ucred) || usermount == 0) {
@@ -1155,6 +1159,21 @@
 		mtx_unlock(&mountlist_mtx);
 	} else {
 		AUDIT_ARG_UPATH1(td, pathbuf);
+		/*
+		 * Try to find global path for path argument.
+		 */
+		NDINIT(&nd, LOOKUP,
+		    FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
+		    UIO_SYSSPACE, pathbuf, td);
+		if (namei(&nd) == 0) {
+			vfslocked = NDHASGIANT(&nd);
+			NDFREE(&nd, NDF_ONLY_PNBUF);
+			error = vn_path_to_global_path(td, nd.ni_vp, pathbuf,
+			    MNAMELEN);
+			if (error == 0 || error == ENODEV)
+				vput(nd.ni_vp);
+			VFS_UNLOCK_GIANT(vfslocked);
+		}
 		mtx_lock(&mountlist_mtx);
 		TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) {
 			if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0)
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/mips/atheros/ar71xx_machdep.c
--- a/head/sys/mips/atheros/ar71xx_machdep.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/mips/atheros/ar71xx_machdep.c	Mon Jan 16 14:38:30 2012 +0200
@@ -25,9 +25,10 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/mips/atheros/ar71xx_machdep.c 227924 2011-11-24 07:32:52Z adrian $");
+__FBSDID("$FreeBSD: head/sys/mips/atheros/ar71xx_machdep.c 230195 2012-01-16 05:07:32Z adrian $");
 
 #include "opt_ddb.h"
+#include "opt_ar71xx.h"
 
 #include <sys/param.h>
 #include <sys/conf.h>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/mips/atheros/ar71xx_pci.c
--- a/head/sys/mips/atheros/ar71xx_pci.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/mips/atheros/ar71xx_pci.c	Mon Jan 16 14:38:30 2012 +0200
@@ -26,7 +26,9 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/mips/atheros/ar71xx_pci.c 227843 2011-11-22 21:28:20Z marius $");
+__FBSDID("$FreeBSD: head/sys/mips/atheros/ar71xx_pci.c 230195 2012-01-16 05:07:32Z adrian $");
+
+#include "opt_ar71xx.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -248,6 +250,77 @@
 	}
 }
 
+#ifdef	AR71XX_ATH_EEPROM
+/*
+ * Some embedded boards (eg AP94) have the MAC attached via PCI but they
+ * don't have the MAC-attached EEPROM.  The register initialisation
+ * values and calibration data are stored in the on-board flash.
+ * This routine initialises the NIC via the EEPROM register contents
+ * before the probe/attach routines get a go at things.
+ */
+static void
+ar71xx_pci_fixup(device_t dev, u_int bus, u_int slot, u_int func,
+    long flash_addr)
+{
+	uint16_t *cal_data = (uint16_t *) MIPS_PHYS_TO_KSEG1(flash_addr);
+	uint32_t reg, val, bar0;
+
+	printf("%s: flash_addr=%lx, cal_data=%p\n",
+	    __func__, flash_addr, cal_data);
+
+	/* XXX check 0xa55a */
+	/* Save bar(0) address - just to flush bar(0) (SoC WAR) ? */
+	bar0 = ar71xx_pci_read_config(dev, bus, slot, func, PCIR_BAR(0), 4);
+	ar71xx_pci_write_config(dev, bus, slot, func, PCIR_BAR(0),
+	    AR71XX_PCI_MEM_BASE, 4);
+
+	val = ar71xx_pci_read_config(dev, bus, slot, func, PCIR_COMMAND, 2);
+	val |= (PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN);
+	ar71xx_pci_write_config(dev, bus, slot, func, PCIR_COMMAND, val, 2); 
+
+	cal_data += 3;
+	while (*cal_data != 0xffff) {
+		reg = *cal_data++;
+		val = *cal_data++;
+		val |= (*cal_data++) << 16;
+		printf("  reg: %x, val=%x\n", reg, val);
+
+		/* Write eeprom fixup data to device memory */
+		ATH_WRITE_REG(AR71XX_PCI_MEM_BASE + reg, val);
+		DELAY(100);
+	}
+
+	val = ar71xx_pci_read_config(dev, bus, slot, func, PCIR_COMMAND, 2);
+	val &= ~(PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN);
+	ar71xx_pci_write_config(dev, bus, slot, func, PCIR_COMMAND, val, 2);
+
+	/* Write the saved bar(0) address */
+	ar71xx_pci_write_config(dev, bus, slot, func, PCIR_BAR(0), bar0, 4);
+}
+
+static void
+ar71xx_pci_slot_fixup(device_t dev, u_int bus, u_int slot, u_int func)
+{
+	long int flash_addr;
+	char buf[32];
+
+	/*
+	 * Check whether the given slot has a hint to poke.
+	 */
+	printf("%s: checking dev %s, %d/%d/%d\n",
+	    __func__, device_get_nameunit(dev), bus, slot, func);
+	snprintf(buf, sizeof(buf), "bus.%d.%d.%d.ath_fixup_addr",
+	    bus, slot, func);
+
+	if (resource_long_value(device_get_name(dev), device_get_unit(dev),
+	    buf, &flash_addr) == 0) {
+		printf("%s: found fixupaddr at %lx: updating\n",
+		    __func__, flash_addr);
+		ar71xx_pci_fixup(dev, bus, slot, func, flash_addr);
+	}
+}
+#endif	/* AR71XX_ATH_EEPROM */
+
 static int
 ar71xx_pci_probe(device_t dev)
 {
@@ -321,6 +394,16 @@
 	    | PCIM_CMD_SERRESPEN | PCIM_CMD_BACKTOBACK
 	    | PCIM_CMD_PERRESPEN | PCIM_CMD_MWRICEN, 2);
 
+#ifdef	AR71XX_ATH_EEPROM
+	/*
+	 * Hard-code a check for slot 17 and 18 - these are
+	 * the two PCI slots which may have a PCI device that
+	 * requires "fixing".
+	 */
+	ar71xx_pci_slot_fixup(dev, 0, 17, 0);
+	ar71xx_pci_slot_fixup(dev, 0, 18, 0);
+#endif	/* AR71XX_ATH_EEPROM */
+
 	device_add_child(dev, "pci", busno);
 	return (bus_generic_attach(dev));
 }
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/mips/conf/AR71XX_BASE
--- a/head/sys/mips/conf/AR71XX_BASE	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/mips/conf/AR71XX_BASE	Mon Jan 16 14:38:30 2012 +0200
@@ -4,7 +4,7 @@
 # This includes all the common drivers for the AR71XX boards along with
 # the usb, net80211 and atheros driver code.
 #
-# $FreeBSD: head/sys/mips/conf/AR71XX_BASE 228987 2011-12-30 09:39:24Z adrian $
+# $FreeBSD: head/sys/mips/conf/AR71XX_BASE 230152 2012-01-15 19:43:56Z adrian $
 #
 
 machine		mips mipseb
@@ -24,8 +24,9 @@
 
 makeoptions	DEBUG=-g		#Build kernel with gdb(1) debug symbols
 
-# Also build these as modules, just to ensure the build gets tested.
-makeoptions	MODULES_OVERRIDE="wlan wlan_xauth wlan_acl wlan_wep wlan_tkip wlan_ccmp wlan_rssadapt wlan_amrr ath ath_pci"
+# Build these as modules so small platform builds will have the
+# modules already built.
+makeoptions	MODULES_OVERRIDE="random gpio ar71xx if_gif if_gre if_bridge bridgestp usb wlan wlan_xauth wlan_acl wlan_wep wlan_tkip wlan_ccmp wlan_rssadapt wlan_amrr ath ath_pci"
 
 options		DDB
 options		KDB
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/mips/include/db_machdep.h
--- a/head/sys/mips/include/db_machdep.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/mips/include/db_machdep.h	Mon Jan 16 14:38:30 2012 +0200
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	JNPR: db_machdep.h,v 1.7 2006/10/16 12:30:34 katta
- * $FreeBSD$
+ * $FreeBSD: head/sys/mips/include/db_machdep.h 230094 2012-01-13 23:31:36Z gonzo $
  */
 
 #ifndef	_MIPS_DB_MACHDEP_H_
@@ -93,6 +93,7 @@
 int db_inst_type(int);
 db_addr_t branch_taken(int inst, db_addr_t pc);
 void stacktrace_subr(register_t pc, register_t sp, register_t ra, int (*)(const char *, ...));
-int kdbpeek(int *);
+int32_t kdbpeek(int *);
+int64_t kdbpeekd(int *);
 
 #endif	/* !_MIPS_DB_MACHDEP_H_ */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/mips/include/float.h
--- a/head/sys/mips/include/float.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/mips/include/float.h	Mon Jan 16 14:38:30 2012 +0200
@@ -29,7 +29,7 @@
  *	from: @(#)float.h	7.1 (Berkeley) 5/8/90
  *	from: src/sys/i386/include/float.h,v 1.8 1999/08/28 00:44:11 peter
  *	JNPR: float.h,v 1.4 2006/12/02 09:53:41 katta
- * $FreeBSD$
+ * $FreeBSD: head/sys/mips/include/float.h 230199 2012-01-16 05:23:27Z das $
  */
 
 #ifndef _MACHINE_FLOAT_H_
@@ -47,12 +47,11 @@
 #else
 #define	FLT_ROUNDS	-1
 #endif
-/*
- * XXXMIPS: MIPS32 has both float and double type, so set FLT_EVAL_METHOD
- *   to 0. Check it for 64-bits systems.
- */
+
+#if __ISO_C_VISIBLE >= 1999
 #define	FLT_EVAL_METHOD	0
 #define	DECIMAL_DIG	17
+#endif
 
 #define	FLT_MANT_DIG	24		/* p */
 #define	FLT_EPSILON	1.19209290E-07F /* b**(1-p) */
@@ -75,13 +74,13 @@
 #define	DBL_MAX_10_EXP	308
 
 #define	LDBL_MANT_DIG	DBL_MANT_DIG
-#define	LDBL_EPSILON	DBL_EPSILON
+#define	LDBL_EPSILON	(long double)DBL_EPSILON
 #define	LDBL_DIG	DBL_DIG
 #define	LDBL_MIN_EXP	DBL_MIN_EXP
-#define	LDBL_MIN	DBL_MIN
+#define	LDBL_MIN	(long double)DBL_MIN
 #define	LDBL_MIN_10_EXP DBL_MIN_10_EXP
 #define	LDBL_MAX_EXP	DBL_MAX_EXP
-#define	LDBL_MAX	DBL_MAX
+#define	LDBL_MAX	(long double)DBL_MAX
 #define	LDBL_MAX_10_EXP DBL_MAX_10_EXP
 
 #endif /* _MACHINE_FLOAT_H_ */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/mips/mips/db_trace.c
--- a/head/sys/mips/mips/db_trace.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/mips/mips/db_trace.c	Mon Jan 16 14:38:30 2012 +0200
@@ -6,7 +6,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/mips/mips/db_trace.c 228091 2011-11-28 19:48:04Z gonzo $");
+__FBSDID("$FreeBSD: head/sys/mips/mips/db_trace.c 230094 2012-01-13 23:31:36Z gonzo $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -49,10 +49,13 @@
  */
 #define	MIPS_END_OF_FUNCTION(ins)	((ins) == 0x03e00008)
 
-/*
- * kdbpeekD(addr) - skip one word starting at 'addr', then read the second word
- */
-#define	kdbpeekD(addr)	kdbpeek(((int *)(addr)) + 1)
+#if defined(__mips_n64)
+#	define	MIPS_IS_VALID_KERNELADDR(reg)	((((reg) & 3) == 0) && \
+					((vm_offset_t)(reg) >= MIPS_XKPHYS_START))
+#else
+#	define	MIPS_IS_VALID_KERNELADDR(reg)	((((reg) & 3) == 0) && \
+					((vm_offset_t)(reg) >= MIPS_KSEG0_START))
+#endif
 
 /*
  * Functions ``special'' enough to print by name
@@ -141,8 +144,8 @@
 	}
 	/* check for bad SP: could foul up next frame */
 	/*XXX MIPS64 bad: this hard-coded SP is lame */
-	if (sp & 3 || (uintptr_t)sp < 0x80000000u) {
-		(*printfn) ("SP 0x%x: not in kernel\n", sp);
+	if (!MIPS_IS_VALID_KERNELADDR(sp)) {
+		(*printfn) ("SP 0x%jx: not in kernel\n", sp);
 		ra = 0;
 		subr = 0;
 		goto done;
@@ -182,8 +185,8 @@
 	}
 	/* check for bad PC */
 	/*XXX MIPS64 bad: These hard coded constants are lame */
-	if (pc & 3 || pc < (uintptr_t)0x80000000) {
-		(*printfn) ("PC 0x%x: not in kernel\n", pc);
+	if (!MIPS_IS_VALID_KERNELADDR(pc)) {
+		(*printfn) ("PC 0x%jx: not in kernel\n", pc);
 		ra = 0;
 		goto done;
 	}
@@ -304,27 +307,27 @@
 			mask |= (1 << i.IType.rt);
 			switch (i.IType.rt) {
 			case 4:/* a0 */
-				args[0] = kdbpeekD((int *)(sp + (short)i.IType.imm));
+				args[0] = kdbpeekd((int *)(sp + (short)i.IType.imm));
 				valid_args[0] = 1;
 				break;
 
 			case 5:/* a1 */
-				args[1] = kdbpeekD((int *)(sp + (short)i.IType.imm));
+				args[1] = kdbpeekd((int *)(sp + (short)i.IType.imm));
 				valid_args[1] = 1;
 				break;
 
 			case 6:/* a2 */
-				args[2] = kdbpeekD((int *)(sp + (short)i.IType.imm));
+				args[2] = kdbpeekd((int *)(sp + (short)i.IType.imm));
 				valid_args[2] = 1;
 				break;
 
 			case 7:/* a3 */
-				args[3] = kdbpeekD((int *)(sp + (short)i.IType.imm));
+				args[3] = kdbpeekd((int *)(sp + (short)i.IType.imm));
 				valid_args[3] = 1;
 				break;
 
 			case 31:	/* ra */
-				ra = kdbpeekD((int *)(sp + (short)i.IType.imm));
+				ra = kdbpeekd((int *)(sp + (short)i.IType.imm));
 			}
 			break;
 
@@ -350,7 +353,7 @@
 			(*printfn)("?");
 	}
 
-	(*printfn) (") ra %x sp %x sz %d\n", ra, sp, stksize);
+	(*printfn) (") ra %jx sp %jx sz %d\n", ra, sp, stksize);
 
 	if (ra) {
 		if (pc == ra && stksize == 0)
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/mips/mips/elf_machdep.c
--- a/head/sys/mips/mips/elf_machdep.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/mips/mips/elf_machdep.c	Mon Jan 16 14:38:30 2012 +0200
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/mips/mips/elf_machdep.c 229803 2012-01-08 05:44:19Z gonzo $");
+__FBSDID("$FreeBSD: head/sys/mips/mips/elf_machdep.c 230046 2012-01-13 07:00:47Z gonzo $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -227,7 +227,11 @@
 			return (-1);
 
 		addend &= 0x03ffffff;
-		addend <<= 2;
+		/*
+		 * Addendum for .rela R_MIPS_26 is not shifted right
+		 */
+		if (rela == NULL)
+			addend <<= 2;
 
 		addr += ((Elf_Addr)where & 0xf0000000) | addend;
 		addr >>= 2;
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/mips/mips/support.S
--- a/head/sys/mips/mips/support.S	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/mips/mips/support.S	Mon Jan 16 14:38:30 2012 +0200
@@ -47,7 +47,7 @@
  *
  *	from: @(#)locore.s	8.5 (Berkeley) 1/4/94
  *	JNPR: support.S,v 1.5.2.2 2007/08/29 10:03:49 girish
- * $FreeBSD$
+ * $FreeBSD: head/sys/mips/mips/support.S 230094 2012-01-13 23:31:36Z gonzo $
  */
 
 /*
@@ -1340,6 +1340,25 @@
 	PTR_S	zero, U_PCB_ONFAULT(t1)
 END(kdbpeek)
 
+LEAF(kdbpeekd)
+	PTR_LA	v1, ddberr
+	and	v0, a0, 3			# unaligned ?
+	GET_CPU_PCPU(t1)
+	PTR_L	t1, PC_CURPCB(t1)
+	bne	v0, zero, 1f
+	PTR_S	v1, U_PCB_ONFAULT(t1)
+
+	ld	v0, (a0)
+	jr	ra
+	PTR_S	zero, U_PCB_ONFAULT(t1)
+
+1:
+	REG_LHI	v0, 0(a0)
+	REG_LLO	v0, 7(a0)
+	jr	ra
+	PTR_S	zero, U_PCB_ONFAULT(t1)
+END(kdbpeekd)
+
 ddberr:
 	jr	ra
 	nop
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/modules/ar71xx/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/modules/ar71xx/Makefile	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,30 @@
+#
+# $FreeBSD: head/sys/modules/ar71xx/Makefile 230151 2012-01-15 19:42:55Z adrian $
+#
+# Copyright (c) 2011 Adrian Chadd.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+SUBDIR = ar71xx_ehci ar71xx_ohci
+
+.include <bsd.subdir.mk>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/modules/ar71xx/ar71xx_ehci/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/modules/ar71xx/ar71xx_ehci/Makefile	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2012 Adrian Chadd, Xenion Pty Ltd
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer,
+#    without modification.
+# 2. Redistributions in binary form must reproduce at minimum a disclaimer
+#    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+#    redistribution must be conditioned upon including a substantially
+#    similar Disclaimer requirement for further binary redistribution.
+#
+# NO WARRANTY
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGES.
+#
+# $FreeBSD: head/sys/modules/ar71xx/ar71xx_ehci/Makefile 230151 2012-01-15 19:42:55Z adrian $
+#
+
+.PATH:	${.CURDIR}/../../../mips/atheros/
+
+KMOD=	ar71xx_ehci
+SRCS=	ar71xx_ehci.c
+SRCS+=	device_if.h bus_if.h usb_if.h opt_usb.h opt_bus.h
+
+.PATH: ${.CURDIR}/../../../dev/usb/controller/
+SRCS+=	ehci.c
+
+CFLAGS+=  -I. -I${.CURDIR}/../../../mips/atheros
+
+.include <bsd.kmod.mk>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/modules/ar71xx/ar71xx_ohci/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/modules/ar71xx/ar71xx_ohci/Makefile	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2012 Adrian Chadd, Xenion Pty Ltd
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer,
+#    without modification.
+# 2. Redistributions in binary form must reproduce at minimum a disclaimer
+#    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+#    redistribution must be conditioned upon including a substantially
+#    similar Disclaimer requirement for further binary redistribution.
+#
+# NO WARRANTY
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGES.
+#
+# $FreeBSD: head/sys/modules/ar71xx/ar71xx_ohci/Makefile 230151 2012-01-15 19:42:55Z adrian $
+#
+
+.PATH:	${.CURDIR}/../../../mips/atheros/
+
+KMOD=	ar71xx_ohci
+SRCS=	ar71xx_ohci.c
+SRCS+=	device_if.h bus_if.h usb_if.h opt_usb.h opt_bus.h
+
+CFLAGS+=  -I. -I${.CURDIR}/../../../mips/atheros
+
+.PATH:	${.CURDIR}/../../../dev/usb/controller/
+SRCS+=	 ohci.c
+
+.include <bsd.kmod.mk>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/modules/gpio/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/modules/gpio/Makefile	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,30 @@
+#
+# $FreeBSD: head/sys/modules/gpio/Makefile 230150 2012-01-15 19:40:59Z adrian $
+#
+# Copyright (c) 2011 Adrian Chadd.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+SUBDIR = gpiobus gpioiic gpioled
+
+.include <bsd.subdir.mk>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/modules/gpio/gpiobus/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/modules/gpio/gpiobus/Makefile	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2012 Adrian Chadd, Xenion Pty Ltd
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer,
+#    without modification.
+# 2. Redistributions in binary form must reproduce at minimum a disclaimer
+#    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+#    redistribution must be conditioned upon including a substantially
+#    similar Disclaimer requirement for further binary redistribution.
+#
+# NO WARRANTY
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGES.
+#
+# $FreeBSD: head/sys/modules/gpio/gpiobus/Makefile 230150 2012-01-15 19:40:59Z adrian $
+#
+
+.PATH:	${.CURDIR}/../../../dev/gpio/
+
+KMOD=	gpiobus
+SRCS=	gpiobus.c
+SRCS+=	device_if.h bus_if.h gpio_if.h gpiobus_if.h
+
+CFLAGS+=  -I. -I${.CURDIR}/../../../dev/gpio/
+
+.include <bsd.kmod.mk>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/modules/gpio/gpioiic/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/modules/gpio/gpioiic/Makefile	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2012 Adrian Chadd, Xenion Pty Ltd
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer,
+#    without modification.
+# 2. Redistributions in binary form must reproduce at minimum a disclaimer
+#    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+#    redistribution must be conditioned upon including a substantially
+#    similar Disclaimer requirement for further binary redistribution.
+#
+# NO WARRANTY
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGES.
+#
+# $FreeBSD: head/sys/modules/gpio/gpioiic/Makefile 230150 2012-01-15 19:40:59Z adrian $
+#
+
+.PATH:	${.CURDIR}/../../../dev/gpio/
+
+KMOD=	gpioiic
+SRCS=	gpioiic.c
+SRCS+=	device_if.h bus_if.h gpio_if.h gpiobus_if.h iicbus_if.h iicbb_if.h
+
+CFLAGS+=  -I. -I${.CURDIR}/../../../dev/gpio/
+
+.include <bsd.kmod.mk>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/modules/gpio/gpioled/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sys/modules/gpio/gpioled/Makefile	Mon Jan 16 14:38:30 2012 +0200
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2012 Adrian Chadd, Xenion Pty Ltd
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer,
+#    without modification.
+# 2. Redistributions in binary form must reproduce at minimum a disclaimer
+#    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+#    redistribution must be conditioned upon including a substantially
+#    similar Disclaimer requirement for further binary redistribution.
+#
+# NO WARRANTY
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGES.
+#
+# $FreeBSD: head/sys/modules/gpio/gpioled/Makefile 230150 2012-01-15 19:40:59Z adrian $
+#
+
+.PATH:	${.CURDIR}/../../../dev/gpio/
+
+KMOD=	gpioled
+SRCS=	gpioled.c
+SRCS+=	device_if.h bus_if.h gpio_if.h gpiobus_if.h
+
+CFLAGS+=  -I. -I${.CURDIR}/../../../dev/gpio/
+
+.include <bsd.kmod.mk>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/modules/sound/driver/hda/Makefile
--- a/head/sys/modules/sound/driver/hda/Makefile	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/modules/sound/driver/hda/Makefile	Mon Jan 16 14:38:30 2012 +0200
@@ -1,9 +1,10 @@
-# $FreeBSD$
+# $FreeBSD: head/sys/modules/sound/driver/hda/Makefile 230130 2012-01-15 13:21:36Z mav $
 
 .PATH: ${.CURDIR}/../../../../dev/sound/pci/hda
 
 KMOD=	snd_hda
-SRCS=	device_if.h bus_if.h pci_if.h channel_if.h mixer_if.h
-SRCS+=	hdac.c hdac_private.h hdac_reg.h hda_reg.h hdac.h
+SRCS=	device_if.h bus_if.h pci_if.h channel_if.h mixer_if.h hdac_if.h
+SRCS+=	hdaa.c hdaa.h hdaa_patches.c hdac.c hdac_if.h hdac_if.c
+SRCS+=	hdacc.c hdac_private.h hdac_reg.h hda_reg.h hdac.h
 
 .include <bsd.kmod.mk>
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/modules/wlan/Makefile
--- a/head/sys/modules/wlan/Makefile	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/modules/wlan/Makefile	Mon Jan 16 14:38:30 2012 +0200
@@ -1,4 +1,4 @@
-# $FreeBSD: head/sys/modules/wlan/Makefile 222161 2011-05-21 16:34:53Z bschmidt $
+# $FreeBSD: head/sys/modules/wlan/Makefile 230153 2012-01-15 19:45:23Z adrian $
 
 .PATH: ${.CURDIR}/../../net80211
 
@@ -11,7 +11,8 @@
 	ieee80211_scan_sta.c ieee80211_radiotap.c ieee80211_ratectl.c \
 	ieee80211_ratectl_none.c ieee80211_regdomain.c \
 	ieee80211_ht.c ieee80211_hwmp.c ieee80211_adhoc.c ieee80211_hostap.c \
-	ieee80211_monitor.c ieee80211_sta.c ieee80211_wds.c ieee80211_ddb.c
+	ieee80211_monitor.c ieee80211_sta.c ieee80211_wds.c ieee80211_ddb.c \
+	ieee80211_tdma.c
 SRCS+=	bus_if.h device_if.h opt_inet.h opt_inet6.h opt_ipx.h opt_wlan.h \
 	opt_ddb.h
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/net/bpf_buffer.c
--- a/head/sys/net/bpf_buffer.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/net/bpf_buffer.c	Mon Jan 16 14:38:30 2012 +0200
@@ -2,7 +2,7 @@
  * Copyright (c) 2007 Seccuris Inc.
  * All rights reserved.
  *
- * This sofware was developed by Robert N. M. Watson under contract to
+ * This software was developed by Robert N. M. Watson under contract to
  * Seccuris Inc.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/net/bpf_buffer.c 230108 2012-01-14 17:07:52Z eadler $");
 
 #include "opt_bpf.h"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/net/bpf_buffer.h
--- a/head/sys/net/bpf_buffer.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/net/bpf_buffer.h	Mon Jan 16 14:38:30 2012 +0200
@@ -2,7 +2,7 @@
  * Copyright (c) 2007 Seccuris Inc.
  * All rights reserved.
  *
- * This sofware was developed by Robert N. M. Watson under contract to
+ * This software was developed by Robert N. M. Watson under contract to
  * Seccuris Inc.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/net/bpf_buffer.h 230108 2012-01-14 17:07:52Z eadler $
  */
 
 #ifndef _NET_BPF_BUFFER_H_
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/net/bpf_zerocopy.c
--- a/head/sys/net/bpf_zerocopy.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/net/bpf_zerocopy.c	Mon Jan 16 14:38:30 2012 +0200
@@ -2,7 +2,7 @@
  * Copyright (c) 2007 Seccuris Inc.
  * All rights reserved.
  *
- * This sofware was developed by Robert N. M. Watson under contract to
+ * This software was developed by Robert N. M. Watson under contract to
  * Seccuris Inc.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/net/bpf_zerocopy.c 230108 2012-01-14 17:07:52Z eadler $");
 
 #include "opt_bpf.h"
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/net/bpf_zerocopy.h
--- a/head/sys/net/bpf_zerocopy.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/net/bpf_zerocopy.h	Mon Jan 16 14:38:30 2012 +0200
@@ -2,7 +2,7 @@
  * Copyright (c) 2007 Seccuris Inc.
  * All rights reserved.
  *
- * This sofware was developed by Robert N. M. Watson under contract to
+ * This software was developed by Robert N. M. Watson under contract to
  * Seccuris Inc.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/net/bpf_zerocopy.h 230108 2012-01-14 17:07:52Z eadler $
  */
 
 #ifndef _NET_BPF_ZEROCOPY_H_
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/net/if_vlan.c
--- a/head/sys/net/if_vlan.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/net/if_vlan.c	Mon Jan 16 14:38:30 2012 +0200
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/net/if_vlan.c 229587 2012-01-05 11:42:34Z rwatson $");
+__FBSDID("$FreeBSD: head/sys/net/if_vlan.c 230026 2012-01-12 18:39:37Z rwatson $");
 
 #include "opt_vlan.h"
 
@@ -114,7 +114,7 @@
 #endif
 };
 #define	ifv_proto	ifv_mib.ifvm_proto
-#define	ifv_tag		ifv_mib.ifvm_tag
+#define	ifv_vid		ifv_mib.ifvm_tag
 #define	ifv_encaplen	ifv_mib.ifvm_encaplen
 #define	ifv_mtufudge	ifv_mib.ifvm_mtufudge
 #define	ifv_mintu	ifv_mib.ifvm_mintu
@@ -178,7 +178,7 @@
 static	int vlan_remhash(struct ifvlantrunk *trunk, struct ifvlan *ifv);
 static	void vlan_growhash(struct ifvlantrunk *trunk, int howmuch);
 static __inline struct ifvlan * vlan_gethash(struct ifvlantrunk *trunk,
-	uint16_t tag);
+	uint16_t vid);
 #endif
 static	void trunk_destroy(struct ifvlantrunk *trunk);
 
@@ -198,7 +198,7 @@
 static	void vlan_capabilities(struct ifvlan *ifv);
 static	void vlan_trunk_capabilities(struct ifnet *ifp);
 
-static	struct ifnet *vlan_clone_match_ethertag(struct if_clone *,
+static	struct ifnet *vlan_clone_match_ethervid(struct if_clone *,
     const char *, int *);
 static	int vlan_clone_match(struct if_clone *, const char *);
 static	int vlan_clone_create(struct if_clone *, char *, size_t, caddr_t);
@@ -266,9 +266,9 @@
 	KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__));
 
 	b = 1 << trunk->hwidth;
-	i = HASH(ifv->ifv_tag, trunk->hmask);
+	i = HASH(ifv->ifv_vid, trunk->hmask);
 	LIST_FOREACH(ifv2, &trunk->hash[i], ifv_list)
-		if (ifv->ifv_tag == ifv2->ifv_tag)
+		if (ifv->ifv_vid == ifv2->ifv_vid)
 			return (EEXIST);
 
 	/*
@@ -278,7 +278,7 @@
 	 */
 	if (trunk->refcnt > (b * b) / 2) {
 		vlan_growhash(trunk, 1);
-		i = HASH(ifv->ifv_tag, trunk->hmask);
+		i = HASH(ifv->ifv_vid, trunk->hmask);
 	}
 	LIST_INSERT_HEAD(&trunk->hash[i], ifv, ifv_list);
 	trunk->refcnt++;
@@ -296,7 +296,7 @@
 	KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__));
 	
 	b = 1 << trunk->hwidth;
-	i = HASH(ifv->ifv_tag, trunk->hmask);
+	i = HASH(ifv->ifv_vid, trunk->hmask);
 	LIST_FOREACH(ifv2, &trunk->hash[i], ifv_list)
 		if (ifv2 == ifv) {
 			trunk->refcnt--;
@@ -348,7 +348,7 @@
 	for (i = 0; i < n; i++)
 		while ((ifv = LIST_FIRST(&trunk->hash[i])) != NULL) {
 			LIST_REMOVE(ifv, ifv_list);
-			j = HASH(ifv->ifv_tag, n2 - 1);
+			j = HASH(ifv->ifv_vid, n2 - 1);
 			LIST_INSERT_HEAD(&hash2[j], ifv, ifv_list);
 		}
 	free(trunk->hash, M_VLAN);
@@ -362,14 +362,14 @@
 }
 
 static __inline struct ifvlan *
-vlan_gethash(struct ifvlantrunk *trunk, uint16_t tag)
+vlan_gethash(struct ifvlantrunk *trunk, uint16_t vid)
 {
 	struct ifvlan *ifv;
 
 	TRUNK_LOCK_RASSERT(trunk);
 
-	LIST_FOREACH(ifv, &trunk->hash[HASH(tag, trunk->hmask)], ifv_list)
-		if (ifv->ifv_tag == tag)
+	LIST_FOREACH(ifv, &trunk->hash[HASH(vid, trunk->hmask)], ifv_list)
+		if (ifv->ifv_vid == vid)
 			return (ifv);
 	return (NULL);
 }
@@ -393,19 +393,19 @@
 #else
 
 static __inline struct ifvlan *
-vlan_gethash(struct ifvlantrunk *trunk, uint16_t tag)
+vlan_gethash(struct ifvlantrunk *trunk, uint16_t vid)
 {
 
-	return trunk->vlans[tag];
+	return trunk->vlans[vid];
 }
 
 static __inline int
 vlan_inshash(struct ifvlantrunk *trunk, struct ifvlan *ifv)
 {
 
-	if (trunk->vlans[ifv->ifv_tag] != NULL)
+	if (trunk->vlans[ifv->ifv_vid] != NULL)
 		return EEXIST;
-	trunk->vlans[ifv->ifv_tag] = ifv;
+	trunk->vlans[ifv->ifv_vid] = ifv;
 	trunk->refcnt++;
 
 	return (0);
@@ -415,7 +415,7 @@
 vlan_remhash(struct ifvlantrunk *trunk, struct ifvlan *ifv)
 {
 
-	trunk->vlans[ifv->ifv_tag] = NULL;
+	trunk->vlans[ifv->ifv_vid] = NULL;
 	trunk->refcnt--;
 
 	return (0);
@@ -617,17 +617,21 @@
 }
 
 /*
- * Return the 16bit vlan tag for this interface.
+ * Return the 12-bit VLAN VID for this interface, for use by external
+ * components such as Infiniband.
+ *
+ * XXXRW: Note that the function name here is historical; it should be named
+ * vlan_vid().
  */
 static int
-vlan_tag(struct ifnet *ifp, uint16_t *tagp)
+vlan_tag(struct ifnet *ifp, uint16_t *vidp)
 {
 	struct ifvlan *ifv;
 
 	if (ifp->if_type != IFT_L2VLAN)
 		return (EINVAL);
 	ifv = ifp->if_softc;
-	*tagp = ifv->ifv_tag;
+	*vidp = ifv->ifv_vid;
 	return (0);
 }
 
@@ -663,10 +667,10 @@
 }
 
 /*
- * Return the vlan device present at the specific tag.
+ * Return the vlan device present at the specific VID.
  */
 static struct ifnet *
-vlan_devat(struct ifnet *ifp, uint16_t tag)
+vlan_devat(struct ifnet *ifp, uint16_t vid)
 {
 	struct ifvlantrunk *trunk;
 	struct ifvlan *ifv;
@@ -676,7 +680,7 @@
 		return (NULL);
 	ifp = NULL;
 	TRUNK_RLOCK(trunk);
-	ifv = vlan_gethash(trunk, tag);
+	ifv = vlan_gethash(trunk, vid);
 	if (ifv)
 		ifp = ifv->ifv_ifp;
 	TRUNK_RUNLOCK(trunk);
@@ -786,11 +790,11 @@
 #endif
 
 static struct ifnet *
-vlan_clone_match_ethertag(struct if_clone *ifc, const char *name, int *tag)
+vlan_clone_match_ethervid(struct if_clone *ifc, const char *name, int *vidp)
 {
 	const char *cp;
 	struct ifnet *ifp;
-	int t;
+	int vid;
 
 	/* Check for <etherif>.<vlan> style interface names. */
 	IFNET_RLOCK_NOSLEEP();
@@ -809,13 +813,13 @@
 			continue;
 		if (*cp == '\0')
 			continue;
-		t = 0;
+		vid = 0;
 		for(; *cp >= '0' && *cp <= '9'; cp++)
-			t = (t * 10) + (*cp - '0');
+			vid = (vid * 10) + (*cp - '0');
 		if (*cp != '\0')
 			continue;
-		if (tag != NULL)
-			*tag = t;
+		if (vidp != NULL)
+			*vidp = vid;
 		break;
 	}
 	IFNET_RUNLOCK_NOSLEEP();
@@ -828,7 +832,7 @@
 {
 	const char *cp;
 
-	if (vlan_clone_match_ethertag(ifc, name, NULL) != NULL)
+	if (vlan_clone_match_ethervid(ifc, name, NULL) != NULL)
 		return (1);
 
 	if (strncmp(VLANNAME, name, strlen(VLANNAME)) != 0)
@@ -848,7 +852,7 @@
 	int wildcard;
 	int unit;
 	int error;
-	int tag;
+	int vid;
 	int ethertag;
 	struct ifvlan *ifv;
 	struct ifnet *ifp;
@@ -866,6 +870,9 @@
 	 *   must be configured separately.
 	 * The first technique is preferred; the latter two are
 	 * supported for backwards compatibilty.
+	 *
+	 * XXXRW: Note historic use of the word "tag" here.  New ioctls may be
+	 * called for.
 	 */
 	if (params) {
 		error = copyin(params, &vlr, sizeof(vlr));
@@ -875,7 +882,7 @@
 		if (p == NULL)
 			return ENXIO;
 		/*
-		 * Don't let the caller set up a VLAN tag with
+		 * Don't let the caller set up a VLAN VID with
 		 * anything except VLID bits.
 		 */
 		if (vlr.vlr_tag & ~EVL_VLID_MASK)
@@ -885,18 +892,18 @@
 			return (error);
 
 		ethertag = 1;
-		tag = vlr.vlr_tag;
+		vid = vlr.vlr_tag;
 		wildcard = (unit < 0);
-	} else if ((p = vlan_clone_match_ethertag(ifc, name, &tag)) != NULL) {
+	} else if ((p = vlan_clone_match_ethervid(ifc, name, &vid)) != NULL) {
 		ethertag = 1;
 		unit = -1;
 		wildcard = 0;
 
 		/*
-		 * Don't let the caller set up a VLAN tag with
+		 * Don't let the caller set up a VLAN VID with
 		 * anything except VLID bits.
 		 */
-		if (tag & ~EVL_VLID_MASK)
+		if (vid & ~EVL_VLID_MASK)
 			return (EINVAL);
 	} else {
 		ethertag = 0;
@@ -958,7 +965,7 @@
 	sdl->sdl_type = IFT_L2VLAN;
 
 	if (ethertag) {
-		error = vlan_config(ifv, p, tag);
+		error = vlan_config(ifv, p, vid);
 		if (error != 0) {
 			/*
 			 * Since we've partialy failed, we need to back
@@ -1068,10 +1075,10 @@
 	 * packet tag that holds it.
 	 */
 	if (p->if_capenable & IFCAP_VLAN_HWTAGGING) {
-		m->m_pkthdr.ether_vtag = ifv->ifv_tag;
+		m->m_pkthdr.ether_vtag = ifv->ifv_vid;
 		m->m_flags |= M_VLANTAG;
 	} else {
-		m = ether_vlanencap(m, ifv->ifv_tag);
+		m = ether_vlanencap(m, ifv->ifv_vid);
 		if (m == NULL) {
 			if_printf(ifp, "unable to prepend VLAN header\n");
 			ifp->if_oerrors++;
@@ -1105,7 +1112,7 @@
 {
 	struct ifvlantrunk *trunk = ifp->if_vlantrunk;
 	struct ifvlan *ifv;
-	uint16_t tag;
+	uint16_t vid;
 
 	KASSERT(trunk != NULL, ("%s: no trunk", __func__));
 
@@ -1114,7 +1121,7 @@
 		 * Packet is tagged, but m contains a normal
 		 * Ethernet frame; the tag is stored out-of-band.
 		 */
-		tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
+		vid = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
 		m->m_flags &= ~M_VLANTAG;
 	} else {
 		struct ether_vlan_header *evl;
@@ -1130,7 +1137,7 @@
 				return;
 			}
 			evl = mtod(m, struct ether_vlan_header *);
-			tag = EVL_VLANOFTAG(ntohs(evl->evl_tag));
+			vid = EVL_VLANOFTAG(ntohs(evl->evl_tag));
 
 			/*
 			 * Remove the 802.1q header by copying the Ethernet
@@ -1155,7 +1162,7 @@
 	}
 
 	TRUNK_RLOCK(trunk);
-	ifv = vlan_gethash(trunk, tag);
+	ifv = vlan_gethash(trunk, vid);
 	if (ifv == NULL || !UP_AND_RUNNING(ifv->ifv_ifp)) {
 		TRUNK_RUNLOCK(trunk);
 		m_freem(m);
@@ -1172,14 +1179,14 @@
 }
 
 static int
-vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t tag)
+vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid)
 {
 	struct ifvlantrunk *trunk;
 	struct ifnet *ifp;
 	int error = 0;
 
 	/* VID numbers 0x0 and 0xFFF are reserved */
-	if (tag == 0 || tag == 0xFFF)
+	if (vid == 0 || vid == 0xFFF)
 		return (EINVAL);
 	if (p->if_type != IFT_ETHER &&
 	    (p->if_capenable & IFCAP_VLAN_HWTAGGING) == 0)
@@ -1211,7 +1218,7 @@
 		TRUNK_LOCK(trunk);
 	}
 
-	ifv->ifv_tag = tag;	/* must set this before vlan_inshash() */
+	ifv->ifv_vid = vid;	/* must set this before vlan_inshash() */
 	error = vlan_inshash(trunk, ifv);
 	if (error)
 		goto done;
@@ -1289,7 +1296,7 @@
 done:
 	TRUNK_UNLOCK(trunk);
 	if (error == 0)
-		EVENTHANDLER_INVOKE(vlan_config, p, ifv->ifv_tag);
+		EVENTHANDLER_INVOKE(vlan_config, p, ifv->ifv_vid);
 	VLAN_UNLOCK();
 
 	return (error);
@@ -1377,7 +1384,7 @@
 	 * to cleanup anyway.
 	 */
 	if (parent != NULL)
-		EVENTHANDLER_INVOKE(vlan_unconfig, parent, ifv->ifv_tag);
+		EVENTHANDLER_INVOKE(vlan_unconfig, parent, ifv->ifv_vid);
 }
 
 /* Handle a reference counted flag that should be set on the parent as well */
@@ -1622,7 +1629,7 @@
 			break;
 		}
 		/*
-		 * Don't let the caller set up a VLAN tag with
+		 * Don't let the caller set up a VLAN VID with
 		 * anything except VLID bits.
 		 */
 		if (vlr.vlr_tag & ~EVL_VLID_MASK) {
@@ -1649,7 +1656,7 @@
 		if (TRUNK(ifv) != NULL) {
 			strlcpy(vlr.vlr_parent, PARENT(ifv)->if_xname,
 			    sizeof(vlr.vlr_parent));
-			vlr.vlr_tag = ifv->ifv_tag;
+			vlr.vlr_tag = ifv->ifv_vid;
 		}
 		VLAN_UNLOCK();
 		error = copyout(&vlr, ifr->ifr_data, sizeof(vlr));
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/net/if_vlan_var.h
--- a/head/sys/net/if_vlan_var.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/net/if_vlan_var.h	Mon Jan 16 14:38:30 2012 +0200
@@ -26,7 +26,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: head/sys/net/if_vlan_var.h 230026 2012-01-12 18:39:37Z rwatson $
  */
 
 #ifndef _NET_IF_VLAN_VAR_H_
@@ -108,7 +108,7 @@
  * received VLAN tag (containing both vlan and priority information)
  * into the ether_vtag mbuf packet header field:
  * 
- *	m->m_pkthdr.ether_vtag = vlan_id;	// ntohs()?
+ *	m->m_pkthdr.ether_vtag = vtag;		// ntohs()?
  *	m->m_flags |= M_VLANTAG;
  *
  * to mark the packet m with the specified VLAN tag.
@@ -133,15 +133,15 @@
 
 #define	VLAN_TRUNKDEV(_ifp)					\
 	(_ifp)->if_type == IFT_L2VLAN ? (*vlan_trunkdev_p)((_ifp)) : NULL
-#define	VLAN_TAG(_ifp, _tag)					\
-	(_ifp)->if_type == IFT_L2VLAN ? (*vlan_tag_p)((_ifp), (_tag)) : EINVAL
+#define	VLAN_TAG(_ifp, _vid)					\
+	(_ifp)->if_type == IFT_L2VLAN ? (*vlan_tag_p)((_ifp), (_vid)) : EINVAL
 #define	VLAN_COOKIE(_ifp)					\
 	(_ifp)->if_type == IFT_L2VLAN ? (*vlan_cookie_p)((_ifp)) : NULL
 #define	VLAN_SETCOOKIE(_ifp, _cookie)				\
 	(_ifp)->if_type == IFT_L2VLAN ?				\
 	    (*vlan_setcookie_p)((_ifp), (_cookie)) : EINVAL
-#define	VLAN_DEVAT(_ifp, _tag)					\
-	(_ifp)->if_vlantrunk != NULL ? (*vlan_devat_p)((_ifp), (_tag)) : NULL
+#define	VLAN_DEVAT(_ifp, _vid)					\
+	(_ifp)->if_vlantrunk != NULL ? (*vlan_devat_p)((_ifp), (_vid)) : NULL
 
 extern	void (*vlan_trunk_cap_p)(struct ifnet *);
 extern	struct ifnet *(*vlan_trunkdev_p)(struct ifnet *);
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/net80211/ieee80211_tdma.c
--- a/head/sys/net80211/ieee80211_tdma.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/net80211/ieee80211_tdma.c	Mon Jan 16 14:38:30 2012 +0200
@@ -26,7 +26,7 @@
 
 #include <sys/cdefs.h>
 #ifdef __FreeBSD__
-__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_tdma.c 226296 2011-10-12 10:19:55Z adrian $");
+__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_tdma.c 230153 2012-01-15 19:45:23Z adrian $");
 #endif
 
 /*
@@ -36,6 +36,8 @@
 #include "opt_tdma.h"
 #include "opt_wlan.h"
 
+#ifdef	IEEE80211_SUPPORT_TDMA
+
 #include <sys/param.h>
 #include <sys/systm.h> 
 #include <sys/mbuf.h>   
@@ -820,3 +822,5 @@
 	return ERESTART;
 }
 IEEE80211_IOCTL_SET(tdma, tdma_ioctl_set80211);
+
+#endif	/* IEEE80211_SUPPORT_TDMA */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/netinet/in.c
--- a/head/sys/netinet/in.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/netinet/in.c	Mon Jan 16 14:38:30 2012 +0200
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/in.c 229621 2012-01-05 19:00:36Z jhb $");
+__FBSDID("$FreeBSD: head/sys/netinet/in.c 230207 2012-01-16 09:53:24Z glebius $");
 
 #include "opt_mpath.h"
 
@@ -73,7 +73,7 @@
 
 static void	in_socktrim(struct sockaddr_in *);
 static int	in_ifinit(struct ifnet *, struct in_ifaddr *,
-		    struct sockaddr_in *, int, int, int);
+		    struct sockaddr_in *, int, int);
 static void	in_purgemaddrs(struct ifnet *);
 
 static VNET_DEFINE(int, nosameprefix);
@@ -220,7 +220,6 @@
 	struct in_addr dst;
 	struct in_ifinfo *ii;
 	struct in_aliasreq *ifra = (struct in_aliasreq *)data;
-	struct sockaddr_in oldaddr;
 	int error, hostIsNew, iaIsNew, maskIsNew;
 	int iaIsFirst;
 	u_long ocmd = cmd;
@@ -278,10 +277,8 @@
 	case SIOCSIFBRDADDR:
 	case SIOCSIFDSTADDR:
 	case SIOCSIFNETMASK:
-		if (ifr->ifr_addr.sa_family != AF_INET ||
-		    ifr->ifr_addr.sa_len != sizeof(struct sockaddr_in))
-			return (EINVAL);
-		break;
+		/* We no longer support that old commands. */
+		return (EINVAL);
 
 	case SIOCALIFADDR:
 		if (td != NULL) {
@@ -322,10 +319,6 @@
 	 */
 	switch (cmd) {
 	case SIOCAIFADDR:
-	case SIOCSIFADDR:
-	case SIOCSIFBRDADDR:
-	case SIOCSIFNETMASK:
-	case SIOCSIFDSTADDR:
 		if (td != NULL) {
 			error = priv_check(td, PRIV_NET_ADDIFADDR);
 			if (error)
@@ -413,10 +406,6 @@
 			error = EADDRNOTAVAIL;
 			goto out;
 		}
-		/* FALLTHROUGH */
-	case SIOCSIFADDR:
-	case SIOCSIFNETMASK:
-	case SIOCSIFDSTADDR:
 		if (ia == NULL) {
 			ia = (struct in_ifaddr *)
 				malloc(sizeof *ia, M_IFADDR, M_NOWAIT |
@@ -452,7 +441,6 @@
 		}
 		break;
 
-	case SIOCSIFBRDADDR:
 	case SIOCGIFADDR:
 	case SIOCGIFNETMASK:
 	case SIOCGIFDSTADDR:
@@ -493,61 +481,6 @@
 		*((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask;
 		goto out;
 
-	case SIOCSIFDSTADDR:
-		if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
-			error = EINVAL;
-			goto out;
-		}
-		oldaddr = ia->ia_dstaddr;
-		ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr;
-		if (ifp->if_ioctl != NULL) {
-			error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR,
-			    (caddr_t)ia);
-			if (error) {
-				ia->ia_dstaddr = oldaddr;
-				goto out;
-			}
-		}
-		if (ia->ia_flags & IFA_ROUTE) {
-			ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
-			rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
-			ia->ia_ifa.ifa_dstaddr =
-					(struct sockaddr *)&ia->ia_dstaddr;
-			rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
-		}
-		goto out;
-
-	case SIOCSIFBRDADDR:
-		if ((ifp->if_flags & IFF_BROADCAST) == 0) {
-			error = EINVAL;
-			goto out;
-		}
-		ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr;
-		goto out;
-
-	case SIOCSIFADDR:
-		error = in_ifinit(ifp, ia,
-		    (struct sockaddr_in *) &ifr->ifr_addr, 1, 0, 0);
-		if (error != 0 && iaIsNew)
-			break;
-		if (error == 0) {
-			ii = ((struct in_ifinfo *)ifp->if_afdata[AF_INET]);
-			if (iaIsFirst &&
-			    (ifp->if_flags & IFF_MULTICAST) != 0) {
-				error = in_joingroup(ifp, &allhosts_addr,
-				    NULL, &ii->ii_allhosts);
-			}
-			EVENTHANDLER_INVOKE(ifaddr_event, ifp);
-		}
-		error = 0;
-		goto out;
-
-	case SIOCSIFNETMASK:
-		ia->ia_sockmask.sin_addr = ((struct sockaddr_in *)
-		    &ifr->ifr_addr)->sin_addr;
-		ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr);
-		goto out;
-
 	case SIOCAIFADDR:
 		maskIsNew = 0;
 		hostIsNew = 1;
@@ -579,8 +512,8 @@
 			maskIsNew  = 1; /* We lie; but the effect's the same */
 		}
 		if (hostIsNew || maskIsNew)
-			error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0,
-			    maskIsNew, (ocmd == cmd ? ifra->ifra_vhid : 0));
+			error = in_ifinit(ifp, ia, &ifra->ifra_addr, maskIsNew,
+			    (ocmd == cmd ? ifra->ifra_vhid : 0));
 		if (error != 0 && iaIsNew)
 			break;
 
@@ -863,14 +796,11 @@
  */
 static int
 in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
-    int scrub, int masksupplied, int vhid)
+    int masksupplied, int vhid)
 {
 	register u_long i = ntohl(sin->sin_addr.s_addr);
 	int flags = RTF_UP, error = 0;
 
-	if (scrub)
-		in_scrubprefix(ia, LLE_STATIC);
-
 	IN_IFADDR_WLOCK();
 	if (ia->ia_addr.sin_family == AF_INET)
 		LIST_REMOVE(ia, ia_hash);
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/netinet/sctp_output.c
--- a/head/sys/netinet/sctp_output.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/netinet/sctp_output.c	Mon Jan 16 14:38:30 2012 +0200
@@ -33,7 +33,7 @@
 /* $KAME: sctp_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $	 */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 228966 2011-12-29 18:25:18Z jhb $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 230136 2012-01-15 13:35:55Z tuexen $");
 
 #include <netinet/sctp_os.h>
 #include <sys/proc.h>
@@ -12839,9 +12839,9 @@
 			goto out_unlocked;
 		}
 	}
-	if ((SCTP_SO_IS_NBIO(so)
+	if (SCTP_SO_IS_NBIO(so)
 	    || (flags & MSG_NBIO)
-	    )) {
+	    ) {
 		non_blocking = 1;
 	}
 	/* would we block? */
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/netinet/sctp_usrreq.c
--- a/head/sys/netinet/sctp_usrreq.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/netinet/sctp_usrreq.c	Mon Jan 16 14:38:30 2012 +0200
@@ -33,7 +33,7 @@
 /* $KAME: sctp_usrreq.c,v 1.48 2005/03/07 23:26:08 itojun Exp $	 */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 228907 2011-12-27 10:16:24Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 230104 2012-01-14 09:10:20Z tuexen $");
 #include <netinet/sctp_os.h>
 #include <sys/proc.h>
 #include <netinet/sctp_pcb.h>
@@ -3019,7 +3019,7 @@
 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
 				error = EINVAL;
 			} else {
-				SCTP_INP_RUNLOCK(inp);
+				SCTP_INP_RLOCK(inp);
 				onoff = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO);
 				SCTP_INP_RUNLOCK(inp);
 			}
@@ -3038,7 +3038,7 @@
 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
 				error = EINVAL;
 			} else {
-				SCTP_INP_RUNLOCK(inp);
+				SCTP_INP_RLOCK(inp);
 				onoff = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO);
 				SCTP_INP_RUNLOCK(inp);
 			}
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/netinet/sctputil.c
--- a/head/sys/netinet/sctputil.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/netinet/sctputil.c	Mon Jan 16 14:38:30 2012 +0200
@@ -33,7 +33,7 @@
 /* $KAME: sctputil.c,v 1.37 2005/03/07 23:26:09 itojun Exp $	 */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 229805 2012-01-08 09:56:24Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 230136 2012-01-15 13:35:55Z tuexen $");
 
 #include <netinet/sctp_os.h>
 #include <netinet/sctp_pcb.h>
@@ -6373,7 +6373,7 @@
 		return;
 	}
 	addr_touse = sa;
-#if defined(INET6) && !defined(__Userspace__)	/* TODO port in6_sin6_2_sin */
+#if defined(INET6)
 	if (sa->sa_family == AF_INET6) {
 		struct sockaddr_in6 *sin6;
 
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/netinet6/sctp6_var.h
--- a/head/sys/netinet6/sctp6_var.h	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/netinet6/sctp6_var.h	Mon Jan 16 14:38:30 2012 +0200
@@ -35,9 +35,8 @@
 #define _NETINET6_SCTP6_VAR_H_
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_var.h 228653 2011-12-17 19:21:40Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_var.h 230138 2012-01-15 14:03:05Z tuexen $");
 
-/* TODO __Userspace__ IPv6 stuff... */
 #if defined(_KERNEL)
 
 SYSCTL_DECL(_net_inet6_sctp6);
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/ofed/drivers/infiniband/core/local_sa.c
--- a/head/sys/ofed/drivers/infiniband/core/local_sa.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/ofed/drivers/infiniband/core/local_sa.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 Intel Corporation.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/ofed/drivers/infiniband/core/notice.c
--- a/head/sys/ofed/drivers/infiniband/core/notice.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/ofed/drivers/infiniband/core/notice.c	Mon Jan 16 14:38:30 2012 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2006 Intel Corporation.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/powerpc/aim/machdep.c
--- a/head/sys/powerpc/aim/machdep.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/powerpc/aim/machdep.c	Mon Jan 16 14:38:30 2012 +0200
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/powerpc/aim/machdep.c 228869 2011-12-24 19:34:52Z jhibbits $");
+__FBSDID("$FreeBSD: head/sys/powerpc/aim/machdep.c 230123 2012-01-15 00:08:14Z nwhitehorn $");
 
 #include "opt_compat.h"
 #include "opt_ddb.h"
@@ -238,6 +238,7 @@
 extern void	*rstcode, *rstsize;
 #endif
 extern void	*trapcode, *trapsize;
+extern void	*slbtrap, *slbtrapsize;
 extern void	*alitrap, *alisize;
 extern void	*dsitrap, *dsisize;
 extern void	*decrint, *decrsize;
@@ -490,8 +491,8 @@
 	bcopy(&dsitrap,  (void *)(EXC_DSI + trap_offset),  (size_t)&dsisize);
 	bcopy(generictrap, (void *)EXC_ISI,  (size_t)&trapsize);
 	#ifdef __powerpc64__
-	bcopy(generictrap, (void *)EXC_DSE,  (size_t)&trapsize);
-	bcopy(generictrap, (void *)EXC_ISE,  (size_t)&trapsize);
+	bcopy(&slbtrap, (void *)EXC_DSE,  (size_t)&slbtrapsize);
+	bcopy(&slbtrap, (void *)EXC_ISE,  (size_t)&slbtrapsize);
 	#endif
 	bcopy(generictrap, (void *)EXC_EXI,  (size_t)&trapsize);
 	bcopy(generictrap, (void *)EXC_FPU,  (size_t)&trapsize);
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/powerpc/aim/slb.c
--- a/head/sys/powerpc/aim/slb.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/powerpc/aim/slb.c	Mon Jan 16 14:38:30 2012 +0200
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/sys/powerpc/aim/slb.c 227568 2011-11-16 16:46:09Z alc $
+ * $FreeBSD: head/sys/powerpc/aim/slb.c 230123 2012-01-15 00:08:14Z nwhitehorn $
  */
 
 #include <sys/param.h>
@@ -409,15 +409,11 @@
 
 /* Lock entries mapping kernel text and stacks */
 
-#define SLB_SPILLABLE(slbe) \
-	(((slbe & SLBE_ESID_MASK) < VM_MIN_KERNEL_ADDRESS && \
-	    (slbe & SLBE_ESID_MASK) > 16*SEGMENT_LENGTH) || \
-	    (slbe & SLBE_ESID_MASK) > VM_MAX_KERNEL_ADDRESS)
 void
 slb_insert_kernel(uint64_t slbe, uint64_t slbv)
 {
 	struct slb *slbcache;
-	int i, j;
+	int i;
 
 	/* We don't want to be preempted while modifying the kernel map */
 	critical_enter();
@@ -437,15 +433,9 @@
 			slbcache[USER_SLB_SLOT].slbe = 1;
 	}
 
-	for (i = mftb() % n_slbs, j = 0; j < n_slbs; j++, i = (i+1) % n_slbs) {
-		if (i == USER_SLB_SLOT)
-			continue;
-
-		if (SLB_SPILLABLE(slbcache[i].slbe))
-			break;
-	}
-
-	KASSERT(j < n_slbs, ("All kernel SLB slots locked!"));
+	i = mftb() % n_slbs;
+	if (i == USER_SLB_SLOT)
+			i = (i+1) % n_slbs;
 
 fillkernslb:
 	KASSERT(i != USER_SLB_SLOT,
diff -r b112b8e55492 -r 484dfe564ae6 head/sys/powerpc/aim/trap.c
--- a/head/sys/powerpc/aim/trap.c	Sun Jan 15 00:25:08 2012 +0200
+++ b/head/sys/powerpc/aim/trap.c	Mon Jan 16 14:38:30 2012 +0200
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/powerpc/aim/trap.c 228869 2011-12-24 19:34:52Z jhibbits $");
+__FBSDID("$FreeBSD: head/sys/powerpc/aim/trap.c 230123 2012-01-15 00:08:14Z nwhitehorn $");
 
 #include "opt_hwpmc_hooks.h"
 
@@ -88,7 +88,9 @@
 static void	syscall(struct trapframe *frame);
 
 #ifdef __powerpc64__
-static int	handle_slb_spill(pmap_t pm, vm_offset_t addr);
+       void	handle_kernel_slb_spill(int, register_t, register_t);
+static int	handle_user_slb_spill(pmap_t pm, vm_offset_t addr);
+extern int	n_slbs;
 #endif
 
 int	setfault(faultbuf);		/* defined in locore.S */
@@ -191,7 +193,7 @@
 #ifdef __powerpc64__
 		case EXC_ISE:
 		case EXC_DSE:
-			if (handle_slb_spill(&p->p_vmspace->vm_pmap,
+			if (handle_user_slb_spill(&p->p_vmspace->vm_pmap,
 			    (type == EXC_ISE) ? frame->srr0 :
 			    frame->cpu.aim.dar) != 0)
 				sig = SIGSEGV;
@@ -259,27 +261,20 @@
 		KASSERT(cold || td->td_ucred != NULL,
 		    ("kernel trap doesn't have ucred"));
 		switch (type) {
+#ifdef __powerpc64__
+		case EXC_DSE:
+			if ((frame->cpu.aim.dar & SEGMENT_MASK) == USER_ADDR) {
+				__asm __volatile ("slbmte %0, %1" ::
+					"r"(td->td_pcb->pcb_cpu.aim.usr_vsid),
+					"r"(USER_SLB_SLBE));
+				return;
+			}
+			break;
+#endif
 		case EXC_DSI:
 			if (trap_pfault(frame, 0) == 0)
  				return;
 			break;
-#ifdef __powerpc64__
-		case EXC_DSE:
-			if ((frame->cpu.aim.dar & SEGMENT_MASK) == USER_ADDR) {
-				__asm __volatile ("slbmte %0, %1" ::
-				     "r"(td->td_pcb->pcb_cpu.aim.usr_vsid),
-				     "r"(USER_SLB_SLBE));
-				return;
-			}
-
-			/* FALLTHROUGH */
-		case EXC_ISE:
-			if (handle_slb_spill(kernel_pmap,
-			    (type == EXC_ISE) ? frame->srr0 :
-			    frame->cpu.aim.dar) != 0)
-				panic("Fault handling kernel SLB miss");
-			return;
-#endif
 		case EXC_MCHK:
 			if (handle_onfault(frame))
  				return;
@@ -326,8 +321,7 @@
 	printf("%s %s trap:\n", isfatal ? "fatal" : "handled",
 	    user ? "user" : "kernel");
 	printf("\n");
-	printf("   exception       = 0x%x (%s)\n", vector >> 8,
-	    trapname(vector));
+	printf("   exception       = 0x%x (%s)\n", vector, trapname(vector));
 	switch (vector) {
 	case EXC_DSE:
 	case EXC_DSI:
@@ -486,8 +480,54 @@
 }
 
 #ifdef __powerpc64__
+/* Handle kern