Merge branch 'topic/misc' into for-linus
authorTakashi Iwai <tiwai@suse.de>
Sun, 22 May 2011 08:01:29 +0000 (10:01 +0200)
committerTakashi Iwai <tiwai@suse.de>
Sun, 22 May 2011 08:01:29 +0000 (10:01 +0200)
14 files changed:
1  2 
MAINTAINERS
include/sound/control.h
sound/pci/Kconfig
sound/pci/asihpi/asihpi.c
sound/pci/asihpi/hpi6000.c
sound/pci/asihpi/hpi6205.c
sound/pci/asihpi/hpi_internal.h
sound/pci/asihpi/hpimsgx.c
sound/pci/au88x0/au88x0_pcm.c
sound/pci/intel8x0m.c
sound/usb/6fire/firmware.c
sound/usb/format.c
sound/usb/mixer.c
sound/usb/quirks.c

diff --combined MAINTAINERS
@@@ -151,7 -151,6 +151,7 @@@ S: Maintaine
  F:    drivers/net/hamradio/6pack.c
  
  8169 10/100/1000 GIGABIT ETHERNET DRIVER
 +M:    Realtek linux nic maintainers <nic_swsd@realtek.com>
  M:    Francois Romieu <romieu@fr.zoreil.com>
  L:    netdev@vger.kernel.org
  S:    Maintained
@@@ -185,9 -184,10 +185,9 @@@ F:        Documentation/filesystems/9p.tx
  F:    fs/9p/
  
  A2232 SERIAL BOARD DRIVER
 -M:    Enver Haase <A2232@gmx.net>
  L:    linux-m68k@lists.linux-m68k.org
 -S:    Maintained
 -F:    drivers/char/ser_a2232*
 +S:    Orphan
 +F:    drivers/staging/generic_serial/ser_a2232*
  
  AACRAID SCSI RAID DRIVER
  M:    Adaptec OEM Raid Solutions <aacraid@adaptec.com>
@@@ -877,13 -877,6 +877,13 @@@ F:       arch/arm/mach-mv78xx0
  F:    arch/arm/mach-orion5x/
  F:    arch/arm/plat-orion/
  
 +ARM/Orion SoC/Technologic Systems TS-78xx platform support
 +M:    Alexander Clouter <alex@digriz.org.uk>
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +W:    http://www.digriz.org.uk/ts78xx/kernel
 +S:    Maintained
 +F:    arch/arm/mach-orion5x/ts78xx-*
 +
  ARM/MIOA701 MACHINE SUPPORT
  M:    Robert Jarzmik <robert.jarzmik@free.fr>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@ -1032,13 -1025,12 +1032,13 @@@ W:   http://www.fluff.org/ben/linux
  S:    Maintained
  F:    arch/arm/mach-s3c64xx/
  
 -ARM/S5P ARM ARCHITECTURES
 +ARM/S5P EXYNOS ARM ARCHITECTURES
  M:    Kukjin Kim <kgene.kim@samsung.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  L:    linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm/mach-s5p*/
 +F:    arch/arm/mach-exynos*/
  
  ARM/SAMSUNG MOBILE MACHINE SUPPORT
  M:    Kyungmin Park <kyungmin.park@samsung.com>
@@@ -1071,7 -1063,7 +1071,7 @@@ F:      arch/arm/mach-shmobile
  F:    drivers/sh/
  
  ARM/TELECHIPS ARM ARCHITECTURE
 -M:    "Hans J. Koch" <hjk@linutronix.de>
 +M:    "Hans J. Koch" <hjk@hansjkoch.de>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm/plat-tcc/
@@@ -1165,14 -1157,14 +1165,14 @@@ S:   Maintaine
  F:    Documentation/hwmon/asc7621
  F:    drivers/hwmon/asc7621.c
  
 -ASUS ACPI EXTRAS DRIVER
 +ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS
  M:    Corentin Chary <corentincj@iksaif.net>
 -M:    Karol Kozimor <sziwan@users.sourceforge.net>
  L:    acpi4asus-user@lists.sourceforge.net
  L:    platform-driver-x86@vger.kernel.org
  W:    http://acpi4asus.sf.net
  S:    Maintained
 -F:    drivers/platform/x86/asus_acpi.c
 +F:    drivers/platform/x86/asus*.c
 +F:    drivers/platform/x86/eeepc*.c
  
  ASUS ASB100 HARDWARE MONITOR DRIVER
  M:    "Mark M. Hoffman" <mhoffman@lightlink.com>
@@@ -1180,6 -1172,14 +1180,6 @@@ L:     lm-sensors@lm-sensors.or
  S:    Maintained
  F:    drivers/hwmon/asb100.c
  
 -ASUS LAPTOP EXTRAS DRIVER
 -M:    Corentin Chary <corentincj@iksaif.net>
 -L:    acpi4asus-user@lists.sourceforge.net
 -L:    platform-driver-x86@vger.kernel.org
 -W:    http://acpi4asus.sf.net
 -S:    Maintained
 -F:    drivers/platform/x86/asus-laptop.c
 -
  ASYNCHRONOUS TRANSFERS/TRANSFORMS (IOAT) API
  M:    Dan Williams <dan.j.williams@intel.com>
  W:    http://sourceforge.net/projects/xscaleiop
@@@ -1831,10 -1831,11 +1831,10 @@@ S:   Maintaine
  F:    drivers/platform/x86/compal-laptop.c
  
  COMPUTONE INTELLIPORT MULTIPORT CARD
 -M:    "Michael H. Warfield" <mhw@wittsend.com>
  W:    http://www.wittsend.com/computone.html
 -S:    Maintained
 +S:    Orphan
  F:    Documentation/serial/computone.txt
 -F:    drivers/char/ip2/
 +F:    drivers/staging/tty/ip2/
  
  CONEXANT ACCESSRUNNER USB DRIVER
  M:    Simon Arlott <cxacru@fire.lp0.eu>
@@@ -2017,7 -2018,7 +2017,7 @@@ F:      drivers/net/wan/cycx
  CYCLADES ASYNC MUX DRIVER
  W:    http://www.cyclades.com/
  S:    Orphan
 -F:    drivers/char/cyclades.c
 +F:    drivers/tty/cyclades.c
  F:    include/linux/cyclades.h
  
  CYCLADES PC300 DRIVER
@@@ -2131,8 -2132,8 +2131,8 @@@ L:      Eng.Linux@digi.co
  W:    http://www.digi.com
  S:    Orphan
  F:    Documentation/serial/digiepca.txt
 -F:    drivers/char/epca*
 -F:    drivers/char/digi*
 +F:    drivers/staging/tty/epca*
 +F:    drivers/staging/tty/digi*
  
  DIOLAN U2C-12 I2C DRIVER
  M:    Guenter Roeck <guenter.roeck@ericsson.com>
@@@ -2413,6 -2414,22 +2413,6 @@@ T:     git git://git.alsa-project.org/alsa-
  S:    Maintained
  F:    sound/usb/misc/ua101.c
  
 -EEEPC LAPTOP EXTRAS DRIVER
 -M:    Corentin Chary <corentincj@iksaif.net>
 -L:    acpi4asus-user@lists.sourceforge.net
 -L:    platform-driver-x86@vger.kernel.org
 -W:    http://acpi4asus.sf.net
 -S:    Maintained
 -F:    drivers/platform/x86/eeepc-laptop.c
 -
 -EEEPC WMI EXTRAS DRIVER
 -M:    Corentin Chary <corentincj@iksaif.net>
 -L:    acpi4asus-user@lists.sourceforge.net
 -L:    platform-driver-x86@vger.kernel.org
 -W:    http://acpi4asus.sf.net
 -S:    Maintained
 -F:    drivers/platform/x86/eeepc-wmi.c
 -
  EFIFB FRAMEBUFFER DRIVER
  L:    linux-fbdev@vger.kernel.org
  M:    Peter Jones <pjones@redhat.com>
@@@ -2809,7 -2826,7 +2809,7 @@@ GPIO SUBSYSTE
  M:    Grant Likely <grant.likely@secretlab.ca>
  S:    Maintained
  T:    git git://git.secretlab.ca/git/linux-2.6.git
 -F:    Documentation/gpio/gpio.txt
 +F:    Documentation/gpio.txt
  F:    drivers/gpio/
  F:    include/linux/gpio*
  
@@@ -4084,7 -4101,7 +4084,7 @@@ F:      drivers/video/matrox/matroxfb_
  F:    include/linux/matroxfb.h
  
  MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
 -M:    "Hans J. Koch" <hjk@linutronix.de>
 +M:    "Hans J. Koch" <hjk@hansjkoch.de>
  L:    lm-sensors@lm-sensors.org
  S:    Maintained
  F:    Documentation/hwmon/max6650
@@@ -4199,7 -4216,7 +4199,7 @@@ MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL C
  M:    Jiri Slaby <jirislaby@gmail.com>
  S:    Maintained
  F:    Documentation/serial/moxa-smartio
 -F:    drivers/char/mxser.*
 +F:    drivers/tty/mxser.*
  
  MSI LAPTOP SUPPORT
  M:    "Lee, Chun-Yi" <jlee@novell.com>
@@@ -4241,7 -4258,7 +4241,7 @@@ F:      sound/oss/msnd
  
  MULTITECH MULTIPORT CARD (ISICOM)
  S:    Orphan
 -F:    drivers/char/isicom.c
 +F:    drivers/tty/isicom.c
  F:    include/linux/isicom.h
  
  MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
@@@ -4264,6 -4281,13 +4264,13 @@@ M:    Tim Hockin <thockin@hockin.org
  S:    Maintained
  F:    drivers/net/natsemi.c
  
+ NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER
+ M:    Daniel Mack <zonque@gmail.com>
+ S:    Maintained
+ L:    alsa-devel@alsa-project.org
+ W:    http://www.native-instruments.com
+ F:    sound/usb/caiaq/
  NCP FILESYSTEM
  M:    Petr Vandrovec <petr@vandrovec.name>
  S:    Odd Fixes
@@@ -5280,14 -5304,14 +5287,14 @@@ F:   drivers/memstick/host/r592.
  RISCOM8 DRIVER
  S:    Orphan
  F:    Documentation/serial/riscom8.txt
 -F:    drivers/char/riscom8*
 +F:    drivers/staging/tty/riscom8*
  
  ROCKETPORT DRIVER
  P:    Comtrol Corp.
  W:    http://www.comtrol.com
  S:    Maintained
  F:    Documentation/serial/rocket.txt
 -F:    drivers/char/rocket*
 +F:    drivers/tty/rocket*
  
  ROSE NETWORK LAYER
  M:    Ralf Baechle <ralf@linux-mips.org>
@@@ -5397,7 -5421,7 +5404,7 @@@ F:      drivers/media/video/*7146
  F:    include/media/*7146*
  
  SAMSUNG AUDIO (ASoC) DRIVERS
 -M:    Jassi Brar <jassi.brar@samsung.com>
 +M:    Jassi Brar <jassisinghbrar@gmail.com>
  L:    alsa-devel@alsa-project.org (moderated for non-subscribers)
  S:    Supported
  F:    sound/soc/samsung
@@@ -5923,9 -5947,10 +5930,9 @@@ F:     arch/arm/mach-spear6xx/spear600.
  F:    arch/arm/mach-spear6xx/spear600_evb.c
  
  SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
 -M:    Roger Wolff <R.E.Wolff@BitWizard.nl>
 -S:    Supported
 +S:    Orphan
  F:    Documentation/serial/specialix.txt
 -F:    drivers/char/specialix*
 +F:    drivers/staging/tty/specialix*
  
  SPI SUBSYSTEM
  M:    David Brownell <dbrownell@users.sourceforge.net>
@@@ -5970,6 -5995,7 +5977,6 @@@ F:      arch/alpha/kernel/srm_env.
  
  STABLE BRANCH
  M:    Greg Kroah-Hartman <greg@kroah.com>
 -M:    Chris Wright <chrisw@sous-sol.org>
  L:    stable@kernel.org
  S:    Maintained
  
@@@ -6253,8 -6279,7 +6260,8 @@@ M:      Greg Ungerer <gerg@uclinux.org
  W:    http://www.uclinux.org/
  L:    uclinux-dev@uclinux.org  (subscribers-only)
  S:    Maintained
 -F:    arch/m68knommu/
 +F:    arch/m68k/*/*_no.*
 +F:    arch/m68k/include/asm/*_no.*
  
  UCLINUX FOR RENESAS H8/300 (H8300)
  M:    Yoshinori Sato <ysato@users.sourceforge.jp>
@@@ -6556,7 -6581,7 +6563,7 @@@ S:      Maintaine
  F:    drivers/usb/host/uhci*
  
  USB "USBNET" DRIVER FRAMEWORK
 -M:    David Brownell <dbrownell@users.sourceforge.net>
 +M:    Oliver Neukum <oneukum@suse.de>
  L:    netdev@vger.kernel.org
  W:    http://www.linux-usb.org/usbnet
  S:    Maintained
@@@ -6624,7 -6649,7 +6631,7 @@@ F:      fs/hostfs
  F:    fs/hppfs/
  
  USERSPACE I/O (UIO)
 -M:    "Hans J. Koch" <hjk@linutronix.de>
 +M:    "Hans J. Koch" <hjk@hansjkoch.de>
  M:    Greg Kroah-Hartman <gregkh@suse.de>
  S:    Maintained
  F:    Documentation/DocBook/uio-howto.tmpl
@@@ -6922,25 -6947,6 +6929,25 @@@ T:    git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    drivers/platform/x86
  
 +XEN HYPERVISOR INTERFACE
 +M:    Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
 +M:    Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
 +L:    xen-devel@lists.xensource.com (moderated for non-subscribers)
 +L:    virtualization@lists.linux-foundation.org
 +S:    Supported
 +F:    arch/x86/xen/
 +F:    drivers/*/xen-*front.c
 +F:    drivers/xen/
 +F:    arch/x86/include/asm/xen/
 +F:    include/xen/
 +
 +XEN NETWORK BACKEND DRIVER
 +M:    Ian Campbell <ian.campbell@citrix.com>
 +L:    xen-devel@lists.xensource.com (moderated for non-subscribers)
 +L:    netdev@vger.kernel.org
 +S:    Supported
 +F:    drivers/net/xen-netback/*
 +
  XEN PCI SUBSYSTEM
  M:    Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
  L:    xen-devel@lists.xensource.com (moderated for non-subscribers)
@@@ -6955,6 -6961,18 +6962,6 @@@ S:     Supporte
  F:    arch/x86/xen/*swiotlb*
  F:    drivers/xen/*swiotlb*
  
 -XEN HYPERVISOR INTERFACE
 -M:    Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
 -M:    Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
 -L:    xen-devel@lists.xensource.com (moderated for non-subscribers)
 -L:    virtualization@lists.linux-foundation.org
 -S:    Supported
 -F:    arch/x86/xen/
 -F:    drivers/*/xen-*front.c
 -F:    drivers/xen/
 -F:    arch/x86/include/asm/xen/
 -F:    include/xen/
 -
  XFS FILESYSTEM
  P:    Silicon Graphics Inc
  M:    Alex Elder <aelder@sgi.com>
diff --combined include/sound/control.h
@@@ -113,6 -113,7 +113,7 @@@ struct snd_kcontrol *snd_ctl_new1(cons
  void snd_ctl_free_one(struct snd_kcontrol * kcontrol);
  int snd_ctl_add(struct snd_card * card, struct snd_kcontrol * kcontrol);
  int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
+ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace);
  int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
  int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
  int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id,
@@@ -191,7 -192,7 +192,7 @@@ int _snd_ctl_add_slave(struct snd_kcont
   * Returns zero if successful or a negative error code.
   *
   * All slaves must be the same type (returning the same information
 - * via info callback).  The fucntion doesn't check it, so it's your
 + * via info callback).  The function doesn't check it, so it's your
   * responsibility.
   *
   * Also, some additional limitations:
diff --combined sound/pci/Kconfig
@@@ -534,6 -534,14 +534,14 @@@ config SND_ES1968_INPU
          If you say N the buttons will directly control the master volume.
          It is recommended to say Y.
  
+ config SND_ES1968_RADIO
+       bool "Enable TEA5757 radio tuner support for es1968"
+       depends on SND_ES1968
+       depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_ES1968
+       help
+         Say Y here to include support for TEA5757 radio tuner integrated on
+         some MediaForte cards (e.g. SF64-PCE2).
  config SND_FM801
        tristate "ForteMedia FM801"
        select SND_OPL3_LIB
@@@ -552,13 -560,13 +560,13 @@@ config SND_FM801_TEA575X_BOO
        depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801
        help
          Say Y here to include support for soundcards based on the ForteMedia
-         FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media
-         Forte SF256-PCS-02) into the snd-fm801 driver.
+         FM801 chip with a TEA5757 tuner (MediaForte SF256-PCS, SF256-PCP and
+         SF64-PCR) into the snd-fm801 driver.
  
- config SND_FM801_TEA575X
+ config SND_TEA575X
        tristate
-       depends on SND_FM801_TEA575X_BOOL
-       default SND_FM801
+       depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO
+       default SND_FM801 || SND_ES1968
  
  source "sound/pci/hda/Kconfig"
  
@@@ -658,15 -666,6 +666,15 @@@ config SND_KORG121
          To compile this driver as a module, choose M here: the module
          will be called snd-korg1212.
  
 +config SND_LOLA
 +      tristate "Digigram Lola"
 +      select SND_PCM
 +      help
 +        Say Y to include support for Digigram Lola boards.
 +
 +        To compile this driver as a module, choose M here: the module
 +        will be called snd-lola.
 +
  config SND_LX6464ES
        tristate "Digigram LX6464ES"
        select SND_PCM
  #include <sound/tlv.h>
  #include <sound/hwdep.h>
  
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
  MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
  
+ #if defined CONFIG_SND_DEBUG
+ /* copied from pcm_lib.c, hope later patch will make that version public
+ and this copy can be removed */
+ static void pcm_debug_name(struct snd_pcm_substream *substream,
+                          char *name, size_t len)
+ {
+       snprintf(name, len, "pcmC%dD%d%c:%d",
+                substream->pcm->card->number,
+                substream->pcm->device,
+                substream->stream ? 'c' : 'p',
+                substream->number);
+ }
+ #define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name))
+ #else
+ #define pcm_debug_name(s, n, l) do { } while (0)
+ #define DEBUG_NAME(name, substream) do { } while (0)
+ #endif
  #if defined CONFIG_SND_DEBUG_VERBOSE
  /**
   * snd_printddd - very verbose debug printk
@@@ -58,7 -77,7 +77,7 @@@
  #define snd_printddd(format, args...) \
        __snd_printk(3, __FILE__, __LINE__, format, ##args)
  #else
- #define snd_printddd(format, args...) do { } while (0)
+ #define snd_printddd(format, args...) do { } while (0)
  #endif
  
  static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;    /* index 0-MAX */
@@@ -101,13 -120,6 +120,6 @@@ static int adapter_fs = DEFAULT_SAMPLER
  #define PERIOD_BYTES_MIN  2048
  #define BUFFER_BYTES_MAX (512 * 1024)
  
- /* convert stream to character */
- #define SCHR(s) ((s == SNDRV_PCM_STREAM_PLAYBACK) ? 'P' : 'C')
- /*#define TIMER_MILLISECONDS 20
- #define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000)
- */
  #define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
  
  struct clk_source {
@@@ -136,7 -148,7 +148,7 @@@ struct snd_card_asihpi 
        u32 h_mixer;
        struct clk_cache cc;
  
-       u16 support_mmap;
+       u16 can_dma;
        u16 support_grouping;
        u16 support_mrx;
        u16 update_interval_frames;
@@@ -155,6 -167,7 +167,7 @@@ struct snd_card_asihpi_pcm 
        unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */
        unsigned int pcm_buf_dma_ofs;   /* DMA R/W offset in buffer */
        unsigned int pcm_buf_elapsed_dma_ofs;   /* DMA R/W offset in buffer */
+       unsigned int drained_count;
        struct snd_pcm_substream *substream;
        u32 h_stream;
        struct hpi_format format;
@@@ -288,19 -301,26 +301,26 @@@ static u16 handle_error(u16 err, int li
  #define hpi_handle_error(x)  handle_error(x, __LINE__, __FILE__)
  
  /***************************** GENERAL PCM ****************/
- static void print_hwparams(struct snd_pcm_hw_params *p)
+ static void print_hwparams(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *p)
  {
-       snd_printd("HWPARAMS \n");
-       snd_printd("samplerate %d \n", params_rate(p));
-       snd_printd("Channels %d \n", params_channels(p));
-       snd_printd("Format %d \n", params_format(p));
-       snd_printd("subformat %d \n", params_subformat(p));
-       snd_printd("Buffer bytes %d \n", params_buffer_bytes(p));
-       snd_printd("Period bytes %d \n", params_period_bytes(p));
-       snd_printd("access %d \n", params_access(p));
-       snd_printd("period_size %d \n", params_period_size(p));
-       snd_printd("periods %d \n", params_periods(p));
-       snd_printd("buffer_size %d \n", params_buffer_size(p));
+       DEBUG_NAME(substream, name);
+       snd_printd("%s HWPARAMS\n", name);
+       snd_printd(" samplerate %d Hz\n", params_rate(p));
+       snd_printd(" channels %d\n", params_channels(p));
+       snd_printd(" format %d\n", params_format(p));
+       snd_printd(" subformat %d\n", params_subformat(p));
+       snd_printd(" buffer %d B\n", params_buffer_bytes(p));
+       snd_printd(" period %d B\n", params_period_bytes(p));
+       snd_printd(" access %d\n", params_access(p));
+       snd_printd(" period_size %d\n", params_period_size(p));
+       snd_printd(" periods %d\n", params_periods(p));
+       snd_printd(" buffer_size %d\n", params_buffer_size(p));
+       snd_printd(" %d B/s\n", params_rate(p) *
+               params_channels(p) *
+               snd_pcm_format_width(params_format(p)) / 8);
  }
  
  static snd_pcm_format_t hpi_to_alsa_formats[] = {
@@@ -451,7 -471,7 +471,7 @@@ static int snd_card_asihpi_pcm_hw_param
        int width;
        unsigned int bytes_per_sec;
  
-       print_hwparams(params);
+       print_hwparams(substream, params);
        err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
        if (err < 0)
                return err;
        if (err)
                return err;
  
-       snd_printdd("format %d, %d chans, %d_hz\n",
-                               format, params_channels(params),
-                               params_rate(params));
        hpi_handle_error(hpi_format_create(&dpcm->format,
                        params_channels(params),
                        format, params_rate(params), 0, 0));
        }
  
        dpcm->hpi_buffer_attached = 0;
-       if (card->support_mmap) {
+       if (card->can_dma) {
                err = hpi_stream_host_buffer_attach(dpcm->h_stream,
                        params_buffer_bytes(params),  runtime->dma_addr);
                if (err == 0) {
        dpcm->bytes_per_sec = bytes_per_sec;
        dpcm->buffer_bytes = params_buffer_bytes(params);
        dpcm->period_bytes = params_period_bytes(params);
-       snd_printdd("buffer_bytes=%d, period_bytes=%d, bps=%d\n",
-                       dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec);
  
        return 0;
  }
@@@ -564,9 -577,10 +577,10 @@@ static int snd_card_asihpi_trigger(stru
        struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
        struct snd_pcm_substream *s;
        u16 e;
+       DEBUG_NAME(substream, name);
+       snd_printdd("%s trigger\n", name);
  
-       snd_printdd("%c%d trigger\n",
-                       SCHR(substream->stream), substream->number);
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
                snd_pcm_group_for_each_entry(s, substream) {
                        if (substream->stream != s->stream)
                                continue;
  
-                       if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
-                               (card->support_mmap)) {
+                       ds->drained_count = 0;
+                       if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                                /* How do I know how much valid data is present
                                * in buffer? Must be at least one period!
                                * Guessing 2 periods, but if
                        }
  
                        if (card->support_grouping) {
-                               snd_printdd("\t%c%d group\n",
-                                               SCHR(s->stream),
-                                               s->number);
+                               snd_printdd("%d group\n", s->number);
                                e = hpi_stream_group_add(
                                        dpcm->h_stream,
                                        ds->h_stream);
                /* start the master stream */
                snd_card_asihpi_pcm_timer_start(substream);
                if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
-                       !card->support_mmap)
+                       !card->can_dma)
                        hpi_handle_error(hpi_stream_start(dpcm->h_stream));
                break;
  
                        s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
  
                        if (card->support_grouping) {
-                               snd_printdd("\t%c%d group\n",
-                               SCHR(s->stream),
-                                       s->number);
+                               snd_printdd("%d group\n", s->number);
                                snd_pcm_trigger_done(s, substream);
                        } else
                                break;
@@@ -732,9 -742,9 +742,9 @@@ static void snd_card_asihpi_timer_funct
        int loops = 0;
        u16 state;
        u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
+       DEBUG_NAME(substream, name);
  
-       snd_printdd("%c%d snd_card_asihpi_timer_function\n",
-                               SCHR(substream->stream), substream->number);
+       snd_printdd("%s snd_card_asihpi_timer_function\n", name);
  
        /* find minimum newdata and buffer pos in group */
        snd_pcm_group_for_each_entry(s, substream) {
                /* number of bytes in on-card buffer */
                runtime->delay = on_card_bytes;
  
+               if (!card->can_dma)
+                       on_card_bytes = bytes_avail;
                if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                        pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
                        if (state == HPI_STATE_STOPPED) {
                                    (on_card_bytes < ds->pcm_buf_host_rw_ofs)) {
                                        hpi_handle_error(hpi_stream_start(ds->h_stream));
                                        snd_printdd("P%d start\n", s->number);
+                                       ds->drained_count = 0;
                                }
                        } else if (state == HPI_STATE_DRAINED) {
                                snd_printd(KERN_WARNING "P%d drained\n",
                                                s->number);
-                               /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
-                               continue; */
+                               ds->drained_count++;
+                               if (ds->drained_count > 2) {
+                                       snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
+                                       continue;
+                               }
+                       } else {
+                               ds->drained_count = 0;
                        }
                } else
                        pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
                                newdata);
                }
  
-               snd_printdd("hw_ptr x%04lX, appl_ptr x%04lX\n",
+               snd_printdd("hw_ptr 0x%04lX, appl_ptr 0x%04lX\n",
                        (unsigned long)frames_to_bytes(runtime,
                                                runtime->status->hw_ptr),
                        (unsigned long)frames_to_bytes(runtime,
                                                runtime->control->appl_ptr));
  
-               snd_printdd("%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X,"
-                       " aux=x%04X space=x%04X\n",
-                       loops, SCHR(s->stream), s->number,
-                       state,  ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail,
+               snd_printdd("%d S=%d, "
+                       "rw=0x%04X, dma=0x%04X, left=0x%04X, "
+                       "aux=0x%04X space=0x%04X\n",
+                       s->number, state,
+                       ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs,
+                       (int)bytes_avail,
                        (int)on_card_bytes, buffer_size-bytes_avail);
                loops++;
        }
  
        next_jiffies = max(next_jiffies, 1U);
        dpcm->timer.expires = jiffies + next_jiffies;
-       snd_printdd("jif %d buf pos x%04X newdata x%04X xfer x%04X\n",
+       snd_printdd("jif %d buf pos 0x%04X newdata 0x%04X xfer 0x%04X\n",
                        next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
  
        snd_pcm_group_for_each_entry(s, substream) {
  
                ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
  
-               if (xfercount && (on_card_bytes <= ds->period_bytes)) {
-                       if (card->support_mmap) {
-                               if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-                                       snd_printddd("P%d write x%04x\n",
+               if (xfercount &&
+                       /* Limit use of on card fifo for playback */
+                       ((on_card_bytes <= ds->period_bytes) ||
+                       (s->stream == SNDRV_PCM_STREAM_CAPTURE)))
+               {
+                       unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes;
+                       unsigned int xfer1, xfer2;
+                       char *pd = &s->runtime->dma_area[buf_ofs];
+                       if (card->can_dma) { /* buffer wrap is handled at lower level */
+                               xfer1 = xfercount;
+                               xfer2 = 0;
+                       } else {
+                               xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs);
+                               xfer2 = xfercount - xfer1;
+                       }
+                       if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+                               snd_printddd("P%d write1 0x%04X 0x%04X\n",
+                                       s->number, xfer1, buf_ofs);
+                               hpi_handle_error(
+                                       hpi_outstream_write_buf(
+                                               ds->h_stream, pd, xfer1,
+                                               &ds->format));
+                               if (xfer2) {
+                                       pd = s->runtime->dma_area;
+                                       snd_printddd("P%d write2 0x%04X 0x%04X\n",
                                                        s->number,
-                                                       ds->period_bytes);
+                                                       xfercount - xfer1, buf_ofs);
                                        hpi_handle_error(
                                                hpi_outstream_write_buf(
-                                                       ds->h_stream,
-                                                       &s->runtime->
-                                                               dma_area[0],
-                                                       xfercount,
+                                                       ds->h_stream, pd,
+                                                       xfercount - xfer1,
                                                        &ds->format));
-                               } else {
-                                       snd_printddd("C%d read x%04x\n",
-                                               s->number,
-                                               xfercount);
+                               }
+                       } else {
+                               snd_printddd("C%d read1 0x%04x\n",
+                                       s->number, xfer1);
+                               hpi_handle_error(
+                                       hpi_instream_read_buf(
+                                               ds->h_stream,
+                                               pd, xfer1));
+                               if (xfer2) {
+                                       pd = s->runtime->dma_area;
+                                       snd_printddd("C%d read2 0x%04x\n",
+                                               s->number, xfer2);
                                        hpi_handle_error(
                                                hpi_instream_read_buf(
                                                        ds->h_stream,
-                                                       NULL, xfercount));
+                                                       pd, xfer2));
                                }
-                               ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount;
-                       } /* else R/W will be handled by read/write callbacks */
+                       }
+                       ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount;
                        ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs;
                        snd_pcm_period_elapsed(s);
                }
  static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
                                          unsigned int cmd, void *arg)
  {
-       snd_printdd(KERN_INFO "Playback ioctl %d\n", cmd);
+       snd_printddd(KERN_INFO "P%d ioctl %d\n", substream->number, cmd);
        return snd_pcm_lib_ioctl(substream, cmd, arg);
  }
  
@@@ -873,7 -927,7 +927,7 @@@ static int snd_card_asihpi_playback_pre
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
  
-       snd_printdd("playback prepare %d\n", substream->number);
+       snd_printdd("P%d prepare\n", substream->number);
  
        hpi_handle_error(hpi_outstream_reset(dpcm->h_stream));
        dpcm->pcm_buf_host_rw_ofs = 0;
@@@ -890,7 -944,7 +944,7 @@@ snd_card_asihpi_playback_pointer(struc
        snd_pcm_uframes_t ptr;
  
        ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs  % dpcm->buffer_bytes);
-       snd_printddd("playback_pointer=x%04lx\n", (unsigned long)ptr);
+       snd_printddd("P%d pointer = 0x%04lx\n", substream->number, (unsigned long)ptr);
        return ptr;
  }
  
@@@ -963,7 -1017,7 +1017,7 @@@ static int snd_card_asihpi_playback_ope
  
        /*? also check ASI5000 samplerate source
            If external, only support external rate.
 -          If internal and other stream playing, cant switch
 +          If internal and other stream playing, can't switch
        */
  
        init_timer(&dpcm->timer);
                                        SNDRV_PCM_INFO_DOUBLE |
                                        SNDRV_PCM_INFO_BATCH |
                                        SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                                       SNDRV_PCM_INFO_PAUSE;
-       if (card->support_mmap)
-               snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP |
-                                               SNDRV_PCM_INFO_MMAP_VALID;
+                                       SNDRV_PCM_INFO_PAUSE |
+                                       SNDRV_PCM_INFO_MMAP |
+                                       SNDRV_PCM_INFO_MMAP_VALID;
  
        if (card->support_grouping)
                snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
        /* struct is copied, so can create initializer dynamically */
        runtime->hw = snd_card_asihpi_playback;
  
-       if (card->support_mmap)
+       if (card->can_dma)
                err = snd_pcm_hw_constraint_pow2(runtime, 0,
                                        SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
        if (err < 0)
@@@ -1028,58 -1080,6 +1080,6 @@@ static int snd_card_asihpi_playback_clo
        return 0;
  }
  
- static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
-                                       int channel,
-                                       snd_pcm_uframes_t pos,
-                                       void __user *src,
-                                       snd_pcm_uframes_t count)
- {
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
-       unsigned int len;
-       len = frames_to_bytes(runtime, count);
-       if (copy_from_user(runtime->dma_area, src, len))
-               return -EFAULT;
-       snd_printddd("playback copy%d %u bytes\n",
-                       substream->number, len);
-       hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream,
-                               runtime->dma_area, len, &dpcm->format));
-       dpcm->pcm_buf_host_rw_ofs += len;
-       return 0;
- }
- static int snd_card_asihpi_playback_silence(struct snd_pcm_substream *
-                                           substream, int channel,
-                                           snd_pcm_uframes_t pos,
-                                           snd_pcm_uframes_t count)
- {
-       /* Usually writes silence to DMA buffer, which should be overwritten
-       by real audio later.  Our fifos cannot be overwritten, and are not
-       free-running DMAs. Silence is output on fifo underflow.
-       This callback is still required to allow the copy callback to be used.
-       */
-       return 0;
- }
- static struct snd_pcm_ops snd_card_asihpi_playback_ops = {
-       .open = snd_card_asihpi_playback_open,
-       .close = snd_card_asihpi_playback_close,
-       .ioctl = snd_card_asihpi_playback_ioctl,
-       .hw_params = snd_card_asihpi_pcm_hw_params,
-       .hw_free = snd_card_asihpi_hw_free,
-       .prepare = snd_card_asihpi_playback_prepare,
-       .trigger = snd_card_asihpi_trigger,
-       .pointer = snd_card_asihpi_playback_pointer,
-       .copy = snd_card_asihpi_playback_copy,
-       .silence = snd_card_asihpi_playback_silence,
- };
  static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
        .open = snd_card_asihpi_playback_open,
        .close = snd_card_asihpi_playback_close,
@@@ -1211,18 -1211,16 +1211,16 @@@ static int snd_card_asihpi_capture_open
        snd_card_asihpi_capture_format(card, dpcm->h_stream,
                                       &snd_card_asihpi_capture);
        snd_card_asihpi_pcm_samplerates(card,  &snd_card_asihpi_capture);
-       snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED;
-       if (card->support_mmap)
-               snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP |
-                                               SNDRV_PCM_INFO_MMAP_VALID;
+       snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
+                                       SNDRV_PCM_INFO_MMAP |
+                                       SNDRV_PCM_INFO_MMAP_VALID;
  
        if (card->support_grouping)
                snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
  
        runtime->hw = snd_card_asihpi_capture;
  
-       if (card->support_mmap)
+       if (card->can_dma)
                err = snd_pcm_hw_constraint_pow2(runtime, 0,
                                        SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
        if (err < 0)
@@@ -1246,28 -1244,6 +1244,6 @@@ static int snd_card_asihpi_capture_clos
        return 0;
  }
  
- static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
-                               int channel, snd_pcm_uframes_t pos,
-                               void __user *dst, snd_pcm_uframes_t count)
- {
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
-       u32 len;
-       len = frames_to_bytes(runtime, count);
-       snd_printddd("capture copy%d %d bytes\n", substream->number, len);
-       hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream,
-                               runtime->dma_area, len));
-       dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len;
-       if (copy_to_user(dst, runtime->dma_area, len))
-               return -EFAULT;
-       return 0;
- }
  static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
        .open = snd_card_asihpi_capture_open,
        .close = snd_card_asihpi_capture_close,
        .pointer = snd_card_asihpi_capture_pointer,
  };
  
- static struct snd_pcm_ops snd_card_asihpi_capture_ops = {
-       .open = snd_card_asihpi_capture_open,
-       .close = snd_card_asihpi_capture_close,
-       .ioctl = snd_card_asihpi_capture_ioctl,
-       .hw_params = snd_card_asihpi_pcm_hw_params,
-       .hw_free = snd_card_asihpi_hw_free,
-       .prepare = snd_card_asihpi_capture_prepare,
-       .trigger = snd_card_asihpi_trigger,
-       .pointer = snd_card_asihpi_capture_pointer,
-       .copy = snd_card_asihpi_capture_copy
- };
  static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
                                      int device, int substreams)
  {
        if (err < 0)
                return err;
        /* pointer to ops struct is stored, dont change ops afterwards! */
-       if (asihpi->support_mmap) {
                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
                                &snd_card_asihpi_playback_mmap_ops);
                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
                                &snd_card_asihpi_capture_mmap_ops);
-       } else {
-               snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
-                               &snd_card_asihpi_playback_ops);
-               snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
-                               &snd_card_asihpi_capture_ops);
-       }
  
        pcm->private_data = asihpi;
        pcm->info_flags = 0;
@@@ -1413,14 -1370,16 +1370,16 @@@ static void asihpi_ctl_init(struct snd_
                                struct hpi_control *hpi_ctl,
                                char *name)
  {
-       char *dir = "";
+       char *dir;
        memset(snd_control, 0, sizeof(*snd_control));
        snd_control->name = hpi_ctl->name;
        snd_control->private_value = hpi_ctl->h_control;
        snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
        snd_control->index = 0;
  
-       if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
+       if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE)
+               dir = ""; /* clock is neither capture nor playback */
+       else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
                dir = "Capture ";  /* On or towards a PCM capture destination*/
        else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
                (!hpi_ctl->dst_node_type))
                dir = "Playback "; /* PCM Playback source, or  output node */
  
        if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
-               sprintf(hpi_ctl->name, "%s%d %s%d %s%s",
+               sprintf(hpi_ctl->name, "%s %d %s %d %s%s",
                        asihpi_src_names[hpi_ctl->src_node_type],
                        hpi_ctl->src_node_index,
                        asihpi_dst_names[hpi_ctl->dst_node_type],
@@@ -2875,14 -2834,14 +2834,14 @@@ static int __devinit snd_asihpi_probe(s
        if (err)
                asihpi->update_interval_frames = 512;
  
-       if (!asihpi->support_mmap)
+       if (!asihpi->can_dma)
                asihpi->update_interval_frames *= 2;
  
        hpi_handle_error(hpi_instream_open(asihpi->adapter_index,
                             0, &h_stream));
  
        err = hpi_instream_host_buffer_free(h_stream);
-       asihpi->support_mmap = (!err);
+       asihpi->can_dma = (!err);
  
        hpi_handle_error(hpi_instream_close(h_stream));
  
                asihpi->out_max_chans = 2;
        }
  
-       snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n",
-                       asihpi->support_mmap,
+       snd_printk(KERN_INFO "has dma:%d, grouping:%d, mrx:%d\n",
+                       asihpi->can_dma,
                        asihpi->support_grouping,
                        asihpi->support_mrx
              );
            by enable_hwdep  module param*/
        snd_asihpi_hpi_new(asihpi, 0, NULL);
  
-       if (asihpi->support_mmap)
-               strcpy(card->driver, "ASIHPI-MMAP");
-       else
-               strcpy(card->driver, "ASIHPI");
+       strcpy(card->driver, "ASIHPI");
  
        sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
        sprintf(card->longname, "%s %i",
@@@ -200,8 -200,8 +200,8 @@@ static void hpi_read_block(struct dsp_o
  static void subsys_create_adapter(struct hpi_message *phm,
        struct hpi_response *phr);
  
- static void subsys_delete_adapter(struct hpi_message *phm,
-       struct hpi_response *phr);
+ static void adapter_delete(struct hpi_adapter_obj *pao,
+       struct hpi_message *phm, struct hpi_response *phr);
  
  static void adapter_get_asserts(struct hpi_adapter_obj *pao,
        struct hpi_message *phm, struct hpi_response *phr);
@@@ -222,9 -222,6 +222,6 @@@ static void subsys_message(struct hpi_m
        case HPI_SUBSYS_CREATE_ADAPTER:
                subsys_create_adapter(phm, phr);
                break;
-       case HPI_SUBSYS_DELETE_ADAPTER:
-               subsys_delete_adapter(phm, phr);
-               break;
        default:
                phr->error = HPI_ERROR_INVALID_FUNC;
                break;
@@@ -279,6 -276,10 +276,10 @@@ static void adapter_message(struct hpi_
                adapter_get_asserts(pao, phm, phr);
                break;
  
+       case HPI_ADAPTER_DELETE:
+               adapter_delete(pao, phm, phr);
+               break;
        default:
                hw_message(pao, phm, phr);
                break;
@@@ -333,26 -334,22 +334,22 @@@ void HPI_6000(struct hpi_message *phm, 
  {
        struct hpi_adapter_obj *pao = NULL;
  
-       /* subsytem messages get executed by every HPI. */
-       /* All other messages are ignored unless the adapter index matches */
-       /* an adapter in the HPI */
-       /*HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction); */
-       /* if Dsp has crashed then do not communicate with it any more */
        if (phm->object != HPI_OBJ_SUBSYSTEM) {
                pao = hpi_find_adapter(phm->adapter_index);
                if (!pao) {
-                       HPI_DEBUG_LOG(DEBUG,
-                               " %d,%d refused, for another HPI?\n",
-                               phm->object, phm->function);
+                       hpi_init_response(phr, phm->object, phm->function,
+                               HPI_ERROR_BAD_ADAPTER_NUMBER);
+                       HPI_DEBUG_LOG(DEBUG, "invalid adapter index: %d \n",
+                               phm->adapter_index);
                        return;
                }
  
+               /* Don't even try to communicate with crashed DSP */
                if (pao->dsp_crashed >= 10) {
                        hpi_init_response(phr, phm->object, phm->function,
                                HPI_ERROR_DSP_HARDWARE);
-                       HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n",
-                               phm->object, phm->function);
+                       HPI_DEBUG_LOG(DEBUG, "adapter %d dsp crashed\n",
+                               phm->adapter_index);
                        return;
                }
        }
@@@ -423,7 -420,7 +420,7 @@@ static void subsys_create_adapter(struc
  
        ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
        if (!ao.priv) {
 -              HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
 +              HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n");
                phr->error = HPI_ERROR_MEMORY_ALLOC;
                return;
        }
        phr->error = 0;
  }
  
- static void subsys_delete_adapter(struct hpi_message *phm,
-       struct hpi_response *phr)
+ static void adapter_delete(struct hpi_adapter_obj *pao,
+       struct hpi_message *phm, struct hpi_response *phr)
  {
-       struct hpi_adapter_obj *pao = NULL;
-       pao = hpi_find_adapter(phm->obj_index);
-       if (!pao)
-               return;
        delete_adapter_obj(pao);
        hpi_delete_adapter(pao);
        phr->error = 0;
@@@ -152,8 -152,8 +152,8 @@@ static void hw_message(struct hpi_adapt
  
  static void subsys_create_adapter(struct hpi_message *phm,
        struct hpi_response *phr);
- static void subsys_delete_adapter(struct hpi_message *phm,
-       struct hpi_response *phr);
+ static void adapter_delete(struct hpi_adapter_obj *pao,
+       struct hpi_message *phm, struct hpi_response *phr);
  
  static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
        u32 *pos_error_code);
@@@ -223,15 -223,13 +223,13 @@@ static u16 boot_loader_test_pld(struct 
  
  /*****************************************************************************/
  
- static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
+ static void subsys_message(struct hpi_adapter_obj *pao,
+       struct hpi_message *phm, struct hpi_response *phr)
  {
        switch (phm->function) {
        case HPI_SUBSYS_CREATE_ADAPTER:
                subsys_create_adapter(phm, phr);
                break;
-       case HPI_SUBSYS_DELETE_ADAPTER:
-               subsys_delete_adapter(phm, phr);
-               break;
        default:
                phr->error = HPI_ERROR_INVALID_FUNC;
                break;
@@@ -279,6 -277,10 +277,10 @@@ static void adapter_message(struct hpi_
        struct hpi_message *phm, struct hpi_response *phr)
  {
        switch (phm->function) {
+       case HPI_ADAPTER_DELETE:
+               adapter_delete(pao, phm, phr);
+               break;
        default:
                hw_message(pao, phm, phr);
                break;
@@@ -371,36 -373,17 +373,17 @@@ static void instream_message(struct hpi
  /** Entry point to this HPI backend
   * All calls to the HPI start here
   */
- void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
+ void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
+       struct hpi_response *phr)
  {
-       struct hpi_adapter_obj *pao = NULL;
-       /* subsytem messages are processed by every HPI.
-        * All other messages are ignored unless the adapter index matches
-        * an adapter in the HPI
-        */
-       /* HPI_DEBUG_LOG(DEBUG, "HPI Obj=%d, Func=%d\n", phm->wObject,
-          phm->wFunction); */
-       /* if Dsp has crashed then do not communicate with it any more */
-       if (phm->object != HPI_OBJ_SUBSYSTEM) {
-               pao = hpi_find_adapter(phm->adapter_index);
-               if (!pao) {
-                       HPI_DEBUG_LOG(DEBUG,
-                               " %d,%d refused, for another HPI?\n",
-                               phm->object, phm->function);
-                       return;
-               }
-               if ((pao->dsp_crashed >= 10)
-                       && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
-                       /* allow last resort debug read even after crash */
-                       hpi_init_response(phr, phm->object, phm->function,
-                               HPI_ERROR_DSP_HARDWARE);
-                       HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
-                               phm->object, phm->function);
-                       return;
-               }
+       if (pao && (pao->dsp_crashed >= 10)
+               && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
+               /* allow last resort debug read even after crash */
+               hpi_init_response(phr, phm->object, phm->function,
+                       HPI_ERROR_DSP_HARDWARE);
+               HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", phm->object,
+                       phm->function);
+               return;
        }
  
        /* Init default response  */
        case HPI_TYPE_MESSAGE:
                switch (phm->object) {
                case HPI_OBJ_SUBSYSTEM:
-                       subsys_message(phm, phr);
+                       subsys_message(pao, phm, phr);
                        break;
  
                case HPI_OBJ_ADAPTER:
        }
  }
  
+ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
+ {
+       struct hpi_adapter_obj *pao = NULL;
+       if (phm->object != HPI_OBJ_SUBSYSTEM) {
+               /* normal messages must have valid adapter index */
+               pao = hpi_find_adapter(phm->adapter_index);
+       } else {
+               /* subsys messages don't address an adapter */
+               _HPI_6205(NULL, phm, phr);
+               return;
+       }
+       if (pao)
+               _HPI_6205(pao, phm, phr);
+       else
+               hpi_init_response(phr, phm->object, phm->function,
+                       HPI_ERROR_BAD_ADAPTER_NUMBER);
+ }
  /*****************************************************************************/
  /* SUBSYSTEM */
  
@@@ -466,7 -469,7 +469,7 @@@ static void subsys_create_adapter(struc
  
        ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
        if (!ao.priv) {
 -              HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
 +              HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n");
                phr->error = HPI_ERROR_MEMORY_ALLOC;
                return;
        }
  }
  
  /** delete an adapter - required by WDM driver */
- static void subsys_delete_adapter(struct hpi_message *phm,
-       struct hpi_response *phr)
+ static void adapter_delete(struct hpi_adapter_obj *pao,
+       struct hpi_message *phm, struct hpi_response *phr)
  {
-       struct hpi_adapter_obj *pao;
        struct hpi_hw_obj *phw;
  
-       pao = hpi_find_adapter(phm->obj_index);
        if (!pao) {
                phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
                return;
@@@ -563,11 -564,12 +564,12 @@@ static u16 create_adapter_obj(struct hp
        }
  
        err = adapter_boot_load_dsp(pao, pos_error_code);
-       if (err)
+       if (err) {
+               HPI_DEBUG_LOG(ERROR, "DSP code load failed\n");
                /* no need to clean up as SubSysCreateAdapter */
                /* calls DeleteAdapter on error. */
                return err;
+       }
        HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
  
        /* allow boot load even if mem alloc wont work */
                                control_cache.number_of_controls,
                                interface->control_cache.size_in_bytes,
                                p_control_cache_virtual);
                        if (!phw->p_cache)
                                err = HPI_ERROR_MEMORY_ALLOC;
                }
  }
  
  /** Free memory areas allocated by adapter
-  * this routine is called from SubSysDeleteAdapter,
+  * this routine is called from AdapterDelete,
    * and SubSysCreateAdapter if duplicate index
  */
  static void delete_adapter_obj(struct hpi_adapter_obj *pao)
  {
-       struct hpi_hw_obj *phw;
+       struct hpi_hw_obj *phw = pao->priv;
        int i;
  
-       phw = pao->priv;
        if (hpios_locked_mem_valid(&phw->h_control_cache)) {
                hpios_locked_mem_free(&phw->h_control_cache);
                hpi_free_control_cache(phw->p_cache);
@@@ -1275,6 -1276,7 +1276,7 @@@ static u16 adapter_boot_load_dsp(struc
        case HPI_ADAPTER_FAMILY_ASI(0x6300):
                boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400);
                break;
+       case HPI_ADAPTER_FAMILY_ASI(0x5500):
        case HPI_ADAPTER_FAMILY_ASI(0x5600):
        case HPI_ADAPTER_FAMILY_ASI(0x6500):
                boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600);
@@@ -2059,7 -2061,6 +2061,6 @@@ static int wait_dsp_ack(struct hpi_hw_o
  static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
  {
        struct bus_master_interface *interface = phw->p_interface_buffer;
        u32 r;
  
        interface->host_cmd = cmd;
@@@ -294,7 -294,7 +294,7 @@@ enum HPI_CONTROL_ATTRIBUTES 
  
  /* These defines are used to fill in protocol information for an Ethernet packet
      sent using HMI on CS18102 */
- /** ID supplied by Cirrius for ASI packets. */
+ /** ID supplied by Cirrus for ASI packets. */
  #define HPI_ETHERNET_PACKET_ID                  0x85
  /** Simple packet - no special routing required */
  #define HPI_ETHERNET_PACKET_V1                  0x01
  /** This packet must make its way to the host across the HPI interface */
  #define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1   0x41
  
- #define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */
+ #define HPI_ETHERNET_UDP_PORT 44600 /**< HPI UDP service */
  
  /** Default network timeout in milli-seconds. */
  #define HPI_ETHERNET_TIMEOUT_MS 500
@@@ -397,14 -397,14 +397,14 @@@ enum HPI_FUNCTION_IDS 
        HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1),
        HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2),
        HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3),
-       HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4),
+       /* HPI_SUBSYS_FIND_ADAPTERS     = HPI_FUNC_ID(SUBSYSTEM, 4), */
        HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5),
        HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6),
-       HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7),
+       /* HPI_SUBSYS_DELETE_ADAPTER    = HPI_FUNC_ID(SUBSYSTEM, 7), */
        HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8),
        HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9),
-       HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10),
-       HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11),
+       /* HPI_SUBSYS_READ_PORT_8               = HPI_FUNC_ID(SUBSYSTEM, 10), */
+       /* HPI_SUBSYS_WRITE_PORT_8              = HPI_FUNC_ID(SUBSYSTEM, 11), */
        HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12),
        HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13),
        HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14),
        HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18),
        HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19),
        HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20),
- #define HPI_ADAPTER_FUNCTION_COUNT 20
+       HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21),
+ #define HPI_ADAPTER_FUNCTION_COUNT 21
  
        HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1),
        HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2),
@@@ -607,7 -608,7 +608,7 @@@ struct hpi_data_compat32 
  #endif
  
  struct hpi_buffer {
 -  /** placehoder for backward compatability (see dwBufferSize) */
 +  /** placehoder for backward compatibility (see dwBufferSize) */
        struct hpi_msg_format reserved;
        u32 command; /**< HPI_BUFFER_CMD_xxx*/
        u32 pci_address; /**< PCI physical address of buffer for DSP DMA */
@@@ -1561,8 -1562,6 +1562,6 @@@ void hpi_send_recv(struct hpi_message *
  u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource,
        u16 *pw_adapter_index);
  
- u16 hpi_subsys_delete_adapter(u16 adapter_index);
  u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer,
        struct hpi_hostbuffer_status **pp_status);
  
@@@ -1584,9 -1583,7 +1583,7 @@@ void hpi_stream_response_to_legacy(stru
  
  /*////////////////////////////////////////////////////////////////////////// */
  /* declarations for individual HPI entry points */
- hpi_handler_func HPI_1000;
  hpi_handler_func HPI_6000;
  hpi_handler_func HPI_6205;
- hpi_handler_func HPI_COMMON;
  
  #endif                                /* _HPI_INTERNAL_H_ */
@@@ -211,24 -211,6 +211,6 @@@ static void subsys_message(struct hpi_m
                HPIMSGX__init(phm, phr);
                break;
  
-       case HPI_SUBSYS_DELETE_ADAPTER:
-               HPIMSGX__cleanup(phm->obj_index, h_owner);
-               {
-                       struct hpi_message hm;
-                       struct hpi_response hr;
-                       hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
-                               HPI_ADAPTER_CLOSE);
-                       hm.adapter_index = phm->obj_index;
-                       hw_entry_point(&hm, &hr);
-               }
-               if ((phm->obj_index < HPI_MAX_ADAPTERS)
-                       && hpi_entry_points[phm->obj_index]) {
-                       hpi_entry_points[phm->obj_index] (phm, phr);
-                       hpi_entry_points[phm->obj_index] = NULL;
-               } else
-                       phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
-               break;
        default:
                /* Must explicitly handle every subsys message in this switch */
                hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function,
@@@ -247,6 -229,19 +229,19 @@@ static void adapter_message(struct hpi_
        case HPI_ADAPTER_CLOSE:
                adapter_close(phm, phr);
                break;
+       case HPI_ADAPTER_DELETE:
+               HPIMSGX__cleanup(phm->adapter_index, h_owner);
+               {
+                       struct hpi_message hm;
+                       struct hpi_response hr;
+                       hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
+                               HPI_ADAPTER_CLOSE);
+                       hm.adapter_index = phm->adapter_index;
+                       hw_entry_point(&hm, &hr);
+               }
+               hw_entry_point(phm, phr);
+               break;
        default:
                hw_entry_point(phm, phr);
                break;
@@@ -722,7 -717,7 +717,7 @@@ static u16 HPIMSGX__init(struct hpi_mes
                return phr->error;
        }
        if (hr.error == 0) {
 -              /* the adapter was created succesfully
 +              /* the adapter was created successfully
                   save the mapping for future use */
                hpi_entry_points[hr.u.s.adapter_index] = entry_point_func;
                /* prepare adapter (pre-open streams etc.) */
@@@ -44,10 -44,10 +44,10 @@@ static struct snd_pcm_hardware snd_vort
        .channels_min = 1,
        .channels_max = 2,
        .buffer_bytes_max = 0x10000,
 -      .period_bytes_min = 0x1,
 +      .period_bytes_min = 0x20,
        .period_bytes_max = 0x1000,
        .periods_min = 2,
 -      .periods_max = 32,
 +      .periods_max = 1024,
  };
  
  #ifndef CHIP_AU8820
@@@ -140,9 -140,6 +140,9 @@@ static int snd_vortex_pcm_open(struct s
                                        SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0)
                return err;
  
 +      snd_pcm_hw_constraint_step(runtime, 0,
 +                                      SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 64);
 +
        if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
  #ifndef CHIP_AU8820
                if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) {
@@@ -426,11 -423,11 +426,11 @@@ static struct snd_pcm_ops snd_vortex_pl
  */
  
  static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = {
-       "AU88x0 ADB",
-       "AU88x0 SPDIF",
-       "AU88x0 A3D",
-       "AU88x0 WT",
-       "AU88x0 I2S",
+       CARD_NAME " ADB",
+       CARD_NAME " SPDIF",
+       CARD_NAME " A3D",
+       CARD_NAME " WT",
+       CARD_NAME " I2S",
  };
  static char *vortex_pcm_name[VORTEX_PCM_LAST] = {
        "adb",
@@@ -518,7 -515,7 +518,7 @@@ static int __devinit snd_vortex_new_pcm
                return -ENODEV;
  
        /* idx indicates which kind of PCM device. ADB, SPDIF, I2S and A3D share the 
 -       * same dma engine. WT uses it own separate dma engine whcih cant capture. */
 +       * same dma engine. WT uses it own separate dma engine which can't capture. */
        if (idx == VORTEX_PCM_ADB)
                nr_capt = nr;
        else
                          nr_capt, &pcm);
        if (err < 0)
                return err;
-       strcpy(pcm->name, vortex_pcm_name[idx]);
+       snprintf(pcm->name, sizeof(pcm->name),
+               "%s %s", CARD_NAME_SHORT, vortex_pcm_name[idx]);
        chip->pcm[idx] = pcm;
        // This is an evil hack, but it saves a lot of duplicated code.
        VORTEX_PCM_TYPE(pcm) = idx;
diff --combined sound/pci/intel8x0m.c
@@@ -235,8 -235,8 +235,8 @@@ static DEFINE_PCI_DEVICE_TABLE(snd_inte
        { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */
        { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */
        { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */
+       { PCI_VDEVICE(AMD, 0x746e), DEVICE_INTEL },     /* AMD8111 */
  #if 0
-       { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL },     /* AMD8111 */
        { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI },   /* Ali5455 */
  #endif
        { 0, }
@@@ -331,7 -331,7 +331,7 @@@ static int snd_intel8x0m_codec_semaphor
                udelay(10);
        } while (time--);
  
 -      /* access to some forbidden (non existant) ac97 registers will not
 +      /* access to some forbidden (non existent) ac97 registers will not
         * reset the semaphore. So even if you don't get the semaphore, still
         * continue the access. We don't need the semaphore anyway. */
        snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
@@@ -1261,9 -1261,9 +1261,9 @@@ static struct shortname_table 
        { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" },
        { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" },
        { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" },
+       { 0x746e, "AMD AMD8111" },
  #if 0
        { 0x5455, "ALi M5455" },
-       { 0x746d, "AMD AMD8111" },
  #endif
        { 0 },
  };
@@@ -3,12 -3,6 +3,6 @@@
   *
   * Firmware loader
   *
-  * Currently not working for all devices. To be able to use the device
-  * in linux, it is also possible to let the windows driver upload the firmware.
-  * For that, start the computer in windows and reboot.
-  * As long as the device is connected to the power supply, no firmware reload
-  * needs to be performed.
-  *
   * Author:    Torsten Schenk <torsten.schenk@zoho.com>
   * Created:   Jan 01, 2011
   * Version:   0.3.0
@@@ -21,6 -15,7 +15,7 @@@
   */
  
  #include <linux/firmware.h>
+ #include <linux/bitrev.h>
  
  #include "firmware.h"
  #include "chip.h"
@@@ -33,32 -28,6 +28,6 @@@ enum 
        FPGA_BUFSIZE = 512, FPGA_EP = 2
  };
  
- static const u8 BIT_REVERSE_TABLE[256] = {
-       0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50,
-       0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8,
-       0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04,
-       0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4,
-       0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c,
-       0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82,
-       0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32,
-       0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
-       0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46,
-       0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6,
-       0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e,
-       0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
-       0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71,
-       0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99,
-       0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25,
-       0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
-       0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d,
-       0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3,
-       0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b,
-       0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb,
-       0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67,
-       0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f,
-       0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f,
-       0xbf, 0x7f, 0xff };
  /*
   * wMaxPacketSize of pcm endpoints.
   * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c
@@@ -72,11 -41,15 +41,15 @@@ static const u8 ep_w_max_packet_size[] 
        0x94, 0x01, 0x5c, 0x02  /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */
  };
  
+ static const u8 known_fw_versions[][4] = {
+       { 0x03, 0x01, 0x0b, 0x00 }
+ };
  struct ihex_record {
        u16 address;
        u8 len;
        u8 data[256];
 -      char error; /* true if an error occured parsing this record */
 +      char error; /* true if an error occurred parsing this record */
  
        u8 max_len; /* maximum record length in whole ihex */
  
@@@ -107,7 -80,7 +80,7 @@@ static u8 usb6fire_fw_ihex_hex(const u
  
  /*
   * returns true if record is available, false otherwise.
 - * iff an error occured, false will be returned and record->error will be true.
 + * iff an error occurred, false will be returned and record->error will be true.
   */
  static bool usb6fire_fw_ihex_next_record(struct ihex_record *record)
  {
@@@ -340,7 -313,7 +313,7 @@@ static int usb6fire_fw_fpga_upload
  
        while (c != end) {
                for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++)
-                       buffer[i] = BIT_REVERSE_TABLE[(u8) *c];
+                       buffer[i] = byte_rev_table[(u8) *c];
  
                ret = usb6fire_fw_fpga_write(device, buffer, i);
                if (ret < 0) {
        return 0;
  }
  
+ /* check, if the firmware version the devices has currently loaded
+  * is known by this driver. 'version' needs to have 4 bytes version
+  * info data. */
+ static int usb6fire_fw_check(u8 *version)
+ {
+       int i;
+       for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++)
+               if (!memcmp(version, known_fw_versions + i, 4))
+                       return 0;
+       snd_printk(KERN_ERR PREFIX "invalid fimware version in device: "
+                       "%02x %02x %02x %02x. "
+                       "please reconnect to power. if this failure "
+                       "still happens, check your firmware installation.",
+                       version[0], version[1], version[2], version[3]);
+       return -EINVAL;
+ }
  int usb6fire_fw_init(struct usb_interface *intf)
  {
        int i;
                                "firmware state.\n");
                return ret;
        }
-       if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55
-                       || buffer[4] != 0x03 || buffer[5] != 0x01 || buffer[7]
-                       != 0x00) {
+       if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) {
                snd_printk(KERN_ERR PREFIX "unknown device firmware state "
                                "received from device: ");
                for (i = 0; i < 8; i++)
                return -EIO;
        }
        /* do we need fpga loader ezusb firmware? */
-       if (buffer[3] == 0x01 && buffer[6] == 0x19) {
+       if (buffer[3] == 0x01) {
                ret = usb6fire_fw_ezusb_upload(intf,
                                "6fire/dmx6firel2.ihx", 0, NULL, 0);
                if (ret < 0)
                return FW_NOT_READY;
        }
        /* do we need fpga firmware and application ezusb firmware? */
-       else if (buffer[3] == 0x02 && buffer[6] == 0x0b) {
+       else if (buffer[3] == 0x02) {
+               ret = usb6fire_fw_check(buffer + 4);
+               if (ret < 0)
+                       return ret;
                ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin");
                if (ret < 0)
                        return ret;
                return FW_NOT_READY;
        }
        /* all fw loaded? */
-       else if (buffer[3] == 0x03 && buffer[6] == 0x0b)
-               return 0;
+       else if (buffer[3] == 0x03)
+               return usb6fire_fw_check(buffer + 4);
        /* unknown data? */
        else {
                snd_printk(KERN_ERR PREFIX "unknown device firmware state "
diff --combined sound/usb/format.c
@@@ -30,6 -30,7 +30,7 @@@
  #include "helper.h"
  #include "debug.h"
  #include "clock.h"
+ #include "format.h"
  
  /*
   * parse the audio format type I descriptor
@@@ -176,11 -177,9 +177,11 @@@ static int parse_audio_format_rates_v1(
                        if (!rate)
                                continue;
                        /* C-Media CM6501 mislabels its 96 kHz altsetting */
 +                      /* Terratec Aureon 7.1 USB C-Media 6206, too */
                        if (rate == 48000 && nr_rates == 1 &&
                            (chip->usb_id == USB_ID(0x0d8c, 0x0201) ||
 -                           chip->usb_id == USB_ID(0x0d8c, 0x0102)) &&
 +                           chip->usb_id == USB_ID(0x0d8c, 0x0102) ||
 +                           chip->usb_id == USB_ID(0x0ccd, 0x00b1)) &&
                            fp->altsetting == 5 && fp->maxpacksize == 392)
                                rate = 96000;
                        /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */
diff --combined sound/usb/mixer.c
@@@ -1097,11 -1097,13 +1097,13 @@@ static void build_feature_ctl(struct mi
                append_ctl_name(kctl, control == UAC_FU_MUTE ?
                                " Switch" : " Volume");
                if (control == UAC_FU_VOLUME) {
-                       kctl->tlv.c = mixer_vol_tlv;
-                       kctl->vd[0].access |= 
-                               SNDRV_CTL_ELEM_ACCESS_TLV_READ |
-                               SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
                        check_mapped_dB(map, cval);
+                       if (cval->dBmin < cval->dBmax) {
+                               kctl->tlv.c = mixer_vol_tlv;
+                               kctl->vd[0].access |= 
+                                       SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+                                       SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
+                       }
                }
                break;
  
  /*
   * parse a feature unit
   *
 - * most of controlls are defined here.
 + * most of controls are defined here.
   */
  static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr)
  {
diff --combined sound/usb/quirks.c
@@@ -266,7 -266,7 +266,7 @@@ static int create_uaxx_quirk(struct snd
   * audio-interface quirks
   *
   * returns zero if no standard audio/MIDI parsing is needed.
 - * returns a postive value if standard audio/midi interfaces are parsed
 + * returns a positive value if standard audio/midi interfaces are parsed
   * after this.
   * returns a negative value at error.
   */
@@@ -533,13 -533,13 +533,14 @@@ int snd_usb_apply_boot_quirk(struct usb
  
        case USB_ID(0x0d8c, 0x0102):
                /* C-Media CM6206 / CM106-Like Sound Device */
 +      case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
                return snd_usb_cm6206_boot_quirk(dev);
  
        case USB_ID(0x133e, 0x0815):
                /* Access Music VirusTI Desktop */
                return snd_usb_accessmusic_boot_quirk(dev);
  
+       case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */
        case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
        case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
                return snd_usb_nativeinstruments_boot_quirk(dev);