亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? writing-an-alsa-driver.tmpl

?? 優龍2410linux2.6.8內核源代碼
?? TMPL
?? 第 1 頁 / 共 5 頁
字號:
    <section id="pci-resource-example">      <title>Full Code Example</title>      <para>        In this section, we'll finish the chip-specific constructor,      destructor and PCI entries. The example code is shown first,      below.         <example>          <title>PCI Resource Managements Example</title>          <programlisting><![CDATA[  struct snd_mychip {          snd_card_t *card;          struct pci_dev *pci;          unsigned long port;          struct resource *res_port;          int irq;  };  static int snd_mychip_free(mychip_t *chip)  {          // 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          if (chip->irq >= 0)                  free_irq(chip->irq, (void *)chip);          // release the data          snd_magic_kfree(chip);          return 0;  }  // chip-specific constructor  static int __devinit snd_mychip_create(snd_card_t *card,                                         struct pci_dev *pci,                                         mychip_t **rchip)  {          mychip_t *chip;          int err;          static snd_device_ops_t ops = {                 .dev_free = snd_mychip_dev_free,          };          *rchip = NULL;          // check PCI availability (28bit DMA)          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) {                  printk(KERN_ERR "error to set 28bit mask DMA\n");                  return -ENXIO;          }          chip = snd_magic_kcalloc(mychip_t, 0, GFP_KERNEL);          if (chip == NULL)                  return -ENOMEM;          // 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;          }          if (request_irq(pci->irq, snd_mychip_interrupt,                          SA_INTERRUPT|SA_SHIRQ, "My Chip",                          (void *)chip)) {                  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)          if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,                                    chip, &ops)) < 0) {                  snd_mychip_free(chip);                  return err;          }          *rchip = chip;          return 0;  }          // 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, },          ....          { 0, }  };  MODULE_DEVICE_TABLE(pci, snd_mychip_ids);  // pci_driver definition  static struct pci_driver driver = {          .name = "My Own Chip",          .id_table = snd_mychip_ids,          .probe = snd_mychip_probe,          .remove = __devexit_p(snd_mychip_remove),  };  // initialization of the module  static int __init alsa_card_mychip_init(void)  {          return pci_module_init(&driver);  }  // clean up the module  static void __exit alsa_card_mychip_exit(void)  {          pci_unregister_driver(&driver);  }  module_init(alsa_card_mychip_init)  module_exit(alsa_card_mychip_exit)  EXPORT_NO_SYMBOLS; /* for old kernels only */]]>          </programlisting>        </example>      </para>    </section>    <section id="pci-resource-some-haftas">      <title>Some Hafta's</title>      <para>        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.       </para>      <para>        In the case of PCI devices, you have to call at first      <function>pci_enable_device()</function> function before      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.       </para>      <para>        Suppose the 28bit mask, and the code to be added would be like:        <informalexample>          <programlisting><![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) {          printk(KERN_ERR "error to set 28bit mask DMA\n");          return -ENXIO;  }  ]]>          </programlisting>        </informalexample>      </para>    </section>    <section id="pci-resource-resource-allocation">      <title>Resource Allocation</title>      <para>        The allocation of I/O ports and irqs are done via standard kernel      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.       </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:         <informalexample>          <programlisting><![CDATA[  struct snd_mychip {          snd_card_t *card;          unsigned long port;          struct resource *res_port;          int irq;  };]]>          </programlisting>        </informalexample>      </para>      <para>        For an i/o port (and also a memory region), you need to have      the resource pointer for the standard resource management. For      an irq, you have to keep only the irq number (integer). But you      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      don't have to take care of resetting them.       </para>      <para>        The allocation of an i/o port is done like this:        <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;  }]]>          </programlisting>        </informalexample>      </para>      <para>        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      <function>request_region()</function>. The pointer must be      released via <function>kfree()</function>, but there is some      problem regarding this. This issue will be explained more below.      </para>      <para>        The allocation of an interrupt source is done like this:        <informalexample>          <programlisting><![CDATA[  if (request_irq(pci->irq, snd_mychip_interrupt,                  SA_INTERRUPT|SA_SHIRQ, "My Chip",                  (void *)chip)) {          snd_mychip_free(chip);          printk(KERN_ERR "cannot grab irq %d\n", pci->irq);          return -EBUSY;  }  chip->irq = pci->irq;]]>          </programlisting>        </informalexample>        where <function>snd_mychip_interrupt()</function> is the      interrupt handler defined <link      linkend="pcm-interface-interrupt-handler"><citetitle>later</citetitle></link>.      Note that chip-&gt;irq should be defined      only when <function>request_irq()</function> succeeded.      </para>      <para>      On the PCI bus, the interrupts can be shared. Thus,      <constant>SA_SHIRQ</constant> is given as the interrupt flag of      <function>request_irq()</function>.       </para>      <para>        The last argument of <function>request_irq()</function> is the      data pointer passed to the interrupt handler. Usually, the      chip-specific record is used for that, but you can use what you      like, too.       </para>      <para>        I won't define the detail of the interrupt handler at this        point, but at least its appearance can be explained now. The        interrupt handler looks usually like the following:         <informalexample>          <programlisting><![CDATA[  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);          ....          return IRQ_HANDLED;  }]]>          </programlisting>        </informalexample>        Again the magic-cast is used here to get the correct pointer      from the second argument.       </para>      <para>        Now let's write the corresponding destructor for the resources      above. The role of destructor is simple: disable the hardware      (if already activated) and release the resources. So far, we      have no hardware part, so the disabling is not written here.       </para>      <para>        For releasing the resources, <quote>check-and-release</quote>        method is a safer way. For the i/o port, do like this:         <informalexample>          <programlisting><![CDATA[  if (chip->res_port) {          release_resource(chip->res_port);          kfree_nocheck(chip->res_port);  }]]>          </programlisting>        </informalexample>      </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.       </para>      <para>        For releasing the interrupt, do like this:        <informalexample>          <programlisting><![CDATA[  if (chip->irq >= 0)          free_irq(chip->irq, (void *)chip);]]>          </programlisting>        </informalexample>        And finally, release the chip-specific record.        <informalexample>          <programlisting><![CDATA[  snd_magic_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      set <parameter>__devexit</parameter> prefix for this destructor.       </para>      <para>      We didn't implement the hardware-disabling part in the above.      If you need to do this, please note that the destructor may be      called even before the initialization of the chip is completed.      It would be better to have a flag to skip the hardware-disabling      if the hardware was not initialized yet.      </para>      <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      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.      </para>      <para>        The management of a memory-mapped region is almost as same as        the management of an i/o port. You'll need three fields like        the following:         <informalexample>          <programlisting><![CDATA[  struct snd_mychip {          ....          unsigned long iobase_phys;          unsigned long iobase_virt;          struct resource *res_iobase;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
风流少妇一区二区| 亚洲综合色成人| 国产精品亚洲一区二区三区在线| 欧美一区二区三区爱爱| 久久成人免费网站| 久久影院午夜论| 成人av在线观| 亚洲五码中文字幕| 91麻豆精品91久久久久久清纯 | 91免费在线视频观看| 一区二区三区不卡在线观看 | 亚洲精选一二三| 欧美日韩一区二区三区不卡| 日韩av不卡在线观看| 久久网站热最新地址| 99精品国产99久久久久久白柏| 亚洲伦在线观看| 欧美一区二区在线免费观看| 国产成人在线免费观看| 夜夜嗨av一区二区三区中文字幕| 制服丝袜在线91| 国产成人免费高清| 亚洲国产一区视频| 久久无码av三级| 精品视频在线看| 国产揄拍国内精品对白| 亚洲一区在线视频观看| 欧美精品一区二区三区蜜桃| 99久久久精品免费观看国产蜜| 日韩精品免费视频人成| **性色生活片久久毛片| 日韩一区二区三区电影在线观看| 成人免费毛片app| 日韩成人免费电影| 亚洲图片另类小说| 欧美电影免费观看高清完整版在线观看| 国产传媒欧美日韩成人| 婷婷综合另类小说色区| 国产精品美女久久久久久| 日韩视频在线永久播放| 91高清视频在线| 国产xxx精品视频大全| 天天操天天综合网| 亚洲乱码国产乱码精品精可以看 | 在线观看视频91| 国产精品99久久久久久久女警| 亚洲国产精品自拍| 亚洲人成伊人成综合网小说| 久久一区二区三区四区| 91麻豆精品国产91久久久久| 91高清在线观看| 91最新地址在线播放| 国产美女精品在线| 麻豆传媒一区二区三区| 首页欧美精品中文字幕| 亚洲一区二区三区美女| 亚洲女同一区二区| 国产欧美日韩久久| 国产欧美日韩中文久久| 久久久久久久久久久久久久久99 | 色香蕉成人二区免费| 成人中文字幕合集| 国内成人自拍视频| 久久精品久久精品| 日本中文字幕不卡| 日本不卡视频一二三区| 亚洲aⅴ怡春院| 亚洲国产精品尤物yw在线观看| 一区二区激情小说| 亚洲欧美韩国综合色| 亚洲免费在线视频| 亚洲精品国产精华液| 亚洲色图色小说| 亚洲精品免费播放| 一区二区在线观看av| 樱桃国产成人精品视频| 一区二区三区毛片| 亚洲国产精品嫩草影院| 亚洲一区二区三区小说| 午夜日韩在线观看| 免费成人小视频| 久久精品99国产精品| 久草在线在线精品观看| 国产麻豆精品视频| 国产成+人+日韩+欧美+亚洲| 成人h动漫精品一区二区| 99这里只有久久精品视频| 91麻豆免费看片| 在线观看一区日韩| 7777精品伊人久久久大香线蕉 | 亚洲精品一区二区三区在线观看| 精品国产91乱码一区二区三区| 欧美精品一区二区三区很污很色的| 亚洲精品在线观看网站| 中文一区二区在线观看| 亚洲乱码中文字幕综合| 日韩精品一级中文字幕精品视频免费观看 | 国内不卡的二区三区中文字幕 | 丰满放荡岳乱妇91ww| 不卡高清视频专区| 色欧美片视频在线观看在线视频| 在线观看不卡视频| 欧美一区二区在线看| 国产午夜久久久久| 一区二区三区四区视频精品免费 | 午夜精品在线看| 精品一二三四在线| 99r精品视频| 91精品国产麻豆| 中文字幕成人在线观看| 一区二区三区视频在线看| 日本成人在线看| 不卡视频在线观看| 日韩一级在线观看| 17c精品麻豆一区二区免费| 丝袜诱惑制服诱惑色一区在线观看| 国产一区二区三区四区在线观看 | 欧美日韩大陆一区二区| 久久人人爽人人爽| 亚洲综合色丁香婷婷六月图片| 韩国女主播成人在线| 欧美这里有精品| 久久久久久久电影| 一区二区三区精品| 国产在线乱码一区二区三区| 欧美亚洲精品一区| 日本一区二区免费在线| 午夜精品aaa| 99re在线视频这里只有精品| 日韩女同互慰一区二区| 亚洲一区二区美女| 99视频有精品| 久久久久免费观看| 日本 国产 欧美色综合| 色婷婷综合久久久久中文一区二区 | 精品国产乱码久久久久久夜甘婷婷| 亚洲欧洲综合另类| 国产精品夜夜嗨| 日韩欧美一区二区不卡| 亚洲高清视频的网址| 91亚洲男人天堂| 国产性天天综合网| 精品写真视频在线观看| 欧美日本在线看| 亚洲人成网站精品片在线观看| 国产一区二区电影| 欧美电影免费提供在线观看| 调教+趴+乳夹+国产+精品| 日本精品免费观看高清观看| 欧美国产精品一区二区| 国产在线播放一区| 欧美不卡一二三| 精品一区二区三区免费视频| 91精选在线观看| 日欧美一区二区| 欧美电影在线免费观看| 一区二区三区日韩精品视频| 99精品在线免费| 1024成人网| 色呦呦国产精品| 亚洲人成在线观看一区二区| 成人99免费视频| 国产精品乱码久久久久久| 成人小视频免费在线观看| 久久久久久久综合色一本| 国产曰批免费观看久久久| 久久久久国产精品厨房| 国产成人在线视频免费播放| 欧美激情一区二区在线| 成人免费的视频| 亚洲欧洲一区二区三区| 色欧美88888久久久久久影院| 亚洲免费在线观看| 欧洲av在线精品| 日韩高清不卡一区二区三区| 91精品欧美综合在线观看最新| 蓝色福利精品导航| 久久久久一区二区三区四区| 国产高清成人在线| 亚洲欧洲av色图| 欧美日韩成人综合| 久久精品国产澳门| 久久久国产一区二区三区四区小说| 国产99久久久国产精品免费看| 中文字幕高清不卡| 在线精品视频免费观看| 日韩av电影免费观看高清完整版在线观看 | 欧美一区二区二区| 国产美女精品在线| 国产精品久久久久久妇女6080 | 精品免费国产二区三区| 国产夫妻精品视频| 亚洲自拍都市欧美小说| 日韩欧美一区中文| 成人午夜视频在线观看| 亚洲国产人成综合网站| 亚洲精品一线二线三线| 日本韩国视频一区二区| 美女一区二区视频| 亚洲视频免费在线观看|