fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / Documentation / sound / alsa / DocBook / writing-an-alsa-driver.tmpl
index 63a46fd..ccd0a95 100644 (file)
@@ -18,8 +18,8 @@
       </affiliation>
      </author>
 
-     <date>Mar. 6, 2004</date>
-     <edition>0.3.1</edition>
+     <date>November 17, 2005</date>
+     <edition>0.3.6</edition>
 
     <abstract>
       <para>
@@ -30,7 +30,7 @@
 
     <legalnotice>
     <para>
-    Copyright (c) 2002-2004  Takashi Iwai <email>tiwai@suse.de</email>
+    Copyright (c) 2002-2005  Takashi Iwai <email>tiwai@suse.de</email>
     </para>
 
     <para>
       </para>
 
       <para>
-        One is the the trees provided as a tarball or via cvs from the
+        One is the trees provided as a tarball or via cvs from the
       ALSA's ftp site, and another is the 2.6 (or later) Linux kernel
-      tree. To synchronize both, the ALSA driver tree is split to
+      tree. To synchronize both, the ALSA driver tree is split into
       two different trees: alsa-kernel and alsa-driver. The former
       contains purely the source codes for the Linux 2.6 (or later)
       tree. This tree is designed only for compilation on 2.6 or
           <listitem><para>create <function>probe()</function> callback.</para></listitem>
           <listitem><para>create <function>remove()</function> callback.</para></listitem>
           <listitem><para>create pci_driver table which contains the three pointers above.</para></listitem>
-          <listitem><para>create <function>init()</function> function just calling <function>pci_module_init()</function> to register the pci_driver table defined above.</para></listitem>
+          <listitem><para>create <function>init()</function> function just calling <function>pci_register_driver()</function> to register the pci_driver table defined above.</para></listitem>
           <listitem><para>create <function>exit()</function> function to call <function>pci_unregister_driver()</function> function.</para></listitem>
         </itemizedlist>
       </para>
   #include <linux/pci.h>
   #include <linux/slab.h>
   #include <sound/core.h>
-  #define SNDRV_GET_ID
   #include <sound/initval.h>
 
-  // module parameters (see "Module Parameters")
+  /* module parameters (see "Module Parameters") */
   static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
   static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
   static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
 
-  // definition of the chip-specific record
-  typedef struct snd_mychip mychip_t;
-  struct snd_mychip {
-          snd_card_t *card;
+  /* definition of the chip-specific record */
+  struct mychip {
+          struct snd_card *card;
           // rest of implementation will be in the section
           // "PCI Resource Managements"
   };
 
-  // this should be go into <sound/sndmagic.h>
-  // (see "Management of Cards and Components")
-  #define mychip_t_magic        0xa15a4501
-
-  // chip-specific destructor
-  // (see "PCI Resource Managements")
-  static int snd_mychip_free(mychip_t *chip)
+  /* chip-specific destructor
+   * (see "PCI Resource Managements")
+   */
+  static int snd_mychip_free(struct mychip *chip)
   {
-          // will be implemented later...
+          .... // will be implemented later...
   }
 
-  // component-destructor
-  // (see "Management of Cards and Components")
-  static int snd_mychip_dev_free(snd_device_t *device)
+  /* component-destructor
+   * (see "Management of Cards and Components")
+   */
+  static int snd_mychip_dev_free(struct snd_device *device)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t,
-                  device->device_data, return -ENXIO);
-          return snd_mychip_free(chip);
+          return snd_mychip_free(device->device_data);
   }
 
-  // chip-specific constructor
-  // (see "Management of Cards and Components")
-  static int __devinit snd_mychip_create(snd_card_t *card,
+  /* chip-specific constructor
+   * (see "Management of Cards and Components")
+   */
+  static int __devinit snd_mychip_create(struct snd_card *card,
                                          struct pci_dev *pci,
-                                         mychip_t **rchip)
+                                         struct mychip **rchip)
   {
-          mychip_t *chip;
+          struct mychip *chip;
           int err;
-          static snd_device_ops_t ops = {
+          static struct snd_device_ops ops = {
                  .dev_free = snd_mychip_dev_free,
           };
 
 
           // check PCI availability here
           // (see "PCI Resource Managements")
+          ....
 
-          // allocate a chip-specific data with magic-alloc
-          chip = snd_magic_kcalloc(mychip_t, 0, GFP_KERNEL);
+          /* allocate a chip-specific data with zero filled */
+          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
           if (chip == NULL)
                   return -ENOMEM;
 
 
           // rest of initialization here; will be implemented
           // later, see "PCI Resource Managements"
+          ....
 
           if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
                                     chip, &ops)) < 0) {
                   snd_mychip_free(chip);
                   return err;
           }
+
+          snd_card_set_dev(card, &pci->dev);
+
           *rchip = chip;
           return 0;
   }
 
-  // constructor -- see "Constructor" sub-section
+  /* constructor -- see "Constructor" sub-section */
   static int __devinit snd_mychip_probe(struct pci_dev *pci,
                                const struct pci_device_id *pci_id)
   {
           static int dev;
-          snd_card_t *card;
-          mychip_t *chip;
+          struct snd_card *card;
+          struct mychip *chip;
           int err;
 
-          // (1)
+          /* (1) */
           if (dev >= SNDRV_CARDS)
                   return -ENODEV;
           if (!enable[dev]) {
                   return -ENOENT;
           }
 
-          // (2)
+          /* (2) */
           card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
           if (card == NULL)
                   return -ENOMEM;
 
-          // (3)
+          /* (3) */
           if ((err = snd_mychip_create(card, pci, &chip)) < 0) {
                   snd_card_free(card);
                   return err;
           }
 
-          // (4)
+          /* (4) */
           strcpy(card->driver, "My Chip");
           strcpy(card->shortname, "My Own Chip 123");
           sprintf(card->longname, "%s at 0x%lx irq %i",
                   card->shortname, chip->ioport, chip->irq);
 
-          // (5)
-          // implemented later
+          /* (5) */
+          .... // implemented later
 
-          // (6)
+          /* (6) */
           if ((err = snd_card_register(card)) < 0) {
                   snd_card_free(card);
                   return err;
           }
 
-          // (7)
-          pci_set_drvdata(pci, chip);
+          /* (7) */
+          pci_set_drvdata(pci, card);
           dev++;
           return 0;
   }
 
-  // destructor -- see "Destructor" sub-section
+  /* destructor -- see "Destructor" sub-section */
   static void __devexit snd_mychip_remove(struct pci_dev *pci)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t,
-                                     pci_get_drvdata(pci), return);
-          if (chip)
-                  snd_card_free(chip->card);
+          snd_card_free(pci_get_drvdata(pci));
           pci_set_drvdata(pci, NULL);
   }
 ]]>
           <informalexample>
             <programlisting>
 <![CDATA[
-  snd_card_t *card;
+  struct snd_card *card;
   ....
   card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
 ]]>
           <informalexample>
             <programlisting>
 <![CDATA[
-  mychip_t *chip;
+  struct mychip *chip;
   ....
   if ((err = snd_mychip_create(card, pci, &chip)) < 0) {
           snd_card_free(card);
           <informalexample>
             <programlisting>
 <![CDATA[
-        pci_set_drvdata(pci, chip);
+        pci_set_drvdata(pci, card);
         dev++;
         return 0;
 ]]>
             </programlisting>
           </informalexample>
 
-          In the above, the chip record is stored. This pointer is
+          In the above, the card record is stored. This pointer is
         referred in the remove callback and power-management
         callbacks, too. 
-       If the card doesn't support the suspend/resume, you can store
-        the card pointer instead of the chip pointer, so that
-        <function>snd_card_free</function> can be called directly
-        without cast in the remove callback.  But anyway, be sure
-        which pointer is used.
         </para>
       </section>
     </section>
 <![CDATA[
   static void __devexit snd_mychip_remove(struct pci_dev *pci)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t,
-                                    pci_get_drvdata(pci), return);
-          if (chip)
-                  snd_card_free(chip->card);
+          snd_card_free(pci_get_drvdata(pci));
           pci_set_drvdata(pci, NULL);
   }
 ]]>
           </programlisting>
         </informalexample>
 
-        The above code assumes that the chip is allocated
-       with snd_magic stuff and
-      has the field to hold the card pointer (see <link
-      linkend="card-management"><citetitle>the next
-      section</citetitle></link>). 
+        The above code assumes that the card pointer is set to the PCI
+       driver data.
       </para>
     </section>
 
   #include <linux/pci.h>
   #include <linux/slab.h>
   #include <sound/core.h>
-  #define SNDRV_GET_ID
   #include <sound/initval.h>
 ]]>
           </programlisting>
         </informalexample>
 
-       where the last twos are necessary only when module options are
+       where the last one is necessary only when module options are
       defined in the source file.  If the codes are split to several
       files, the file without module options don't need them.
       </para>
       </para>
 
       <para>
-      The ALSA interfaces like PCM or control API are define in other
+      The ALSA interfaces like PCM or control API are defined in other
       header files as <filename>&lt;sound/xxx.h&gt;</filename>.
       They have to be included after
       <filename>&lt;sound/core.h&gt;</filename>.
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_card_t *card;
+  struct snd_card *card;
   card = snd_card_new(index, id, module, extra_size);
 ]]>
           </programlisting>
       <para>
         After the card is created, you can attach the components
       (devices) to the card instance. On ALSA driver, a component is
-      represented as a <type>snd_device_t</type> object.
+      represented as a struct <structname>snd_device</structname> object.
       A component can be a PCM instance, a control interface, a raw
       MIDI interface, etc.  Each of such instances has one component
       entry.
       The chip-specific information, e.g. the i/o port address, its
       resource pointer, or the irq number, is stored in the
       chip-specific record.
-      Usually, the chip-specific record is typedef'ed as
-      <type>xxx_t</type> like the following:
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  typedef struct snd_mychip mychip_t;
-  struct snd_mychip {
+  struct mychip {
           ....
   };
 ]]>
         </informalexample>
       </para>
 
-      <para>
-        You might have objections against such a typedef, but this
-      typedef is necessary if you use a <quote>magic-cast</quote>
-      (explained <link
-      linkend="card-management-chip-what-advantage"><citetitle>later</citetitle></link>). 
-      </para>
-
       <para>
         In general, there are two ways to allocate the chip record.
       </para>
           <informalexample>
             <programlisting>
 <![CDATA[
-  card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(mychip_t));
+  card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct mychip));
 ]]>
             </programlisting>
           </informalexample>
 
-          whether <type>mychip_t</type> is the type of the chip record.
+          whether struct <structname>mychip</structname> is the type of the chip record.
         </para>
 
         <para>
           <informalexample>
             <programlisting>
 <![CDATA[
-  mychip_t *chip = (mychip_t *)card->private_data;
+  struct mychip *chip = card->private_data;
 ]]>
             </programlisting>
           </informalexample>
 
-          With this method, you don't have to allocate twice. But you
-        cannot use <quote>magic-cast</quote> for this record pointer,
-        instead. 
+          With this method, you don't have to allocate twice.
+          The record is released together with the card instance.
         </para>
       </section>
 
           After allocating a card instance via
           <function>snd_card_new()</function> (with
           <constant>NULL</constant> on the 4th arg), call
-          <function>snd_magic_kcalloc()</function>. 
+          <function>kzalloc()</function>. 
 
           <informalexample>
             <programlisting>
 <![CDATA[
-  snd_card_t *card;
-  mychip_t *chip;
+  struct snd_card *card;
+  struct mychip *chip;
   card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
   .....
-  chip = snd_magic_kcalloc(mychip_t, 0, GFP_KERNEL);
+  chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 ]]>
             </programlisting>
           </informalexample>
-
-          Once when the record is allocated via snd_magic stuff, you
-        can use <quote>magic-cast</quote> for the void pointer. 
         </para>
 
         <para>
           <informalexample>
             <programlisting>
 <![CDATA[
-  struct snd_mychip {
-          snd_card_t *card;
+  struct mychip {
+          struct snd_card *card;
           ....
   };
 ]]>
           </informalexample>
         </para>
 
-        <para>
-          Also, you need to define a magic-value for <type>mychip_t</type>.
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  #define mychip_t_magic        0xa15a4501
-]]>
-            </programlisting>
-          </informalexample>
-       (the detail will be described in the
-       <link linkend="card-management-chip-what-advantage"><citetitle>
-       next</citetitle></link> subsection).
-       </para>
-
         <para>
           Next, initialize the fields, and register this chip
           record as a low-level device with a specified
           <informalexample>
             <programlisting>
 <![CDATA[
-  static snd_device_ops_t ops = {
+  static struct snd_device_ops ops = {
           .dev_free =        snd_mychip_dev_free,
   };
   ....
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_mychip_dev_free(snd_device_t *device)
+  static int snd_mychip_dev_free(struct snd_device *device)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t, device->device_data,
-                                          return -ENXIO);
-          return snd_mychip_free(chip);
+          return snd_mychip_free(device->device_data);
   }
 ]]>
             </programlisting>
           where <function>snd_mychip_free()</function> is the real destructor.
         </para>
       </section>
-
-      <section id="card-management-chip-what-advantage">
-        <title>Not a magic but a logic</title>
-
-        <para>Now, you might have a question: What is the advantage of the
-        second method?  Obviously, it looks far more complicated.</para> 
-        <para>
-          As I wrote many times, the second method allows a
-        <quote>magic-cast</quote> for <type>mychip_t</type>. If you
-        have a void pointer (such as
-        pcm-&gt;private_data), the pointer type
-        is unknown at the compile time, and you cannot know even if a
-        wrong pointer type is passed. The compiler would accept
-        it. The magic-cast checks the pointer type at the runtime (and
-        whether it's a null pointer, too). Hence, the cast will be
-        much safer and good for debugging. 
-        </para>
-
-       <para>
-       As you have already seen, allocation with a magic-header can
-       be done via <function>snd_magic_kmalloc()</function> or
-       <function>snd_magic_kcalloc()</function>.
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  mychip_t *chip;
-  chip = snd_magic_kmalloc(mychip_t, 0, GFP_KERNEL);
-  chip = snd_magic_kcalloc(mychip_t, 0, GFP_KERNEL);
-]]>
-            </programlisting>
-          </informalexample>
-
-        The difference of these two functions is whether the area is
-       zero-cleared (<function>kcalloc</function>) or not
-       (<function>kmalloc</function>).
-       </para>
-
-       <para>
-       The first argument of the allocator is the type of the
-       record.  The magic-constant has to be defined for this type
-       beforehand.  In this case, we'll need to define
-       <constant>mychip_t_magic</constant>, for example, as already
-       seen,
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  #define mychip_t_magic        0xa15a4501
-]]>
-            </programlisting>
-          </informalexample>
-
-        The value is arbitrary but should be unique.
-        This is usually defined in
-        <filename>&lt;include/sndmagic.h&gt;</filename> or
-        <filename>&lt;include/amagic.h&gt;</filename> for alsa-driver tree,
-        but you may define it locally in the code at the early
-        development stage, since changing
-        <filename>sndmagic.h</filename> will lead to the recompilation
-        of the whole driver codes.
-        </para>
-
-       <para>
-       The second argument is the extra-data length.  It is usually
-        zero.  The third argument is the flags to be passed to kernel
-        memory allocator, <constant>GFP_XXX</constant>.  Normally,
-        <constant>GFP_KERNEL</constant> is passed.
-       </para>
-
-        <para>
-          For casting a pointer, use
-          <function>snd_magic_cast()</function> macro:
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  mychip_t *chip = snd_magic_cast(mychip_t, source_pointer, action);
-]]>
-            </programlisting>
-          </informalexample>
-
-        where <parameter>source_pointer</parameter> is the pointer to
-        be casted (e.g. pcm-&gt;private_data), and
-        <parameter>action</parameter> is the action to do if the cast
-        fails (e.g. return <constant>-EINVAL</constant>). 
-        </para>
-
-       <para>
-       For releasing the magic-allocated data, you need to call
-        <function>snd_magic_kfree()</function> function instead of
-        <function>kfree()</function>.
-
-          <informalexample>
-            <programlisting>
-<![CDATA[
-  snd_magic_kfree(chip);
-]]>
-            </programlisting>
-          </informalexample>
-       </para>
-
-       <para>
-       If you call <function>kfree()</function> for the
-       magic-allocated value, it will lead to memory leaks.
-       When the ALSA drivers are compiled with
-       <constant>CONFIG_SND_DEBUG_MEMORY</constant> kernel config (or
-       configured with <option>--with-debug=full</option>), the
-       non-matching free will be checked and you'll see warning
-       messages.
-       </para>
-
-        <para>
-          If you are 100% sure that your code is bug-free, you can
-          compile the driver without
-          <constant>CONFIG_SND_DEBUG_MEMORY</constant> kernel config,
-          so that the magic-allocator and the magic-cast will be
-          replaced to the normal kmalloc and cast.
-        </para>
-      </section>
     </section>
 
     <section id="card-management-registration">
 
       <para>
       For a device which allows hotplugging, you can use
-      <function>snd_card_free_in_thread</function>.  This one will
-      postpone the destruction and wait in a kernel-thread until all
-      devices are closed.
+      <function>snd_card_free_when_closed</function>.  This one will
+      postpone the destruction until all devices are closed.
       </para>
 
     </section>
           <title>PCI Resource Managements Example</title>
           <programlisting>
 <![CDATA[
-  struct snd_mychip {
-          snd_card_t *card;
+  struct mychip {
+          struct snd_card *card;
           struct pci_dev *pci;
 
           unsigned long port;
-          struct resource *res_port;
-
           int irq;
   };
 
-  static int snd_mychip_free(mychip_t *chip)
+  static int snd_mychip_free(struct mychip *chip)
   {
-          // disable hardware here if any
-          // (not implemented in this document)
+          /* disable hardware here if any */
+          .... // (not implemented in this document)
 
-          // release the i/o port
-          if (chip->res_port) {
-                  release_resource(chip->res_port);
-                  kfree_nocheck(chip->res_port);
-          }
-          // release the irq
+          /* release the irq */
           if (chip->irq >= 0)
-                  free_irq(chip->irq, (void *)chip);
-          // release the data
-          snd_magic_kfree(chip);
+                  free_irq(chip->irq, chip);
+          /* release the i/o ports & memory */
+          pci_release_regions(chip->pci);
+          /* disable the PCI entry */
+          pci_disable_device(chip->pci);
+          /* release the data */
+          kfree(chip);
           return 0;
   }
 
-  // chip-specific constructor
-  static int __devinit snd_mychip_create(snd_card_t *card,
+  /* chip-specific constructor */
+  static int __devinit snd_mychip_create(struct snd_card *card,
                                          struct pci_dev *pci,
-                                         mychip_t **rchip)
+                                         struct mychip **rchip)
   {
-          mychip_t *chip;
+          struct mychip *chip;
           int err;
-          static snd_device_ops_t ops = {
+          static struct snd_device_ops ops = {
                  .dev_free = snd_mychip_dev_free,
           };
 
           *rchip = NULL;
 
-          // check PCI availability (28bit DMA)
+          /* initialize the PCI entry */
           if ((err = pci_enable_device(pci)) < 0)
                   return err;
-          if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
-              pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
+          /* check PCI availability (28bit DMA) */
+          if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
+              pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
                   printk(KERN_ERR "error to set 28bit mask DMA\n");
+                  pci_disable_device(pci);
                   return -ENXIO;
           }
 
-          chip = snd_magic_kcalloc(mychip_t, 0, GFP_KERNEL);
-          if (chip == NULL)
+          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+          if (chip == NULL) {
+                  pci_disable_device(pci);
                   return -ENOMEM;
+          }
 
-          // initialize the stuff
+          /* initialize the stuff */
           chip->card = card;
           chip->pci = pci;
           chip->irq = -1;
 
-          // (1) PCI resource allocation
-          chip->port = pci_resource_start(pci, 0);
-          if ((chip->res_port = request_region(chip->port, 8,
-                                                 "My Chip")) == NULL) { 
-                  snd_mychip_free(chip);
-                  printk(KERN_ERR "cannot allocate the port\n");
-                  return -EBUSY;
+          /* (1) PCI resource allocation */
+          if ((err = pci_request_regions(pci, "My Chip")) < 0) {
+                  kfree(chip);
+                  pci_disable_device(pci);
+                  return err;
           }
+          chip->port = pci_resource_start(pci, 0);
           if (request_irq(pci->irq, snd_mychip_interrupt,
-                          SA_INTERRUPT|SA_SHIRQ, "My Chip",
-                          (void *)chip)) {
+                          IRQF_SHARED, "My Chip", chip)) {
+                  printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
                   snd_mychip_free(chip);
-                  printk(KERN_ERR "cannot grab irq\n");
                   return -EBUSY;
           }
           chip->irq = pci->irq;
 
-          // (2) initialization of the chip hardware
-          //     (not implemented in this document)
+          /* (2) initialization of the chip hardware */
+          .... //   (not implemented in this document)
 
           if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
                                     chip, &ops)) < 0) {
                   snd_mychip_free(chip);
                   return err;
           }
+
+          snd_card_set_dev(card, &pci->dev);
+
           *rchip = chip;
           return 0;
   }        
 
-  // PCI IDs
+  /* PCI IDs */
   static struct pci_device_id snd_mychip_ids[] = {
           { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
             PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
   };
   MODULE_DEVICE_TABLE(pci, snd_mychip_ids);
 
-  // pci_driver definition
+  /* pci_driver definition */
   static struct pci_driver driver = {
           .name = "My Own Chip",
           .id_table = snd_mychip_ids,
           .remove = __devexit_p(snd_mychip_remove),
   };
 
-  // initialization of the module
+  /* initialization of the module */
   static int __init alsa_card_mychip_init(void)
   {
-          int err;
-
-          if ((err = pci_module_init(&driver)) < 0) {
-  #ifdef MODULE
-                  printk(KERN_ERR "My chip soundcard not found "
-                                  "or device busy\n");
-  #endif
-                  return err;
-          }
-          return 0;
+          return pci_register_driver(&driver);
   }
 
-  // clean up the module
+  /* clean up the module */
   static void __exit alsa_card_mychip_exit(void)
   {
           pci_unregister_driver(&driver);
         The allocation of PCI resources is done in the
       <function>probe()</function> function, and usually an extra
       <function>xxx_create()</function> function is written for this
-      purpose. 
+      purpose.
       </para>
 
       <para>
       allocating resources. Also, you need to set the proper PCI DMA
       mask to limit the accessed i/o range. In some cases, you might
       need to call <function>pci_set_master()</function> function,
-      too. 
+      too.
       </para>
 
       <para>
 <![CDATA[
   if ((err = pci_enable_device(pci)) < 0)
           return err;
-  if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
-      pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
+  if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
+      pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
           printk(KERN_ERR "error to set 28bit mask DMA\n");
+          pci_disable_device(pci);
           return -ENXIO;
   }
   
       functions. Unlike ALSA ver.0.5.x., there are no helpers for
       that. And these resources must be released in the destructor
       function (see below). Also, on ALSA 0.9.x, you don't need to
-      allocate (pseudo-)DMA for PCI like ALSA 0.5.x. 
+      allocate (pseudo-)DMA for PCI like ALSA 0.5.x.
       </para>
 
       <para>
         Now assume that this PCI device has an I/O port with 8 bytes
-        and an interrupt. Then <type>mychip_t</type> will have the
-        following fields: 
+        and an interrupt. Then struct <structname>mychip</structname> will have the
+        following fields:
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  struct snd_mychip {
-          snd_card_t *card;
+  struct mychip {
+          struct snd_card *card;
 
           unsigned long port;
-          struct resource *res_port;
-
           int irq;
   };
 ]]>
       need to initialize this number as -1 before actual allocation,
       since irq 0 is valid. The port address and its resource pointer
       can be initialized as null by
-      <function>snd_magic_kcalloc()</function> automatically, so you
+      <function>kzalloc()</function> automatically, so you
       don't have to take care of resetting them. 
       </para>
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  chip->port = pci_resource_start(pci, 0);
-  if ((chip->res_port = request_region(chip->port, 8,
-                                       "My Chip")) == NULL) { 
-          printk(KERN_ERR "cannot allocate the port 0x%lx\n",
-                 chip->port);
-          snd_mychip_free(chip);
-          return -EBUSY;
+  if ((err = pci_request_regions(pci, "My Chip")) < 0) { 
+          kfree(chip);
+          pci_disable_device(pci);
+          return err;
   }
+  chip->port = pci_resource_start(pci, 0);
 ]]>
           </programlisting>
         </informalexample>
       </para>
 
       <para>
+        <!-- obsolete -->
         It will reserve the i/o port region of 8 bytes of the given
       PCI device. The returned value, chip-&gt;res_port, is allocated
       via <function>kmalloc()</function> by
           <programlisting>
 <![CDATA[
   if (request_irq(pci->irq, snd_mychip_interrupt,
-                  SA_INTERRUPT|SA_SHIRQ, "My Chip",
-                  (void *)chip)) {
-          snd_mychip_free(chip);
+                  IRQF_DISABLED|IRQF_SHARED, "My Chip", chip)) {
           printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
+          snd_mychip_free(chip);
           return -EBUSY;
   }
   chip->irq = pci->irq;
 
       <para>
       On the PCI bus, the interrupts can be shared. Thus,
-      <constant>SA_SHIRQ</constant> is given as the interrupt flag of
+      <constant>IRQF_SHARED</constant> is given as the interrupt flag of
       <function>request_irq()</function>. 
       </para>
 
   static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
                                           struct pt_regs *regs)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t, dev_id, return);
+          struct mychip *chip = dev_id;
           ....
           return IRQ_HANDLED;
   }
 ]]>
           </programlisting>
         </informalexample>
-
-        Again the magic-cast is used here to get the correct pointer
-      from the second argument. 
       </para>
 
       <para>
 
       <para>
         For releasing the resources, <quote>check-and-release</quote>
-        method is a safer way. For the i/o port, do like this: 
+        method is a safer way. For the interrupt, do like this: 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  if (chip->res_port) {
-          release_resource(chip->res_port);
-          kfree_nocheck(chip->res_port);
-  }
+  if (chip->irq >= 0)
+          free_irq(chip->irq, chip);
 ]]>
           </programlisting>
         </informalexample>
+
+        Since the irq number can start from 0, you should initialize
+        chip-&gt;irq with a negative value (e.g. -1), so that you can
+        check the validity of the irq number as above.
       </para>
 
       <para>
-        As you can see, the i/o resource pointer is also to be freed
-      via <function>kfree_nocheck()</function> after
-      <function>release_resource()</function> is called. You
-      cannot use <function>kfree()</function> here, because on ALSA,
-      <function>kfree()</function> may be a wrapper to its own
-      allocator with the memory debugging. Since the resource pointer
-      is allocated externally outside the ALSA, it must be released
-      via the native
-      <function>kfree()</function>.
-      <function>kfree_nocheck()</function> is used for that; it calls
-      the native <function>kfree()</function> without wrapper. 
+        When you requested I/O ports or memory regions via
+       <function>pci_request_region()</function> or
+       <function>pci_request_regions()</function> like this example,
+       release the resource(s) using the corresponding function,
+       <function>pci_release_region()</function> or
+       <function>pci_release_regions()</function>.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  pci_release_regions(chip->pci);
+]]>
+          </programlisting>
+        </informalexample>
       </para>
 
       <para>
-        For releasing the interrupt, do like this:
+       When you requested manually via <function>request_region()</function>
+       or <function>request_mem_region</function>, you can release it via
+       <function>release_resource()</function>.  Suppose that you keep
+       the resource pointer returned from <function>request_region()</function>
+       in chip-&gt;res_port, the release procedure looks like below:
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  if (chip->irq >= 0)
-          free_irq(chip->irq, (void *)chip);
+  release_and_free_resource(chip->res_port);
 ]]>
           </programlisting>
         </informalexample>
+      </para>
 
+      <para>
+      Don't forget to call <function>pci_disable_device()</function>
+      before all finished.
+      </para>
+
+      <para>
         And finally, release the chip-specific record.
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_magic_kfree(chip);
+  kfree(chip);
 ]]>
           </programlisting>
         </informalexample>
       </para>
 
       <para>
-        The chip instance is freed via
-      <function>snd_magic_kfree()</function>. Please use this function
-      for the object allocated by
-      <function>snd_magic_kmalloc()</function>. If you free it with
-      <function>kfree()</function>, it won't work properly and will
-      result in the memory leak. Also, again, remember that you cannot
+      Again, remember that you cannot
       set <parameter>__devexit</parameter> prefix for this destructor. 
       </para>
 
       When the chip-data is assigned to the card using
       <function>snd_device_new()</function> with
       <constant>SNDRV_DEV_LOWLELVEL</constant> , its destructor is 
-      called at the last.  that is, it is assured that all other
+      called at the last.  That is, it is assured that all other
       components like PCMs and controls have been already released.
       You don't have to call stopping PCMs, etc. explicitly, but just
       stop the hardware in the low-level.
         <informalexample>
           <programlisting>
 <![CDATA[
-  struct snd_mychip {
+  struct mychip {
           ....
           unsigned long iobase_phys;
-          unsigned long iobase_virt;
-          struct resource *res_iobase;
+          void __iomem *iobase_virt;
   };
 ]]>
           </programlisting>
         </informalexample>
 
-        and the allocation would be (assuming its size is 512 bytes):
+        and the allocation would be like below:
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  chip->iobase_phys = pci_resource_start(pci, 0);
-  chip->iobase_virt = (unsigned long)
-                      ioremap_nocache(chip->iobase_phys, 512);
-  if ((chip->res_port = request_mem_region(chip->iobase_phys, 512,
-                                           "My Chip")) == NULL) {
-          printk(KERN_ERR "cannot allocate the memory region\n");
-          snd_mychip_free(chip);
-          return -EBUSY;
+  if ((err = pci_request_regions(pci, "My Chip")) < 0) {
+          kfree(chip);
+          return err;
   }
+  chip->iobase_phys = pci_resource_start(pci, 0);
+  chip->iobase_virt = ioremap_nocache(chip->iobase_phys,
+                                      pci_resource_len(pci, 0));
 ]]>
           </programlisting>
         </informalexample>
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int snd_mychip_free(mychip_t *chip)
+  static int snd_mychip_free(struct mychip *chip)
   {
           ....
           if (chip->iobase_virt)
-                  iounmap((void *)chip->iobase_virt);
-          if (chip->res_iobase) {
-                  release_resource(chip->res_iobase);
-                  kfree_nocheck(chip->res_iobase);
-          }
+                  iounmap(chip->iobase_virt);
+          ....
+          pci_release_regions(chip->pci);
           ....
   }
 ]]>
 
     </section>
 
+    <section id="pci-resource-device-struct">
+      <title>Registration of Device Struct</title>
+      <para>
+       At some point, typically after calling <function>snd_device_new()</function>,
+       you need to register the struct <structname>device</structname> of the chip
+       you're handling for udev and co.  ALSA provides a macro for compatibility with
+       older kernels.  Simply call like the following:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_card_set_dev(card, &pci->dev);
+]]>
+          </programlisting>
+        </informalexample>
+       so that it stores the PCI's device pointer to the card.  This will be
+       referred by ALSA core functions later when the devices are registered.
+      </para>
+      <para>
+       In the case of non-PCI, pass the proper device struct pointer of the BUS
+       instead.  (In the case of legacy ISA without PnP, you don't have to do
+       anything.)
+      </para>
+    </section>
+
     <section id="pci-resource-entries">
       <title>PCI Entries</title>
       <para>
 <![CDATA[
   static int __init alsa_card_mychip_init(void)
   {
-          int err;
-
-          if ((err = pci_module_init(&driver)) < 0) {
-  #ifdef MODULE
-                  printk(KERN_ERR "My chip soundcard not found"
-                                  " or device busy\n");
-  #endif
-                  return err;
-          }
-          return 0;
+          return pci_register_driver(&driver);
   }
 
   static void __exit alsa_card_mychip_exit(void)
   #include <sound/pcm.h>
   ....
 
-  #define chip_t mychip_t
-  ....
-
   /* hardware definition */
-  static snd_pcm_hardware_t snd_mychip_playback_hw = {
+  static struct snd_pcm_hardware snd_mychip_playback_hw = {
           .info = (SNDRV_PCM_INFO_MMAP |
                    SNDRV_PCM_INFO_INTERLEAVED |
                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
   };
 
   /* hardware definition */
-  static snd_pcm_hardware_t snd_mychip_capture_hw = {
+  static struct snd_pcm_hardware snd_mychip_capture_hw = {
           .info = (SNDRV_PCM_INFO_MMAP |
                    SNDRV_PCM_INFO_INTERLEAVED |
                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
   };
 
   /* open callback */
-  static int snd_mychip_playback_open(snd_pcm_substream_t *substream)
+  static int snd_mychip_playback_open(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
 
           runtime->hw = snd_mychip_playback_hw;
           // more hardware-initialization will be done here
   }
 
   /* close callback */
-  static int snd_mychip_playback_close(snd_pcm_substream_t *substream)
+  static int snd_mychip_playback_close(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
+          struct mychip *chip = snd_pcm_substream_chip(substream);
           // the hardware-specific codes will be here
           return 0;
 
   }
 
   /* open callback */
-  static int snd_mychip_capture_open(snd_pcm_substream_t *substream)
+  static int snd_mychip_capture_open(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
 
           runtime->hw = snd_mychip_capture_hw;
           // more hardware-initialization will be done here
   }
 
   /* close callback */
-  static int snd_mychip_capture_close(snd_pcm_substream_t *substream)
+  static int snd_mychip_capture_close(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
+          struct mychip *chip = snd_pcm_substream_chip(substream);
           // the hardware-specific codes will be here
           return 0;
 
   }
 
   /* hw_params callback */
-  static int snd_mychip_pcm_hw_params(snd_pcm_substream_t *substream,
-                               snd_pcm_hw_params_t * hw_params)
+  static int snd_mychip_pcm_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *hw_params)
   {
           return snd_pcm_lib_malloc_pages(substream,
                                      params_buffer_bytes(hw_params));
   }
 
   /* hw_free callback */
-  static int snd_mychip_pcm_hw_free(snd_pcm_substream_t *substream)
+  static int snd_mychip_pcm_hw_free(struct snd_pcm_substream *substream)
   {
           return snd_pcm_lib_free_pages(substream);
   }
 
   /* prepare callback */
-  static int snd_mychip_pcm_prepare(snd_pcm_substream_t *substream)
+  static int snd_mychip_pcm_prepare(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
 
-          // set up the hardware with the current configuration
-          // for example...
+          /* set up the hardware with the current configuration
+           * for example...
+           */
           mychip_set_sample_format(chip, runtime->format);
           mychip_set_sample_rate(chip, runtime->rate);
           mychip_set_channels(chip, runtime->channels);
-          mychip_set_dma_setup(chip, runtime->dma_area,
+          mychip_set_dma_setup(chip, runtime->dma_addr,
                                chip->buffer_size,
                                chip->period_size);
           return 0;
   }
 
   /* trigger callback */
-  static int snd_mychip_pcm_trigger(snd_pcm_substream_t *substream,
+  static int snd_mychip_pcm_trigger(struct snd_pcm_substream *substream,
                                     int cmd)
   {
           switch (cmd) {
 
   /* pointer callback */
   static snd_pcm_uframes_t
-  snd_mychip_pcm_pointer(snd_pcm_substream_t *substream)
+  snd_mychip_pcm_pointer(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
+          struct mychip *chip = snd_pcm_substream_chip(substream);
           unsigned int current_ptr;
 
-          // get the current hardware pointer
+          /* get the current hardware pointer */
           current_ptr = mychip_get_hw_pointer(chip);
           return current_ptr;
   }
 
   /* operators */
-  static snd_pcm_ops_t snd_mychip_playback_ops = {
+  static struct snd_pcm_ops snd_mychip_playback_ops = {
           .open =        snd_mychip_playback_open,
           .close =       snd_mychip_playback_close,
           .ioctl =       snd_pcm_lib_ioctl,
   };
 
   /* operators */
-  static snd_pcm_ops_t snd_mychip_capture_ops = {
+  static struct snd_pcm_ops snd_mychip_capture_ops = {
           .open =        snd_mychip_capture_open,
           .close =       snd_mychip_capture_close,
           .ioctl =       snd_pcm_lib_ioctl,
    */
 
   /* create a pcm device */
-  static int __devinit snd_mychip_new_pcm(mychip_t *chip)
+  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
   {
-          snd_pcm_t *pcm;
+          struct snd_pcm *pcm;
           int err;
 
           if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1,
           snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
                           &snd_mychip_capture_ops);
           /* pre-allocation of buffers */
+          /* NOTE: this may fail */
           snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                                 snd_dma_pci_data(chip->pci),
                                                 64*1024, 64*1024);
     <section id="pcm-interface-constructor">
       <title>Constructor</title>
       <para>
-        A pcm instance is allocated <function>snd_pcm_new()</function>
+        A pcm instance is allocated by <function>snd_pcm_new()</function>
       function. It would be better to create a constructor for pcm,
       namely, 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int __devinit snd_mychip_new_pcm(mychip_t *chip)
+  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
   {
-          snd_pcm_t *pcm;
+          struct snd_pcm *pcm;
           int err;
 
           if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1,
       specify more numbers, but they must be handled properly in
       open/close, etc. callbacks.  When you need to know which
       substream you are referring to, then it can be obtained from
-      <type>snd_pcm_substream_t</type> data passed to each callback
+      struct <structname>snd_pcm_substream</structname> data passed to each callback
       as follows: 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_pcm_substream_t *substream;
+  struct snd_pcm_substream *substream;
   int index = substream->number;
 ]]>
           </programlisting>
         <informalexample>
           <programlisting>
 <![CDATA[
-  static snd_pcm_ops_t snd_mychip_playback_ops = {
+  static struct snd_pcm_ops snd_mychip_playback_ops = {
           .open =        snd_mychip_pcm_open,
           .close =       snd_mychip_pcm_close,
           .ioctl =       snd_pcm_lib_ioctl,
           <title>PCM Instance with a Destructor</title>
           <programlisting>
 <![CDATA[
-  static void mychip_pcm_free(snd_pcm_t *pcm)
+  static void mychip_pcm_free(struct snd_pcm *pcm)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t,
-                                    pcm->private_data, return);
-          // free your own data
+          struct mychip *chip = snd_pcm_chip(pcm);
+          /* free your own data */
           kfree(chip->my_private_pcm_data);
-          // do what you like else...
+          // do what you like else
+          ....
   }
 
-  static int __devinit snd_mychip_new_pcm(mychip_t *chip)
+  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
   {
-          snd_pcm_t *pcm;
+          struct snd_pcm *pcm;
           ....
-          // allocate your own data
+          /* allocate your own data */
           chip->my_private_pcm_data = kmalloc(...);
-          // set the destructor
+          /* set the destructor */
           pcm->private_data = chip;
           pcm->private_free = mychip_pcm_free;
           ....
 <![CDATA[
 struct _snd_pcm_runtime {
        /* -- Status -- */
-       snd_pcm_substream_t *trigger_master;
+       struct snd_pcm_substream *trigger_master;
        snd_timestamp_t trigger_tstamp; /* trigger timestamp */
        int overrange;
        snd_pcm_uframes_t avail_max;
@@ -2327,8 +2166,7 @@ struct _snd_pcm_runtime {
        unsigned int rate_den;
 
        /* -- SW params -- */
-       int tstamp_timespec;            /* use timeval (0) or timespec (1) */
-       snd_pcm_tstamp_t tstamp_mode;   /* mmap timestamp is updated */
+       struct timespec tstamp_mode;    /* mmap timestamp is updated */
        unsigned int period_step;
        unsigned int sleep_min;         /* min ticks to sleep */
        snd_pcm_uframes_t xfer_align;   /* xfer size need to be a multiple */
@@ -2345,8 +2183,8 @@ struct _snd_pcm_runtime {
        snd_pcm_sync_id_t sync;         /* hardware synchronization ID */
 
        /* -- mmap -- */
-       volatile snd_pcm_mmap_status_t *status;
-       volatile snd_pcm_mmap_control_t *control;
+       volatile struct snd_pcm_mmap_status *status;
+       volatile struct snd_pcm_mmap_control *control;
        atomic_t mmap_count;
 
        /* -- locking / scheduling -- */
@@ -2357,15 +2195,15 @@ struct _snd_pcm_runtime {
 
        /* -- private section -- */
        void *private_data;
-       void (*private_free)(snd_pcm_runtime_t *runtime);
+       void (*private_free)(struct snd_pcm_runtime *runtime);
 
        /* -- hardware description -- */
-       snd_pcm_hardware_t hw;
-       snd_pcm_hw_constraints_t hw_constraints;
+       struct snd_pcm_hardware hw;
+       struct snd_pcm_hw_constraints hw_constraints;
 
        /* -- interrupt callbacks -- */
-       void (*transfer_ack_begin)(snd_pcm_substream_t *substream);
-       void (*transfer_ack_end)(snd_pcm_substream_t *substream);
+       void (*transfer_ack_begin)(struct snd_pcm_substream *substream);
+       void (*transfer_ack_end)(struct snd_pcm_substream *substream);
 
        /* -- timer -- */
        unsigned int timer_resolution;  /* timer resolution */
@@ -2374,11 +2212,12 @@ struct _snd_pcm_runtime {
        unsigned char *dma_area;        /* DMA area */
        dma_addr_t dma_addr;            /* physical bus address (not accessible from main CPU) */
        size_t dma_bytes;               /* size of DMA area */
-       void *dma_private;              /* private DMA data for the memory allocator */
+
+       struct snd_dma_buffer *dma_buffer_p;    /* allocated buffer */
 
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
        /* -- OSS things -- */
-       snd_pcm_oss_runtime_t oss;
+       struct snd_pcm_oss_runtime oss;
 #endif
 };
 ]]>
@@ -2389,7 +2228,7 @@ struct _snd_pcm_runtime {
        <para>
          For the operators (callbacks) of each sound driver, most of
        these records are supposed to be read-only.  Only the PCM
-       middle-layer changes / updates these info.  The excpetions are
+       middle-layer changes / updates these info.  The exceptions are
        the hardware description (hw), interrupt callbacks
        (transfer_ack_xxx), DMA buffer information, and the private
        data.  Besides, if you use the standard buffer allocation
@@ -2404,7 +2243,7 @@ struct _snd_pcm_runtime {
        <section id="pcm-interface-runtime-hw">
        <title>Hardware Description</title>
        <para>
-         The hardware descriptor (<type>snd_pcm_hardware_t</type>)
+         The hardware descriptor (struct <structname>snd_pcm_hardware</structname>)
        contains the definitions of the fundamental hardware
        configuration.  Above all, you'll need to define this in
        <link linkend="pcm-interface-operators-open-callback"><citetitle>
@@ -2419,9 +2258,9 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct snd_pcm_runtime *runtime = substream->runtime;
           ...
-          runtime->hw = snd_mychip_playback_hw; // common definition
+          runtime->hw = snd_mychip_playback_hw; /* common definition */
           if (chip->model == VERY_OLD_ONE)
                   runtime->hw.channels_max = 1;
 ]]>
@@ -2434,7 +2273,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static snd_pcm_hardware_t snd_mychip_playback_hw = {
+  static struct snd_pcm_hardware snd_mychip_playback_hw = {
           .info = (SNDRV_PCM_INFO_MMAP |
                    SNDRV_PCM_INFO_INTERLEAVED |
                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -2489,9 +2328,14 @@ struct _snd_pcm_runtime {
         <constant>PAUSE</constant> bit means that the pcm supports the
         <quote>pause</quote> operation, while the
         <constant>RESUME</constant> bit means that the pcm supports
-        the <quote>suspend/resume</quote> operation. If these flags
-        are set, the <structfield>trigger</structfield> callback below
-        must handle the corresponding commands. 
+        the full <quote>suspend/resume</quote> operation.
+       If <constant>PAUSE</constant> flag is set,
+       the <structfield>trigger</structfield> callback below
+        must handle the corresponding (pause push/release) commands.
+       The suspend/resume trigger commands can be defined even without
+       <constant>RESUME</constant> flag.  See <link
+       linkend="power-management"><citetitle>
+       Power Management</citetitle></link> section for details.
         </para>
 
        <para>
@@ -2664,7 +2508,7 @@ struct _snd_pcm_runtime {
        <title>Running Status</title>
        <para>
        The running status can be referred via <constant>runtime-&gt;status</constant>.
-       This is the pointer to <type>snd_pcm_mmap_status_t</type>
+       This is the pointer to struct <structname>snd_pcm_mmap_status</structname>
        record.  For example, you can get the current DMA hardware
        pointer via <constant>runtime-&gt;status-&gt;hw_ptr</constant>.
        </para>
@@ -2672,7 +2516,7 @@ struct _snd_pcm_runtime {
        <para>
        The DMA application pointer can be referred via
        <constant>runtime-&gt;control</constant>, which points
-       <type>snd_pcm_mmap_control_t</type> record.
+       struct <structname>snd_pcm_mmap_control</structname> record.
        However, accessing directly to this value is not recommended.
        </para>
        </section>
@@ -2685,17 +2529,20 @@ struct _snd_pcm_runtime {
        done in
        <link linkend="pcm-interface-operators-open-callback"><citetitle>
        the open callback</citetitle></link>.
-        Since it's a void pointer, you should use magic-kmalloc and
-       magic-cast for such an object. 
+       Don't mix this with <constant>pcm-&gt;private_data</constant>.
+       The <constant>pcm-&gt;private_data</constant> usually points the
+       chip instance assigned statically at the creation of PCM, while the 
+       <constant>runtime-&gt;private_data</constant> points a dynamic
+       data created at the PCM open callback.
 
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_open(snd_pcm_substream_t *substream)
+  static int snd_xxx_open(struct snd_pcm_substream *substream)
   {
-          my_pcm_data_t *data;
+          struct my_pcm_data *data;
           ....
-          data = snd_magic_kmalloc(my_pcm_data_t, 0, GFP_KERNEL);
+          data = kmalloc(sizeof(*data), GFP_KERNEL);
           substream->runtime->private_data = data;
           ....
   }
@@ -2735,29 +2582,28 @@ struct _snd_pcm_runtime {
 
       <para>
         The callback function takes at least the argument with
-        <type>snd_pcm_substream_t</type> pointer. For retrieving the
+        <structname>snd_pcm_substream</structname> pointer. For retrieving the
         chip record from the given substream instance, you can use the
         following macro. 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  #define chip_t mychip_t
-
   int xxx() {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
+          struct mychip *chip = snd_pcm_substream_chip(substream);
           ....
   }
 ]]>
           </programlisting>
         </informalexample>
-      </para>
 
-      <para>
-        It's expanded with a magic-cast, so the cast-error is
-      automatically checked. You should define <type>chip_t</type> at
-      the beginning of the code, since this will be referred in many
-      places of pcm and control interfaces. 
+       The macro reads <constant>substream-&gt;private_data</constant>,
+       which is a copy of <constant>pcm-&gt;private_data</constant>.
+       You can override the former if you need to assign different data
+       records per PCM substream.  For example, cmi8330 driver assigns
+       different private_data for playback and capture directions,
+       because it uses two different codecs (SB- and AD-compatible) for
+       different directions.
       </para>
 
       <section id="pcm-interface-operators-open-callback">
@@ -2766,7 +2612,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_open(snd_pcm_substream_t *substream);
+  static int snd_xxx_open(struct snd_pcm_substream *substream);
 ]]>
             </programlisting>
           </informalexample>
@@ -2781,10 +2627,10 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_open(snd_pcm_substream_t *substream)
+  static int snd_xxx_open(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
 
           runtime->hw = snd_mychip_playback_hw;
           return 0;
@@ -2817,7 +2663,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_close(snd_pcm_substream_t *substream);
+  static int snd_xxx_close(struct snd_pcm_substream *substream);
 ]]>
             </programlisting>
           </informalexample>
@@ -2832,10 +2678,10 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_close(snd_pcm_substream_t *substream)
+  static int snd_xxx_close(struct snd_pcm_substream *substream)
   {
           ....
-          snd_magic_kfree(substream->runtime->private_data);
+          kfree(substream->runtime->private_data);
           ....
   }
 ]]>
@@ -2859,8 +2705,8 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_hw_params(snd_pcm_substream_t * substream,
-                               snd_pcm_hw_params_t * hw_params);
+  static int snd_xxx_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *hw_params);
 ]]>
             </programlisting>
           </informalexample>
@@ -2919,10 +2765,10 @@ struct _snd_pcm_runtime {
         <para>
           Another note is that this callback is non-atomic
         (schedulable). This is important, because the
-        <structfield>prepare</structfield> callback 
+        <structfield>trigger</structfield> callback 
         is atomic (non-schedulable). That is, mutex or any
-        schedule-related functions are available only in
-        <structfield>hw_params</structfield> callback. 
+        schedule-related functions are not available in
+        <structfield>trigger</structfield> callback.
        Please see the subsection
        <link linkend="pcm-interface-atomicity"><citetitle>
        Atomicity</citetitle></link> for details.
@@ -2935,7 +2781,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_hw_free(snd_pcm_substream_t * substream);
+  static int snd_xxx_hw_free(struct snd_pcm_substream *substream);
 ]]>
             </programlisting>
           </informalexample>
@@ -2970,7 +2816,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_prepare(snd_pcm_substream_t * substream);
+  static int snd_xxx_prepare(struct snd_pcm_substream *substream);
 ]]>
             </programlisting>
           </informalexample>
@@ -2988,7 +2834,8 @@ struct _snd_pcm_runtime {
         </para>
 
         <para>
-          As mentioned above, this callback is atomic.
+       Note that this callback became non-atomic since the recent version.
+       You can use schedule-related functions safely in this callback now.
         </para>
 
         <para>
@@ -3018,7 +2865,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_trigger(snd_pcm_substream_t * substream, int cmd);
+  static int snd_xxx_trigger(struct snd_pcm_substream *substream, int cmd);
 ]]>
             </programlisting>
           </informalexample>
@@ -3060,8 +2907,8 @@ struct _snd_pcm_runtime {
         </para>
 
         <para>
-          When the pcm supports the suspend/resume operation
-        (i.e. <constant>SNDRV_PCM_INFO_RESUME</constant> flag is set),
+          When the pcm supports the suspend/resume operation,
+       regardless of full or partial suspend/resume support,
         <constant>SUSPEND</constant> and <constant>RESUME</constant>
         commands must be handled, too.
         These commands are issued when the power-management status is
@@ -3070,10 +2917,17 @@ struct _snd_pcm_runtime {
         do suspend and resume of the pcm substream, and usually, they
         are identical with <constant>STOP</constant> and
         <constant>START</constant> commands, respectively.
+         See <link linkend="power-management"><citetitle>
+       Power Management</citetitle></link> section for details.
         </para>
 
         <para>
-          This callback is also atomic.
+          As mentioned, this callback is atomic.  You cannot call
+         the function going to sleep.
+         The trigger callback should be as minimal as possible,
+         just really triggering the DMA.  The other stuff should be
+         initialized hw_params and prepare callbacks properly
+         beforehand.
         </para>
       </section>
 
@@ -3083,7 +2937,7 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static snd_pcm_uframes_t snd_xxx_pointer(snd_pcm_substream_t * substream)
+  static snd_pcm_uframes_t snd_xxx_pointer(struct snd_pcm_substream *substream)
 ]]>
             </programlisting>
           </informalexample>
@@ -3139,6 +2993,9 @@ struct _snd_pcm_runtime {
        current appl_ptr for the internal buffer, and this callback
        is useful only for such a purpose.
        </para>
+       <para>
+         This callback is atomic.
+       </para>
       </section>
 
       <section id="pcm-interface-operators-page-callback">
@@ -3190,7 +3047,7 @@ struct _snd_pcm_runtime {
         </para>
 
         <para>
-          If you aquire a spinlock in the interrupt handler, and the
+          If you acquire a spinlock in the interrupt handler, and the
         lock is used in other pcm callbacks, too, then you have to
         release the lock before calling
         <function>snd_pcm_period_elapsed()</function>, because
@@ -3208,11 +3065,11 @@ struct _snd_pcm_runtime {
   static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
                                           struct pt_regs *regs)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t, dev_id, return);
+          struct mychip *chip = dev_id;
           spin_lock(&chip->lock);
           ....
           if (pcm_irq_invoked(chip)) {
-                  // call updater, unlock before it
+                  /* call updater, unlock before it */
                   spin_unlock(&chip->lock);
                   snd_pcm_period_elapsed(chip->substream);
                   spin_lock(&chip->lock);
@@ -3252,29 +3109,30 @@ struct _snd_pcm_runtime {
   static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
                                           struct pt_regs *regs)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t, dev_id, return);
+          struct mychip *chip = dev_id;
           spin_lock(&chip->lock);
           ....
           if (pcm_irq_invoked(chip)) {
                   unsigned int last_ptr, size;
-                  // get the current hardware pointer (in frames)
+                  /* get the current hardware pointer (in frames) */
                   last_ptr = get_hw_ptr(chip);
-                  // calculate the processed frames since the
-                  // last update
+                  /* calculate the processed frames since the
+                   * last update
+                   */
                   if (last_ptr < chip->last_ptr)
                           size = runtime->buffer_size + last_ptr 
                                    - chip->last_ptr; 
                   else
                           size = last_ptr - chip->last_ptr;
-                  // remember the last updated point
+                  /* remember the last updated point */
                   chip->last_ptr = last_ptr;
-                  // accumulate the size
+                  /* accumulate the size */
                   chip->size += size;
-                  // over the period boundary?
+                  /* over the period boundary? */
                   if (chip->size >= runtime->period_size) {
-                          // reset the accumulator
+                          /* reset the accumulator */
                           chip->size %= runtime->period_size;
-                          // call updater
+                          /* call updater */
                           spin_unlock(&chip->lock);
                           snd_pcm_period_elapsed(substream);
                           spin_lock(&chip->lock);
@@ -3319,7 +3177,7 @@ struct _snd_pcm_runtime {
       <para>
       As already seen, some pcm callbacks are atomic and some are
       not.  For example, <parameter>hw_params</parameter> callback is
-      non-atomic, while <parameter>prepare</parameter> callback is
+      non-atomic, while <parameter>trigger</parameter> callback is
       atomic.  This means, the latter is called already in a spinlock
       held by the PCM middle layer. Please take this atomicity into
       account when you use a spinlock or a semaphore in the callbacks.
@@ -3330,11 +3188,16 @@ struct _snd_pcm_runtime {
       <function>schedule</function> or go to
       <function>sleep</function>.  The semaphore and mutex do sleep,
       and hence they cannot be used inside the atomic callbacks
-      (e.g. <parameter>prepare</parameter> callback).
+      (e.g. <parameter>trigger</parameter> callback).
       For taking a certain delay in such a callback, please use
       <function>udelay()</function> or <function>mdelay()</function>.
       </para>
 
+      <para>
+      All three atomic callbacks (trigger, pointer, and ack) are
+      called with local interrupts disabled.
+      </para>
+
     </section>
     <section id="pcm-interface-constraints">
       <title>Constraints</title>
@@ -3356,13 +3219,13 @@ struct _snd_pcm_runtime {
 <![CDATA[
   static unsigned int rates[] =
           {4000, 10000, 22050, 44100};
-  static snd_pcm_hw_constraint_list_t constraints_rates = {
-          .count = sizeof(rates) / sizeof(rates[0]),
+  static struct snd_pcm_hw_constraint_list constraints_rates = {
+          .count = ARRAY_SIZE(rates),
           .list = rates,
           .mask = 0,
   };
 
-  static int snd_mychip_pcm_open(snd_pcm_substream_t *substream)
+  static int snd_mychip_pcm_open(struct snd_pcm_substream *substream)
   {
           int err;
           ....
@@ -3380,25 +3243,26 @@ struct _snd_pcm_runtime {
 
       <para>
         There are many different constraints.
-        Look in <filename>sound/asound.h</filename> for a complete list.
+        Look in <filename>sound/pcm.h</filename> for a complete list.
         You can even define your own constraint rules.
         For example, let's suppose my_chip can manage a substream of 1 channel
         if and only if the format is S16_LE, otherwise it supports any format
-        specified in the <type>snd_pcm_hardware_t</type> stucture (or in any
+        specified in the <structname>snd_pcm_hardware</structname> stucture (or in any
         other constraint_list). You can build a rule like this:
 
         <example>
          <title>Example of Hardware Constraints for Channels</title>
          <programlisting>
 <![CDATA[
-  static int hw_rule_format_by_channels(snd_pcm_hw_params_t *params,
-                                        snd_pcm_hw_rule_t *rule)
+  static int hw_rule_format_by_channels(struct snd_pcm_hw_params *params,
+                                        struct snd_pcm_hw_rule *rule)
   {
-          snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-          snd_mask_t *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
-          snd_mask_t fmt;
+          struct snd_interval *c = hw_param_interval(params,
+                SNDRV_PCM_HW_PARAM_CHANNELS);
+          struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+          struct snd_mask fmt;
 
-          snd_mask_any(&fmt);    // Init the struct
+          snd_mask_any(&fmt);    /* Init the struct */
           if (c->min < 2) {
                   fmt.bits[0] &= SNDRV_PCM_FMTBIT_S16_LE;
                   return snd_mask_refine(f, &fmt);
@@ -3433,12 +3297,13 @@ struct _snd_pcm_runtime {
         <title>Example of Hardware Constraints for Channels</title>
         <programlisting>
 <![CDATA[
-  static int hw_rule_channels_by_format(snd_pcm_hw_params_t *params,
-                                        snd_pcm_hw_rule_t *rule)
+  static int hw_rule_channels_by_format(struct snd_pcm_hw_params *params,
+                                        struct snd_pcm_hw_rule *rule)
   {
-          snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-          snd_mask_t *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
-          snd_interval_t ch;
+          struct snd_interval *c = hw_param_interval(params,
+                        SNDRV_PCM_HW_PARAM_CHANNELS);
+          struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+          struct snd_interval ch;
 
           snd_interval_any(&ch);
           if (f->bits[0] == SNDRV_PCM_FMTBIT_S16_LE) {
@@ -3511,18 +3376,18 @@ struct _snd_pcm_runtime {
       callbacks: <structfield>info</structfield>,
       <structfield>get</structfield> and
       <structfield>put</structfield>. Then, define a
-      <type>snd_kcontrol_new_t</type> record, such as: 
+      struct <structname>snd_kcontrol_new</structname> record, such as: 
 
         <example>
          <title>Definition of a Control</title>
           <programlisting>
 <![CDATA[
-  static snd_kcontrol_new_t my_control __devinitdata = {
+  static struct snd_kcontrol_new my_control __devinitdata = {
           .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
           .name = "PCM Playback Switch",
           .index = 0,
           .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
-          .private_values = 0xffff,
+          .private_value = 0xffff,
           .info = my_control_info,
           .get = my_control_get,
           .put = my_control_put
@@ -3541,10 +3406,17 @@ struct _snd_pcm_runtime {
 
       <para>
         The <structfield>iface</structfield> field specifies the type of
-      the control,
-      <constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>. There are
-      <constant>MIXER</constant>, <constant>PCM</constant>,
-      <constant>CARD</constant>, etc.
+      the control, <constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>, which
+      is usually <constant>MIXER</constant>.
+      Use <constant>CARD</constant> for global controls that are not
+      logically part of the mixer.
+      If the control is closely associated with some specific device on
+      the sound card, use <constant>HWDEP</constant>,
+      <constant>PCM</constant>, <constant>RAWMIDI</constant>,
+      <constant>TIMER</constant>, or <constant>SEQUENCER</constant>, and
+      specify the device number with the
+      <structfield>device</structfield> and
+      <structfield>subdevice</structfield> fields.
       </para>
 
       <para>
@@ -3576,7 +3448,7 @@ struct _snd_pcm_runtime {
       </para>
 
       <para>
-        The <structfield>private_values</structfield> field contains
+        The <structfield>private_value</structfield> field contains
       an arbitrary long integer value for this record. When using
       generic <structfield>info</structfield>,
       <structfield>get</structfield> and
@@ -3673,7 +3545,7 @@ struct _snd_pcm_runtime {
 
         <para>
           More precise information can be found in
-        <filename>alsa-kernel/Documentation/sound/alsa/ControlNames.txt</filename>.
+        <filename>Documentation/sound/alsa/ControlNames.txt</filename>.
         </para>
       </section>
     </section>
@@ -3727,7 +3599,7 @@ struct _snd_pcm_runtime {
         <para>
           The <structfield>info</structfield> callback is used to get
         the detailed information of this control. This must store the
-        values of the given <type>snd_ctl_elem_info_t</type>
+        values of the given struct <structname>snd_ctl_elem_info</structname>
         object. For example, for a boolean control with a single
         element will be: 
 
@@ -3735,8 +3607,8 @@ struct _snd_pcm_runtime {
            <title>Example of info callback</title>
             <programlisting>
 <![CDATA[
-  static int snd_myctl_info(snd_kcontrol_t *kcontrol,
-                          snd_ctl_elem_info_t *uinfo)
+  static int snd_myctl_info(struct snd_kcontrol *kcontrol,
+                          struct snd_ctl_elem_info *uinfo)
   {
           uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
           uinfo->count = 1;
@@ -3770,8 +3642,8 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_myctl_info(snd_kcontrol_t *kcontrol,
-                          snd_ctl_elem_info_t *uinfo)
+  static int snd_myctl_info(struct snd_kcontrol *kcontrol,
+                          struct snd_ctl_elem_info *uinfo)
   {
           static char *texts[4] = {
                   "First", "Second", "Third", "Fourth"
@@ -3806,10 +3678,10 @@ struct _snd_pcm_runtime {
            <title>Example of get callback</title>
             <programlisting>
 <![CDATA[
-  static int snd_myctl_get(snd_kcontrol_t *kcontrol,
-                           snd_ctl_elem_value_t *ucontrol)
+  static int snd_myctl_get(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol)
   {
-          mychip_t *chip = snd_kcontrol_chip(kcontrol);
+          struct mychip *chip = snd_kcontrol_chip(kcontrol);
           ucontrol->value.integer.value[0] = get_some_value(chip);
           return 0;
   }
@@ -3821,8 +3693,7 @@ struct _snd_pcm_runtime {
         <para>
           Here, the chip instance is retrieved via
         <function>snd_kcontrol_chip()</function> macro.  This macro
-        converts from kcontrol-&gt;private_data to the type defined by
-        <type>chip_t</type>. The
+        just accesses to kcontrol-&gt;private_data. The
         kcontrol-&gt;private_data field is 
         given as the argument of <function>snd_ctl_new()</function>
         (see the later subsection
@@ -3846,8 +3717,8 @@ struct _snd_pcm_runtime {
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_sbmixer_get_single(snd_kcontrol_t *kcontrol,
-                                    snd_ctl_elem_value_t *ucontrol)
+  static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol,
+                                    struct snd_ctl_elem_value *ucontrol)
   {
           int reg = kcontrol->private_value & 0xff;
           int shift = (kcontrol->private_value >> 16) & 0xff;
@@ -3883,10 +3754,10 @@ struct _snd_pcm_runtime {
            <title>Example of put callback</title>
             <programlisting>
 <![CDATA[
-  static int snd_myctl_put(snd_kcontrol_t *kcontrol,
-                           snd_ctl_elem_value_t *ucontrol)
+  static int snd_myctl_put(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol)
   {
-          mychip_t *chip = snd_kcontrol_chip(kcontrol);
+          struct mychip *chip = snd_kcontrol_chip(kcontrol);
           int changed = 0;
           if (chip->current_value !=
                ucontrol->value.integer.value[0]) {
@@ -3943,7 +3814,7 @@ struct _snd_pcm_runtime {
         </informalexample>
 
         where <parameter>my_control</parameter> is the
-      <type>snd_kcontrol_new_t</type> object defined above, and chip
+      struct <structname>snd_kcontrol_new</structname> object defined above, and chip
       is the object pointer to be passed to
       kcontrol-&gt;private_data 
       which can be referred in callbacks. 
@@ -3951,7 +3822,7 @@ struct _snd_pcm_runtime {
 
       <para>
         <function>snd_ctl_new1()</function> allocates a new
-      <type>snd_kcontrol_t</type> instance (that's why the definition
+      <structname>snd_kcontrol</structname> instance (that's why the definition
       of <parameter>my_control</parameter> can be with
       <parameter>__devinitdata</parameter> 
       prefix), and <function>snd_ctl_add</function> assigns the given
@@ -3978,7 +3849,7 @@ struct _snd_pcm_runtime {
       control id pointer for the notification. The event-mask
       specifies the types of notification, for example, in the above
       example, the change of control values is notified.
-      The id pointer is the pointer of <type>snd_ctl_elem_id_t</type>
+      The id pointer is the pointer of struct <structname>snd_ctl_elem_id</structname>
       to be notified.
       You can find some examples in <filename>es1938.c</filename> or
       <filename>es1968.c</filename> for hardware volume interrupts. 
@@ -4011,45 +3882,44 @@ struct _snd_pcm_runtime {
            <title>Example of AC97 Interface</title>
             <programlisting>
 <![CDATA[
-  struct snd_mychip {
+  struct mychip {
           ....
-          ac97_t *ac97;
+          struct snd_ac97 *ac97;
           ....
   };
 
-  static unsigned short snd_mychip_ac97_read(ac97_t *ac97,
+  static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
                                              unsigned short reg)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t,
-                                   ac97->private_data, return 0);
+          struct mychip *chip = ac97->private_data;
           ....
           // read a register value here from the codec
           return the_register_value;
   }
 
-  static void snd_mychip_ac97_write(ac97_t *ac97,
+  static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
                                    unsigned short reg, unsigned short val)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t,
-                                   ac97->private_data, return 0);
+          struct mychip *chip = ac97->private_data;
           ....
           // write the given register value to the codec
   }
 
-  static int snd_mychip_ac97(mychip_t *chip)
+  static int snd_mychip_ac97(struct mychip *chip)
   {
-          ac97_bus_t bus, *pbus;
-          ac97_t ac97;
+          struct snd_ac97_bus *bus;
+          struct snd_ac97_template ac97;
           int err;
+          static struct snd_ac97_bus_ops ops = {
+                  .write = snd_mychip_ac97_write,
+                  .read = snd_mychip_ac97_read,
+          };
 
-          memset(&bus, 0, sizeof(bus));
-          bus.write = snd_mychip_ac97_write;
-          bus.read = snd_mychip_ac97_read;
-          if ((err = snd_ac97_bus(chip->card, &bus, &pbus)) < 0)
+          if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus)) < 0)
                   return err;
           memset(&ac97, 0, sizeof(ac97));
           ac97.private_data = chip;
-          return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
+          return snd_ac97_mixer(bus, &ac97, &chip->ac97);
   }
 
 ]]>
@@ -4062,18 +3932,18 @@ struct _snd_pcm_runtime {
       <title>Constructor</title>
       <para>
         For creating an ac97 instance, first call <function>snd_ac97_bus</function>
-      with <type>ac97_bus_t</type> record including callback functions.
+      with an <type>ac97_bus_ops_t</type> record with callback functions.
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  ac97_bus_t bus, *pbus;
-  int err;
+  struct snd_ac97_bus *bus;
+  static struct snd_ac97_bus_ops ops = {
+        .write = snd_mychip_ac97_write,
+        .read = snd_mychip_ac97_read,
+  };
 
-  memset(&bus, 0, sizeof(bus));
-  bus.write = snd_mychip_ac97_write;
-  bus.read = snd_mychip_ac97_read;
-  snd_ac97_bus(card, &bus, &pbus);
+  snd_ac97_bus(card, 0, &ops, NULL, &pbus);
 ]]>
           </programlisting>
         </informalexample>
@@ -4082,13 +3952,14 @@ struct _snd_pcm_runtime {
       </para>
 
       <para>
-      And then call <function>snd_ac97_mixer()</function> with an <type>ac97_t</type>
+      And then call <function>snd_ac97_mixer()</function> with an
+      struct <structname>snd_ac97_template</structname>
       record together with the bus pointer created above.
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  ac97_t ac97;
+  struct snd_ac97_template ac97;
   int err;
 
   memset(&ac97, 0, sizeof(ac97));
@@ -4125,11 +3996,10 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  static unsigned short snd_mychip_ac97_read(ac97_t *ac97,
+  static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
                                              unsigned short reg)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t,
-                                   ac97->private_data, return 0);
+          struct mychip *chip = ac97->private_data;
           ....
           return the_register_value;
   }
@@ -4147,7 +4017,7 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  static void snd_mychip_ac97_write(ac97_t *ac97,
+  static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
                        unsigned short reg, unsigned short val)
 ]]>
           </programlisting>
@@ -4198,7 +4068,7 @@ struct _snd_pcm_runtime {
         Both <function>snd_ac97_write()</function> and
         <function>snd_ac97_update()</function> functions are used to
         set a value to the given register
-        (<constant>AC97_XXX</constant>). The different between them is
+        (<constant>AC97_XXX</constant>). The difference between them is
         that <function>snd_ac97_update()</function> doesn't write a
         value if the given value has been already set, while
         <function>snd_ac97_write()</function> always rewrites the
@@ -4243,8 +4113,8 @@ struct _snd_pcm_runtime {
       <para>
         Also, there is a function to change the sample rate (of a
         certain register such as
-        <constant>AC97_PCM_FRONT_DAC_RATE</constant>) when VRA is
-        supported by the codec:
+        <constant>AC97_PCM_FRONT_DAC_RATE</constant>) when VRA or
+        DRA is supported by the codec:
         <function>snd_ac97_set_rate()</function>. 
 
         <informalexample>
@@ -4273,7 +4143,7 @@ struct _snd_pcm_runtime {
       <para>
         On some chip, the clock of the codec isn't 48000 but using a
       PCI clock (to save a quartz!). In this case, change the field
-      ac97-&gt;clock to the corresponding
+      bus-&gt;clock to the corresponding
       value. For example, intel8x0 
       and es1968 drivers have the auto-measurement function of the
       clock. 
@@ -4284,8 +4154,8 @@ struct _snd_pcm_runtime {
       <title>Proc Files</title>
       <para>
         The ALSA AC97 interface will create a proc file such as
-      <filename>/proc/asound/card0/ac97#0</filename> and
-      <filename>ac97#0regs</filename>. You can refer to these files to
+      <filename>/proc/asound/card0/codec97#0/ac97#0-0</filename> and
+      <filename>ac97#0-0+regs</filename>. You can refer to these files to
       see the current status and registers of the codec. 
       </para>
     </section>
@@ -4294,7 +4164,7 @@ struct _snd_pcm_runtime {
       <title>Multiple Codecs</title>
       <para>
         When there are several codecs on the same card, you need to
-      call <function>snd_ac97_new()</function> multiple times with
+      call <function>snd_ac97_mixer()</function> multiple times with
       ac97.num=1 or greater. The <structfield>num</structfield> field
       specifies the codec 
       number. 
@@ -4332,18 +4202,6 @@ struct _snd_pcm_runtime {
       implementation of mpu401 stuff. For example, emu10k1 has its own
       mpu401 routines. 
       </para>
-
-      <para>
-        In this document, I won't explain the rawmidi interface API,
-      which is the basis of MPU401-UART implementation. 
-      </para>
-
-      <para>
-        For details, please check the source,
-      <filename>core/rawmidi.c</filename>, and examples such as
-      <filename>drivers/mpu401/mpu401_uart.c</filename> or
-      <filename>usb/usbmidi.c</filename>. 
-      </para>
     </section>
 
     <section id="midi-interface-constructor">
@@ -4355,8 +4213,8 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_rawmidi_t *rmidi;
-  snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, integrated,
+  struct snd_rawmidi *rmidi;
+  snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,
                       irq, irq_flags, &rmidi);
 ]]>
           </programlisting>
@@ -4383,31 +4241,52 @@ struct _snd_pcm_runtime {
       </para>
 
       <para>
+       The 5th argument is bitflags for additional information.
         When the i/o port address above is a part of the PCI i/o
       region, the MPU401 i/o port might have been already allocated
-      (reserved) by the driver itself. In such a case, pass non-zero
-      to the 5th argument
-      (<parameter>integrated</parameter>). Otherwise, pass 0 to it,
+      (reserved) by the driver itself. In such a case, pass a bit flag
+      <constant>MPU401_INFO_INTEGRATED</constant>,
       and 
       the mpu401-uart layer will allocate the i/o ports by itself. 
       </para>
 
+       <para>
+       When the controller supports only the input or output MIDI stream,
+       pass <constant>MPU401_INFO_INPUT</constant> or
+       <constant>MPU401_INFO_OUTPUT</constant> bitflag, respectively.
+       Then the rawmidi instance is created as a single stream.
+       </para>
+
+       <para>
+       <constant>MPU401_INFO_MMIO</constant> bitflag is used to change
+       the access method to MMIO (via readb and writeb) instead of
+       iob and outb.  In this case, you have to pass the iomapped address
+       to <function>snd_mpu401_uart_new()</function>.
+       </para>
+
+       <para>
+       When <constant>MPU401_INFO_TX_IRQ</constant> is set, the output
+       stream isn't checked in the default interrupt handler.  The driver
+       needs to call <function>snd_mpu401_uart_interrupt_tx()</function>
+       by itself to start processing the output stream in irq handler.
+       </para>
+
       <para>
         Usually, the port address corresponds to the command port and
         port + 1 corresponds to the data port. If not, you may change
         the <structfield>cport</structfield> field of
-        <type>mpu401_t</type> manually 
-        afterward. However, <type>mpu401_t</type> pointer is not
+        struct <structname>snd_mpu401</structname> manually 
+        afterward. However, <structname>snd_mpu401</structname> pointer is not
         returned explicitly by
         <function>snd_mpu401_uart_new()</function>. You need to cast
         rmidi-&gt;private_data to
-        <type>mpu401_t</type> explicitly, 
+        <structname>snd_mpu401</structname> explicitly, 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  mpu401_t *mpu;
-  mpu = snd_magic_cast(mpu401_t, rmidi->private_data, );
+  struct snd_mpu401 *mpu;
+  mpu = rmidi->private_data;
 ]]>
           </programlisting>
         </informalexample>
@@ -4466,6 +4345,354 @@ struct _snd_pcm_runtime {
   </chapter>
 
 
+<!-- ****************************************************** -->
+<!-- RawMIDI Interface  -->
+<!-- ****************************************************** -->
+  <chapter id="rawmidi-interface">
+    <title>RawMIDI Interface</title>
+
+    <section id="rawmidi-interface-overview">
+      <title>Overview</title>
+
+      <para>
+      The raw MIDI interface is used for hardware MIDI ports that can
+      be accessed as a byte stream.  It is not used for synthesizer
+      chips that do not directly understand MIDI.
+      </para>
+
+      <para>
+      ALSA handles file and buffer management.  All you have to do is
+      to write some code to move data between the buffer and the
+      hardware.
+      </para>
+
+      <para>
+      The rawmidi API is defined in
+      <filename>&lt;sound/rawmidi.h&gt;</filename>.
+      </para>
+    </section>
+
+    <section id="rawmidi-interface-constructor">
+      <title>Constructor</title>
+
+      <para>
+      To create a rawmidi device, call the
+      <function>snd_rawmidi_new</function> function:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_rawmidi *rmidi;
+  err = snd_rawmidi_new(chip->card, "MyMIDI", 0, outs, ins, &rmidi);
+  if (err < 0)
+          return err;
+  rmidi->private_data = chip;
+  strcpy(rmidi->name, "My MIDI");
+  rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
+                      SNDRV_RAWMIDI_INFO_INPUT |
+                      SNDRV_RAWMIDI_INFO_DUPLEX;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+      The first argument is the card pointer, the second argument is
+      the ID string.
+      </para>
+
+      <para>
+      The third argument is the index of this component.  You can
+      create up to 8 rawmidi devices.
+      </para>
+
+      <para>
+      The fourth and fifth arguments are the number of output and
+      input substreams, respectively, of this device.  (A substream is
+      the equivalent of a MIDI port.)
+      </para>
+
+      <para>
+      Set the <structfield>info_flags</structfield> field to specify
+      the capabilities of the device.
+      Set <constant>SNDRV_RAWMIDI_INFO_OUTPUT</constant> if there is
+      at least one output port,
+      <constant>SNDRV_RAWMIDI_INFO_INPUT</constant> if there is at
+      least one input port,
+      and <constant>SNDRV_RAWMIDI_INFO_DUPLEX</constant> if the device
+      can handle output and input at the same time.
+      </para>
+
+      <para>
+      After the rawmidi device is created, you need to set the
+      operators (callbacks) for each substream.  There are helper
+      functions to set the operators for all substream of a device:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mymidi_output_ops);
+  snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mymidi_input_ops);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+      The operators are usually defined like this:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static struct snd_rawmidi_ops snd_mymidi_output_ops = {
+          .open =    snd_mymidi_output_open,
+          .close =   snd_mymidi_output_close,
+          .trigger = snd_mymidi_output_trigger,
+  };
+]]>
+          </programlisting>
+        </informalexample>
+      These callbacks are explained in the <link
+      linkend="rawmidi-interface-callbacks"><citetitle>Callbacks</citetitle></link>
+      section.
+      </para>
+
+      <para>
+      If there is more than one substream, you should give each one a
+      unique name:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct list_head *list;
+  struct snd_rawmidi_substream *substream;
+  list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
+          substream = list_entry(list, struct snd_rawmidi_substream, list);
+          sprintf(substream->name, "My MIDI Port %d", substream->number + 1);
+  }
+  /* same for SNDRV_RAWMIDI_STREAM_INPUT */
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+    </section>
+
+    <section id="rawmidi-interface-callbacks">
+      <title>Callbacks</title>
+
+      <para>
+      In all callbacks, the private data that you've set for the
+      rawmidi device can be accessed as
+      substream-&gt;rmidi-&gt;private_data.
+      <!-- <code> isn't available before DocBook 4.3 -->
+      </para>
+
+      <para>
+      If there is more than one port, your callbacks can determine the
+      port index from the struct snd_rawmidi_substream data passed to each
+      callback:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_rawmidi_substream *substream;
+  int index = substream->number;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <section id="rawmidi-interface-op-open">
+      <title><function>open</function> callback</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int snd_xxx_open(struct snd_rawmidi_substream *substream);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        This is called when a substream is opened.
+        You can initialize the hardware here, but you should not yet
+        start transmitting/receiving data.
+        </para>
+      </section>
+
+      <section id="rawmidi-interface-op-close">
+      <title><function>close</function> callback</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int snd_xxx_close(struct snd_rawmidi_substream *substream);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        Guess what.
+        </para>
+
+        <para>
+        The <function>open</function> and <function>close</function>
+        callbacks of a rawmidi device are serialized with a mutex,
+        and can sleep.
+        </para>
+      </section>
+
+      <section id="rawmidi-interface-op-trigger-out">
+      <title><function>trigger</function> callback for output
+      substreams</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void snd_xxx_output_trigger(struct snd_rawmidi_substream *substream, int up);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        This is called with a nonzero <parameter>up</parameter>
+        parameter when there is some data in the substream buffer that
+        must be transmitted.
+        </para>
+
+        <para>
+        To read data from the buffer, call
+        <function>snd_rawmidi_transmit_peek</function>.  It will
+        return the number of bytes that have been read; this will be
+        less than the number of bytes requested when there is no more
+        data in the buffer.
+        After the data has been transmitted successfully, call
+        <function>snd_rawmidi_transmit_ack</function> to remove the
+        data from the substream buffer:
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  unsigned char data;
+  while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {
+          if (snd_mychip_try_to_transmit(data))
+                  snd_rawmidi_transmit_ack(substream, 1);
+          else
+                  break; /* hardware FIFO full */
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+        If you know beforehand that the hardware will accept data, you
+        can use the <function>snd_rawmidi_transmit</function> function
+        which reads some data and removes it from the buffer at once:
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  while (snd_mychip_transmit_possible()) {
+          unsigned char data;
+          if (snd_rawmidi_transmit(substream, &data, 1) != 1)
+                  break; /* no more data */
+          snd_mychip_transmit(data);
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+        If you know beforehand how many bytes you can accept, you can
+        use a buffer size greater than one with the
+        <function>snd_rawmidi_transmit*</function> functions.
+        </para>
+
+        <para>
+        The <function>trigger</function> callback must not sleep.  If
+        the hardware FIFO is full before the substream buffer has been
+        emptied, you have to continue transmitting data later, either
+        in an interrupt handler, or with a timer if the hardware
+        doesn't have a MIDI transmit interrupt.
+        </para>
+
+        <para>
+        The <function>trigger</function> callback is called with a
+        zero <parameter>up</parameter> parameter when the transmission
+        of data should be aborted.
+        </para>
+      </section>
+
+      <section id="rawmidi-interface-op-trigger-in">
+      <title><function>trigger</function> callback for input
+      substreams</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void snd_xxx_input_trigger(struct snd_rawmidi_substream *substream, int up);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        This is called with a nonzero <parameter>up</parameter>
+        parameter to enable receiving data, or with a zero
+        <parameter>up</parameter> parameter do disable receiving data.
+        </para>
+
+        <para>
+        The <function>trigger</function> callback must not sleep; the
+        actual reading of data from the device is usually done in an
+        interrupt handler.
+        </para>
+
+        <para>
+        When data reception is enabled, your interrupt handler should
+        call <function>snd_rawmidi_receive</function> for all received
+        data:
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  void snd_mychip_midi_interrupt(...)
+  {
+          while (mychip_midi_available()) {
+                  unsigned char data;
+                  data = mychip_midi_read();
+                  snd_rawmidi_receive(substream, &data, 1);
+          }
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+      </section>
+
+      <section id="rawmidi-interface-op-drain">
+      <title><function>drain</function> callback</title>
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void snd_xxx_drain(struct snd_rawmidi_substream *substream);
+]]>
+          </programlisting>
+        </informalexample>
+
+        <para>
+        This is only used with output substreams.  This function should wait
+        until all data read from the substream buffer has been transmitted.
+        This ensures that the device can be closed and the driver unloaded
+        without losing data.
+        </para>
+
+        <para>
+        This callback is optional.  If you do not set
+        <structfield>drain</structfield> in the struct snd_rawmidi_ops
+        structure, ALSA will simply wait for 50&nbsp;milliseconds
+        instead.
+        </para>
+      </section>
+    </section>
+
+  </chapter>
+
+
 <!-- ****************************************************** -->
 <!-- Miscellaneous Devices  -->
 <!-- ****************************************************** -->
@@ -4498,7 +4725,7 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  opl3_t *opl3;
+  struct snd_opl3 *opl3;
   snd_opl3_create(card, lport, rport, OPL3_HW_OPL3_XXX,
                   integrated, &opl3);
 ]]>
@@ -4524,13 +4751,45 @@ struct _snd_pcm_runtime {
       </para>
 
       <para>
-        If this function returns successfully with 0, then create a
+        When the accessing to the hardware requires special method
+        instead of the standard I/O access, you can create opl3 instance
+        separately with <function>snd_opl3_new()</function>.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_opl3 *opl3;
+  snd_opl3_new(card, OPL3_HW_OPL3_XXX, &opl3);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+       Then set <structfield>command</structfield>,
+       <structfield>private_data</structfield> and
+       <structfield>private_free</structfield> for the private
+       access function, the private data and the destructor.
+       The l_port and r_port are not necessarily set.  Only the
+       command must be set properly.  You can retrieve the data
+       from opl3-&gt;private_data field.
+      </para>
+
+      <para>
+       After creating the opl3 instance via <function>snd_opl3_new()</function>,
+       call <function>snd_opl3_init()</function> to initialize the chip to the
+       proper state.  Note that <function>snd_opl3_create()</function> always
+       calls it internally.
+      </para>
+
+      <para>
+        If the opl3 instance is created successfully, then create a
         hwdep device for this opl3. 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_hwdep_t *opl3hwdep;
+  struct snd_hwdep *opl3hwdep;
   snd_opl3_hwdep_new(opl3, 0, 1, &opl3hwdep);
 ]]>
           </programlisting>
@@ -4567,7 +4826,7 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_hwdep_t *hw;
+  struct snd_hwdep *hw;
   snd_hwdep_new(card, "My HWDEP", 0, &hw);
 ]]>
           </programlisting>
@@ -4578,16 +4837,15 @@ struct _snd_pcm_runtime {
 
       <para>
         You can then pass any pointer value to the
-        <parameter>private_data</parameter>. Again, it should be a
-        magic-allocated record, so that the cast can be checked more
-        safely. If you assign a private data, you should define the
+        <parameter>private_data</parameter>.
+        If you assign a private data, you should define the
         destructor, too. The destructor function is set to
         <structfield>private_free</structfield> field.  
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  mydata_t *p = snd_magic_kmalloc(mydata_t, 0, GFP_KERNEL);
+  struct mydata *p = kmalloc(sizeof(*p), GFP_KERNEL);
   hw->private_data = p;
   hw->private_free = mydata_free;
 ]]>
@@ -4599,11 +4857,10 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  static void mydata_free(snd_hwdep_t *hw)
+  static void mydata_free(struct snd_hwdep *hw)
   {
-          mydata_t *p = snd_magic_cast(mydata_csp_t,
-                                       hw->private_data, return);
-          snd_magic_kfree(p);
+          struct mydata *p = hw->private_data;
+          kfree(p);
   }
 ]]>
           </programlisting>
@@ -4735,7 +4992,7 @@ struct _snd_pcm_runtime {
         where <parameter>size</parameter> is the byte size to be
       pre-allocated and the <parameter>max</parameter> is the maximal
       size to be changed via <filename>prealloc</filename> proc file.
-      The allocator will try to get as the large area as possible
+      The allocator will try to get as large area as possible
       within the given size. 
       </para>
 
@@ -4826,9 +5083,9 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int playback_copy(snd_pcm_substream_t *substream, int channel,
+  static int playback_copy(struct snd_pcm_substream *substream, int channel,
                snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count);
-  static int capture_copy(snd_pcm_substream_t *substream, int channel,
+  static int capture_copy(struct snd_pcm_substream *substream, int channel,
                snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count);
 ]]>
           </programlisting>
@@ -4909,7 +5166,7 @@ struct _snd_pcm_runtime {
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int silence(snd_pcm_substream_t *substream, int channel,
+  static int silence(struct snd_pcm_substream *substream, int channel,
                      snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
 ]]>
           </programlisting>
@@ -4957,7 +5214,7 @@ struct _snd_pcm_runtime {
         If your hardware supports the page table like emu10k1 or the
       buffer descriptors like via82xx, you can use the scatter-gather
       (SG) DMA. ALSA provides an interface for handling SG-buffers.
-      The API is provided in <filename>&lt;sound/pcm_sgbuf.h&gt;</filename>. 
+      The API is provided in <filename>&lt;sound/pcm.h&gt;</filename>. 
       </para>
 
       <para>
@@ -4969,14 +5226,14 @@ struct _snd_pcm_runtime {
         You need to pass the <function>snd_dma_pci_data(pci)</function>,
         where pci is the struct <structname>pci_dev</structname> pointer
         of the chip as well.
-        The <type>snd_sg_buf_t</type> instance is created as
+        The <type>struct snd_sg_buf</type> instance is created as
         substream-&gt;dma_private. You can cast
         the pointer like: 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_pcm_sgbuf_t *sgbuf = (snd_pcm_sgbuf_t*)substream->dma_private;
+  struct snd_sg_buf *sgbuf = (struct snd_sg_buf *)substream->dma_private;
 ]]>
           </programlisting>
         </informalexample>
@@ -5031,7 +5288,7 @@ struct _snd_pcm_runtime {
   #include <linux/vmalloc.h>
 
   /* get the physical page pointer on the given offset */
-  static struct page *mychip_page(snd_pcm_substream_t *substream,
+  static struct page *mychip_page(struct snd_pcm_substream *substream,
                                   unsigned long offset)
   {
           void *pageptr = substream->runtime->dma_area + offset;
@@ -5066,7 +5323,7 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  snd_info_entry_t *entry;
+  struct snd_info_entry *entry;
   int err = snd_card_proc_new(card, "my-file", &entry);
 ]]>
         </programlisting>
@@ -5096,7 +5353,7 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  snd_info_set_text_ops(entry, chip, read_size, my_proc_read);
+  snd_info_set_text_ops(entry, chip, my_proc_read);
 ]]>
         </programlisting>
       </informalexample>
@@ -5110,8 +5367,8 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  static void my_proc_read(snd_info_entry_t *entry,
-                           snd_info_buffer_t *buffer);
+  static void my_proc_read(struct snd_info_entry *entry,
+                           struct snd_info_buffer *buffer);
 ]]>
         </programlisting>
       </informalexample>
@@ -5126,11 +5383,10 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  static void my_proc_read(snd_info_entry_t *entry,
-                           snd_info_buffer_t *buffer)
+  static void my_proc_read(struct snd_info_entry *entry,
+                           struct snd_info_buffer *buffer)
   {
-          chip_t *cm = snd_magic_cast(mychip_t,
-                                  entry->private_data, return);
+          struct my_chip *chip = entry->private_data;
 
           snd_iprintf(buffer, "This is my chip!\n");
           snd_iprintf(buffer, "Port = %ld\n", chip->port);
@@ -5158,29 +5414,12 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  entry->c.text.write_size = 256;
   entry->c.text.write = my_proc_write;
 ]]>
         </programlisting>
       </informalexample>
     </para>
 
-    <para>
-    The buffer size for read is set to 1024 implicitly by
-    <function>snd_info_set_text_ops()</function>.  It should suffice
-    in most cases (the size will be aligned to
-    <constant>PAGE_SIZE</constant> anyway), but if you need to handle
-    very large text files, you can set it explicitly, too.
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  entry->c.text.read_size = 65536;
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
-
     <para>
       For the write callback, you can use
     <function>snd_info_get_line()</function> to get a text line, and
@@ -5214,22 +5453,23 @@ struct _snd_pcm_runtime {
       The callback is much more complicated than the text-file
       version. You need to use a low-level i/o functions such as
       <function>copy_from/to_user()</function> to transfer the
-      data. Also, you have to keep tracking the file position, too. 
+      data.
 
       <informalexample>
         <programlisting>
 <![CDATA[
-  static long my_file_io_read(snd_info_entry_t *entry,
+  static long my_file_io_read(struct snd_info_entry *entry,
                               void *file_private_data,
                               struct file *file,
-                              char *buf, long count)
+                              char *buf,
+                              unsigned long count,
+                              unsigned long pos)
   {
           long size = count;
-          if (file->f_pos + size > local_max_size)
-                  size = local_max_size - file->f_pos;
-          if (copy_to_user(buf, local_data + file->f_pos, size))
+          if (pos + size > local_max_size)
+                  size = local_max_size - pos;
+          if (copy_to_user(buf, local_data + pos, size))
                   return -EFAULT;
-          file->f_pos += size;
           return size;
   }
 ]]>
@@ -5246,77 +5486,91 @@ struct _snd_pcm_runtime {
   <chapter id="power-management">
     <title>Power Management</title>
     <para>
-      If the chip is supposed to work with with suspend/resume
+      If the chip is supposed to work with suspend/resume
       functions, you need to add the power-management codes to the
       driver. The additional codes for the power-management should be
       <function>ifdef</function>'ed with
       <constant>CONFIG_PM</constant>. 
     </para>
 
+       <para>
+       If the driver supports the suspend/resume
+       <emphasis>fully</emphasis>, that is, the device can be
+       properly resumed to the status at the suspend is called,
+       you can set <constant>SNDRV_PCM_INFO_RESUME</constant> flag
+       to pcm info field.  Usually, this is possible when the
+       registers of ths chip can be safely saved and restored to the
+       RAM.  If this is set, the trigger callback is called with
+       <constant>SNDRV_PCM_TRIGGER_RESUME</constant> after resume
+       callback is finished. 
+       </para>
+
+       <para>
+       Even if the driver doesn't support PM fully but only the
+       partial suspend/resume is possible, it's still worthy to
+       implement suspend/resume callbacks.  In such a case, applications
+       would reset the status by calling
+       <function>snd_pcm_prepare()</function> and restart the stream
+       appropriately.  Hence, you can define suspend/resume callbacks
+       below but don't set <constant>SNDRV_PCM_INFO_RESUME</constant>
+       info flag to the PCM.
+       </para>
+       
+       <para>
+       Note that the trigger with SUSPEND can be always called when
+       <function>snd_pcm_suspend_all</function> is called,
+       regardless of <constant>SNDRV_PCM_INFO_RESUME</constant> flag.
+       The <constant>RESUME</constant> flag affects only the behavior
+       of <function>snd_pcm_resume()</function>.
+       (Thus, in theory,
+       <constant>SNDRV_PCM_TRIGGER_RESUME</constant> isn't needed
+       to be handled in the trigger callback when no
+       <constant>SNDRV_PCM_INFO_RESUME</constant> flag is set.  But,
+       it's better to keep it for compatibility reason.)
+       </para>
     <para>
-      Basic jobs of suspend/resume are done in
-      <structfield>suspend</structfield> and
-      <structfield>resume</structfield> callbacks of
-      <structname>pci_driver</structname> struct. Unfortunately, the
-      API of these callbacks was changed at the middle time of Linux
-      2.4.x, if you want to keep the support for older kernels, you
-      have to write two different callbacks. The example below is the
-      skeleton callbacks which just call the real suspend and resume
-      functions. 
+      In the earlier version of ALSA drivers, a common
+      power-management layer was provided, but it has been removed.
+      The driver needs to define the suspend/resume hooks according to
+      the bus the device is assigned.  In the case of PCI driver, the
+      callbacks look like below:
 
       <informalexample>
         <programlisting>
 <![CDATA[
-  #ifndef PCI_OLD_SUSPEND
-  static int snd_my_suspend(struct pci_dev *dev, u32 state)
+  #ifdef CONFIG_PM
+  static int snd_my_suspend(struct pci_dev *pci, pm_message_t state)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t,
-                             pci_get_drvdata(dev), return -ENXIO);
-          mychip_suspend(chip);
+          .... /* do things for suspsend */
           return 0;
   }
-  static int snd_my_resume(struct pci_dev *dev)
+  static int snd_my_resume(struct pci_dev *pci)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t,
-                             pci_get_drvdata(dev), return -ENXIO);
-          mychip_resume(chip);
+          .... /* do things for suspsend */
           return 0;
   }
-  #else
-  static void snd_my_suspend(struct pci_dev *dev)
-  {
-          mychip_t *chip = snd_magic_cast(mychip_t,
-                             pci_get_drvdata(dev), return);
-          mychip_suspend(chip);
-  }
-  static void snd_mychip_resume(struct pci_dev *dev)
-  {
-          mychip_t *chip = snd_magic_cast(mychip_t,
-                             pci_get_drvdata(dev), return);
-          mychip_resume(chip);
-  }
   #endif
 ]]>
         </programlisting>
       </informalexample>
     </para>
 
-    <para>
-      For keeping the readability of 2.6 source code, it's recommended to
-      separate the above ifdef condition as the patch file in alsa-driver
-      directory.
-      See <filename>alsa-driver/pci/ali5451.c</filename> for example.
-   </para>
-
     <para>
       The scheme of the real suspend job is as following.
 
       <orderedlist>
-        <listitem><para>Check whether the power-state is already D3hot. If yes, skip the job.</para></listitem>
+        <listitem><para>Retrieve the card and the chip data.</para></listitem>
+        <listitem><para>Call <function>snd_power_change_state()</function> with
+         <constant>SNDRV_CTL_POWER_D3hot</constant> to change the
+         power status.</para></listitem>
         <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem>
+       <listitem><para>If AC97 codecs are used, call
+       <function>snd_ac97_suspend()</function> for each codec.</para></listitem>
         <listitem><para>Save the register values if necessary.</para></listitem>
         <listitem><para>Stop the hardware if necessary.</para></listitem>
-        <listitem><para>Set the power-state as D3hot by calling <function>snd_power_change_state()</function>.</para></listitem>
+        <listitem><para>Disable the PCI device by calling
+         <function>pci_disable_device()</function>.  Then, call
+          <function>pci_save_state()</function> at last.</para></listitem>
       </orderedlist>
     </para>
 
@@ -5326,20 +5580,25 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  static void mychip_suspend(mychip_t *chip)
+  static int mychip_suspend(struct pci_dev *pci, pm_message_t state)
   {
-          snd_card_t *card = chip->card;
-          // (1)
-          if (card->power_state == SNDRV_CTL_POWER_D3hot)
-                  return;
-          // (2)
+          /* (1) */
+          struct snd_card *card = pci_get_drvdata(pci);
+          struct mychip *chip = card->private_data;
+          /* (2) */
+          snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+          /* (3) */
           snd_pcm_suspend_all(chip->pcm);
-          // (3)
+          /* (4) */
+          snd_ac97_suspend(chip->ac97);
+          /* (5) */
           snd_mychip_save_registers(chip);
-          // (4)
+          /* (6) */
           snd_mychip_stop_hardware(chip);
-          // (5)
-          snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+          /* (7) */
+          pci_disable_device(pci);
+          pci_save_state(pci);
+          return 0;
   }
 ]]>
         </programlisting>
@@ -5350,17 +5609,17 @@ struct _snd_pcm_runtime {
     The scheme of the real resume job is as following.
 
     <orderedlist>
-    <listitem><para>Check whether the power-state is already D0.
-    If yes, skip the job.</para></listitem>
-    <listitem><para>Enable the pci device again by calling
-    <function>pci_enable_device()</function>.</para></listitem>
+    <listitem><para>Retrieve the card and the chip data.</para></listitem>
+    <listitem><para>Set up PCI.  First, call <function>pci_restore_state()</function>.
+       Then enable the pci device again by calling <function>pci_enable_device()</function>.
+       Call <function>pci_set_master()</function> if necessary, too.</para></listitem>
     <listitem><para>Re-initialize the chip.</para></listitem>
     <listitem><para>Restore the saved registers if necessary.</para></listitem>
     <listitem><para>Resume the mixer, e.g. calling
     <function>snd_ac97_resume()</function>.</para></listitem>
     <listitem><para>Restart the hardware (if any).</para></listitem>
-    <listitem><para>Set the power-state as D0 by calling
-    <function>snd_power_change_state()</function>.</para></listitem>
+    <listitem><para>Call <function>snd_power_change_state()</function> with
+       <constant>SNDRV_CTL_POWER_D0</constant> to notify the processes.</para></listitem>
     </orderedlist>
     </para>
 
@@ -5370,24 +5629,26 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  static void mychip_resume(mychip_t *chip)
+  static int mychip_resume(struct pci_dev *pci)
   {
-          snd_card_t *card = chip->card;
-          // (1)
-          if (card->power_state == SNDRV_CTL_POWER_D0)
-                  return;
-          // (2)
-          pci_enable_device(chip->pci);
-          // (3)
+          /* (1) */
+          struct snd_card *card = pci_get_drvdata(pci);
+          struct mychip *chip = card->private_data;
+          /* (2) */
+          pci_restore_state(pci);
+          pci_enable_device(pci);
+          pci_set_master(pci);
+          /* (3) */
           snd_mychip_reinit_chip(chip);
-          // (4)
+          /* (4) */
           snd_mychip_restore_registers(chip);
-          // (5)
+          /* (5) */
           snd_ac97_resume(chip->ac97);
-          // (6)
+          /* (6) */
           snd_mychip_restart_chip(chip);
-          // (7)
+          /* (7) */
           snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+          return 0;
   }
 ]]>
         </programlisting>
@@ -5395,41 +5656,48 @@ struct _snd_pcm_runtime {
     </para>
 
     <para>
-      In addition to the callbacks above, you should define a callback
-      for the changes via the ALSA control interface. It's defined
-      like below: 
+       As shown in the above, it's better to save registers after
+       suspending the PCM operations via
+       <function>snd_pcm_suspend_all()</function> or
+       <function>snd_pcm_suspend()</function>.  It means that the PCM
+       streams are already stoppped when the register snapshot is
+       taken.  But, remind that you don't have to restart the PCM
+       stream in the resume callback. It'll be restarted via 
+       trigger call with <constant>SNDRV_PCM_TRIGGER_RESUME</constant>
+       when necessary.
+    </para>
+
+    <para>
+      OK, we have all callbacks now. Let's set them up. In the
+      initialization of the card, make sure that you can get the chip
+      data from the card instance, typically via
+      <structfield>private_data</structfield> field, in case you
+      created the chip data individually.
 
       <informalexample>
         <programlisting>
 <![CDATA[
-  static int snd_mychip_set_power_state(snd_card_t *card,
-                                        unsigned int power_state)
+  static int __devinit snd_mychip_probe(struct pci_dev *pci,
+                               const struct pci_device_id *pci_id)
   {
-          mychip_t *chip = snd_magic_cast(mychip_t,
-                   card->power_state_private_data, return -ENXIO);
-          switch (power_state) {
-          case SNDRV_CTL_POWER_D0:
-          case SNDRV_CTL_POWER_D1:
-          case SNDRV_CTL_POWER_D2:
-                  mychip_resume(chip);
-                  break;
-          case SNDRV_CTL_POWER_D3hot:
-          case SNDRV_CTL_POWER_D3cold:
-                  mychip_suspend(chip);
-                  break;
-          default:
-                  return -EINVAL;
-          }
-          return 0;
+          ....
+          struct snd_card *card;
+          struct mychip *chip;
+          ....
+          card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
+          ....
+          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+          ....
+          card->private_data = chip;
+          ....
   }
 ]]>
         </programlisting>
       </informalexample>
-    </para>
 
-    <para>
-      OK, we have all callbacks now. Let's set up them now. In the
-      initialization of the card, add the following: 
+       When you created the chip data with
+       <function>snd_card_new()</function>, it's anyway accessible
+       via <structfield>private_data</structfield> field.
 
       <informalexample>
         <programlisting>
@@ -5438,41 +5706,43 @@ struct _snd_pcm_runtime {
                                const struct pci_device_id *pci_id)
   {
           ....
-          snd_card_t *card;
+          struct snd_card *card;
+          struct mychip *chip;
           ....
-  #ifdef CONFIG_PM
-          card->set_power_state = snd_mychip_set_power_state;
-          card->power_state_private_data = chip;
-  #endif
+          card = snd_card_new(index[dev], id[dev], THIS_MODULE,
+                              sizeof(struct mychip));
+          ....
+          chip = card->private_data;
           ....
   }
 ]]>
         </programlisting>
       </informalexample>
+
     </para>
 
     <para>
-      If you need a space for saving the registers, you'll need to
-    allocate the buffer for it here, too, since you cannot call
-    <function>kmalloc()</function> with
-    <constant>GFP_KERNEL</constant> flag or
-    <function>vmalloc()</function> in the suspend callback.
+      If you need a space for saving the registers, allocate the
+       buffer for it here, too, since it would be fatal
+    if you cannot allocate a memory in the suspend phase.
     The allocated buffer should be released in the corresponding
     destructor.
     </para>
 
     <para>
-      And next, set suspend/resume callbacks to the pci_driver,
+      And next, set suspend/resume callbacks to the pci_driver.
 
       <informalexample>
         <programlisting>
 <![CDATA[
   static struct pci_driver driver = {
           .name = "My Chip",
-          ....
+          .id_table = snd_my_ids,
+          .probe = snd_my_probe,
+          .remove = __devexit_p(snd_my_remove),
   #ifdef CONFIG_PM
-          .suspend = snd_mychip_suspend,
-          .resume = snd_mychip_resume,
+          .suspend = snd_my_suspend,
+          .resume = snd_my_resume,
   #endif
   };
 ]]>
@@ -5521,20 +5791,9 @@ struct _snd_pcm_runtime {
 
     <para>
       The module parameters must be declared with the standard
-    <function>MODULE_PARM()</function> and
-    <function>MODULE_PARM_DESC()</function> macros. The ALSA provides
-    an additional macro, <function>MODULE_PARM_SYNTAX()</function>,
-    for describing its syntax. The strings will be written to
-    <filename>/lib/modules/XXX/modules.generic_string</filename>
-    file. 
-    </para>
-
-    <para>
-      For convenience, the typical string arguments given to
-    <function>MODULE_PARM_SYNTAX()</function> are defined in
-    <filename>&lt;sound/initval.h&gt;</filename>, such as
-    <constant>SNDRV_ID_DESC</constant> or
-    <constant>SNDRV_ENABLED</constant>.
+    <function>module_param()()</function>,
+    <function>module_param_array()()</function> and
+    <function>MODULE_PARM_DESC()</function> macros.
     </para>
 
     <para>
@@ -5545,15 +5804,12 @@ struct _snd_pcm_runtime {
 <![CDATA[
   #define CARD_NAME "My Chip"
 
-  MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+  module_param_array(index, int, NULL, 0444);
   MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-  MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
-  MODULE_PARM(id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
+  module_param_array(id, charp, NULL, 0444);
   MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-  MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
-  MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+  module_param_array(enable, bool, NULL, 0444);
   MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-  MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
 ]]>
         </programlisting>
       </informalexample>
@@ -5569,47 +5825,13 @@ struct _snd_pcm_runtime {
         <programlisting>
 <![CDATA[
   MODULE_DESCRIPTION("My Chip");
-  MODULE_CLASSES("{sound}");
   MODULE_LICENSE("GPL");
-  MODULE_DEVICES("{{Vendor,My Chip Name}}");
+  MODULE_SUPPORTED_DEVICE("{{Vendor,My Chip Name}}");
 ]]>
         </programlisting>
       </informalexample>
     </para>
 
-    <para>
-      For building the driver into kernel, you should define the
-      <function>setup()</function> function in addition, too. 
-      ALSA provides <function>get_id()</function> function to retrieve
-      a string argument from the kernel boot parameters.
-
-      <informalexample>
-        <programlisting>
-<![CDATA[
-  #ifndef MODULE
-
-  /* format is: snd-mychip=enable,index,id */
-
-  static int __init alsa_card_mychip_setup(char *str)
-  {
-          static unsigned __initdata nr_dev = 0;
-
-          if (nr_dev >= SNDRV_CARDS)
-                  return 0;
-          (void)(get_option(&str,&enable[nr_dev]) == 2 &&
-                 get_option(&str,&index[nr_dev]) == 2 &&
-                 get_id(&str,&id[nr_dev]) == 2);
-          nr_dev++;
-          return 1;
-  }
-
-  __setup("snd-mychip=", alsa_card_mychip_setup);
-
-  #endif /* ifndef MODULE */
-]]>
-        </programlisting>
-      </informalexample>
-    </para>
   </chapter>
 
 
@@ -5631,10 +5853,14 @@ struct _snd_pcm_runtime {
        Suppose that you'll create a new PCI driver for the card
        <quote>xyz</quote>.  The card module name would be
        snd-xyz.  The new driver is usually put into alsa-driver
-       tree.  Then the driver is evaluated, audited and tested
+       tree, <filename>alsa-driver/pci</filename> directory in
+       the case of PCI cards.
+       Then the driver is evaluated, audited and tested
        by developers and users.  After a certain time, the driver
-       will go to alsa-kernel tree and eventually integrated into
-       Linux 2.6 tree.
+       will go to alsa-kernel tree (to the corresponding directory,
+       such as <filename>alsa-kernel/pci</filename>) and eventually
+       integrated into Linux 2.6 tree (the directory would be
+       <filename>linux/sound/pci</filename>).
        </para>
 
        <para>
@@ -5661,7 +5887,7 @@ struct _snd_pcm_runtime {
         <programlisting>
 <![CDATA[
   snd-xyz-objs := xyz.o
-  extra-obj-$(CONFIG_SND_XYZ) += snd-xyz.o
+  obj-$(CONFIG_SND_XYZ) += snd-xyz.o
 ]]>
         </programlisting>
       </informalexample>
@@ -5678,12 +5904,15 @@ struct _snd_pcm_runtime {
       <informalexample>
         <programlisting>
 <![CDATA[
-  config SND_BT87X
-          tristate "Foobar XYX"
+  config SND_XYZ
+          tristate "Foobar XYZ"
           depends on SND
           select SND_PCM
           help
-            Say 'Y' or 'M' to include support for Foobar XYZ soundcard.
+            Say Y here to include support for Foobar XYZ soundcard.
+
+            To compile this driver as a module, choose M here: the module
+            will be called snd-xyz.
 ]]>
         </programlisting>
       </informalexample>
@@ -5730,7 +5959,8 @@ struct _snd_pcm_runtime {
        <orderedlist>
        <listitem>
        <para>
-       Add a new directory (xyz) to extra-subdir-y list in alsa-driver/pci/Makefile
+       Add a new directory (<filename>xyz</filename>) in
+       <filename>alsa-driver/pci/Makefile</filename> like below
 
       <informalexample>
         <programlisting>
@@ -5744,7 +5974,7 @@ struct _snd_pcm_runtime {
 
        <listitem>
        <para>
-       Under the directory xyz, create a Makefile
+       Under the directory <filename>xyz</filename>, create a Makefile
 
       <example>
        <title>Sample Makefile for a driver xyz</title>
@@ -5754,14 +5984,14 @@ struct _snd_pcm_runtime {
   SND_TOPDIR=../..
   endif
 
-  include $(TOPDIR)/toplevel.config
-  include $(TOPDIR)/Makefile.conf
+  include $(SND_TOPDIR)/toplevel.config
+  include $(SND_TOPDIR)/Makefile.conf
 
   snd-xyz-objs := xyz.o abc.o def.o
 
   obj-$(CONFIG_SND_XYZ) += snd-xyz.o
 
-  include $(TOPDIR)/Rules.make
+  include $(SND_TOPDIR)/Rules.make
 ]]>
         </programlisting>
       </example>
@@ -5856,32 +6086,23 @@ struct _snd_pcm_runtime {
         The first argument is the expression to evaluate, and the
       second argument is the action if it fails. When
       <constant>CONFIG_SND_DEBUG</constant>, is set, it will show an
-      error message such as <computeroutput>BUG? (xxx) (called from
-      yyy)</computeroutput>. When no debug flag is set, this is
-      ignored. 
+      error message such as <computeroutput>BUG? (xxx)</computeroutput>
+      together with stack trace.
       </para>
-    </section>
-
-    <section id="useful-functions-snd-runtime-check">
-      <title><function>snd_runtime_check()</function></title>
       <para>
-        This macro is quite similar with
-      <function>snd_assert()</function>. Unlike
-      <function>snd_assert()</function>, the expression is always
-      evaluated regardless of
-      <constant>CONFIG_SND_DEBUG</constant>. When
-      <constant>CONFIG_SND_DEBUG</constant> is set, the macro will
-      show a message like <computeroutput>ERROR (xx) (called from
-      yyy)</computeroutput>. 
+        When no debug flag is set, this macro is ignored. 
       </para>
     </section>
 
     <section id="useful-functions-snd-bug">
       <title><function>snd_BUG()</function></title>
       <para>
-        It calls <function>snd_assert(0,)</function> -- that is, just
-      prints the error message at the point. It's useful to show that
-      a fatal error happens there. 
+        It shows <computeroutput>BUG?</computeroutput> message and
+      stack trace as well as <function>snd_assert</function> at the point.
+      It's useful to show that a fatal error happens there. 
+      </para>
+      <para>
+        When no debug flag is set, this macro is ignored. 
       </para>
     </section>
   </chapter>