· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
PCI Drivers



How to Write Linux PCI Drivers

ÀÌ ¹®¼­´Â /usr/src/linux-2.6.5/Documentation/pci.txt ¹®¼­¸¦ ¹ø¿ªÇÑ °ÍÀÔ´Ï´Ù. ¹ø¿ªÀÌ ¸Å²ô·´Áö ¸øÇÑ ºÎºÐµéÀº ¿ø¹®À» Âü°íÇϼż­ ÀÌÇØÇÏ½Ã±æ ¹Ù¶ø´Ï´Ù. :D



ÀúÀÚ Martin Mares < Mmj_at_ucw.czmj_at_ucw.cz > on 2000.02.07

¹ø¿ª ±è³²Çü < Mpastime_at_ece.uos.ac.krpastime_at_ece.uos.ac.kr > on 2004.05.05



PCI ÀÇ ¼¼°è´Â ±¤´ëÇÏ°í (º°·Î Áñ°ÌÁö ¾Ê°ÚÁö¸¸) ³î¶ó¿òÀ¸·Î °¡µæÇÏ´Ù. °¢°¢ÀÇ PCI ÀåÄ¡µéÀº ¼­·Î ´Ù¸¥ ¿ä±¸»çÇ×°ú ¹ö±×µéÀ» °¡Áø´Ù. À̶§¹®¿¡ ¸®´ª½º Ä¿³ÎÀÇ PCI Áö¿ø ·¹À̾î´Â ¿ì¸®°¡ ¹Ù¶ó´Â ¸¸Å­ °£´ÜÇÏÁö°¡ ¾Ê´Ù. ÀÌ ÂªÀº ±ÛÀº ÀáÀçÀûÀÎ ¸ðµç PCI µå¶óÀ̹ö °³¹ßÀڵ鿡°Ô PCI handling À̶ó´Â ±íÀº ½£¼Ó¿¡¼­ ÀڽŠ¸¸ÀÇ ±æÀ» ã¾Æ³»µµ·Ï µµ¿ÍÁÖ·Á°í ÇÑ´Ù.




1. PCI µå¶óÀ̹öÀÇ ±¸Á¶


2°¡Áö Á¾·ùÀÇ PCI µå¶óÀ̹ö°¡ Á¸ÀçÇÑ´Ù: ½Å½Ä (new-style) µå¶óÀ̹ö´Â ÀåÄ¡¸¦ °Ë»ö (probe) ÇÏ´Â ´ëºÎºÐÀÇ °úÁ¤À» PCI ·¹À̾°Ô ³Ñ°ÜÁÖ¾ú°í ÀåÄ¡ÀÇ ¿Â¶óÀÎ »ðÀÔ°ú Á¦°Å¸¦ Áö¿øÇÑ´Ù. (Áï PCI, hot-pluggable PCI, CardBus ¸¦ ÇϳªÀÇ µå¶óÀ̹ö·Î Áö¿øÇÑ´Ù) ´Ù¸¥ Çϳª´Â ±¸½Ä (old-style) µå¶óÀ̹öÀε¥ ¸ðµç ÀåÄ¡ °Ë»ö °úÁ¤À» ½º½º·Î ó¸®ÇÑ´Ù. ¸¸¾à ²À ±×·¡¾ß ÇÒ ÀÌÀ¯°¡ ¾ø´Ù¸é, »õ·Î ÀÛ¼ºÇÏ´Â Äڵ忡¼­ ±¸½ÄÀÇ ¹æ½ÄÀ» ÀÌ¿ëÇÏ¿© ÀåÄ¡ °Ë»öÀ» ¼öÇàÇÏÁö ¾Êµµ·Ï ÇÏÀÚ. ÀåÄ¡°¡ °Ë»öµÇ°í ³ª¸é µå¶óÀ̹ö´Â (±¸½ÄÀÌ´ø ½Å½ÄÀÌ´ø °£¿¡) ÀåÄ¡¸¦ µ¿ÀÛ½ÃÅ°°í ½Í¾îÇÑ´Ù. ±×·¯±â À§Çؼ­´Â ´ÙÀ½ °úÁ¤ÀÌ ÇÊ¿äÇÏ´Ù:

  • ÀåÄ¡¸¦ È°¼ºÈ­ÇÑ´Ù
  • ÀåÄ¡ÀÇ ¼³Á¤ °ø°£¿¡ Á¢±ÙÇÑ´Ù
  • ÀåÄ¡°¡ Á¦°øÇÏ´Â ÀÚ¿ø (ÁÖ¼Ò¿Í IRQ ¹øÈ£) ¸¦ ¾Ë¾Æ³½´Ù
  • ÀÌ ÀÚ¿øµéÀ» ÇÒ´çÇÑ´Ù
  • ÀåÄ¡¿Í Åë½ÅÇÑ´Ù

À̵éÀº ´ëºÎºÐ ´ÙÀ½ Àý¿¡¼­ ¼³¸íÇÑ´Ù. ³ª¸ÓÁö ºÎºÐÀº ÁÖ¼®ÀÌ Àß ´Þ·ÁÀÖ´Â <linux/pci.h> Äڵ带 º¸°Ô µÉ °ÍÀÌ´Ù.

¸¸¾à PCI subsystem ÀÌ ¼³Á¤µÇÁö ¾Ê¾Ò´Ù¸é (CONFIG_PCI °¡ n °ªÀ» °¡Áü) ´ÙÀ½¿¡ ¼Ò°³ÇÏ´Â ´ëºÎºÐÀÇ ÇÔ¼öµéÀº ³»¿ëÀÌ ¾ø´Â ÀζóÀÎ ÇÔ¼ö ȤÀº µå¶óÀ̹ö »óÀÇ ¸¹Àº ifdef µéÀ» ÇÇÇϱâ À§ÇÑ ÀûÀýÇÑ ¿¡·¯Äڵ带 ¸®ÅÏÇÏ´Â ÇÔ¼ö·Î Á¤ÀÇµÉ °ÍÀÌ´Ù.

2. ½Å½Ä (New-style) µå¶óÀ̹ö


½Å½Ä µå¶óÀ̹ö´Â ÃʱâÈ­ °úÁ¤¿¡¼­ ´ÜÁö ´ÙÀ½°ú °°Àº ¸â¹ö¸¦ Æ÷ÇÔÇÏ´Â µå¶óÀ̹ö¸¦ Ç¥ÇöÇϱâ À§ÇÑ ±¸Á¶Ã¼ (struct pci_driver) ÀÇ Æ÷ÀÎÅ͸¦ Àμö·Î pci_register_driver ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.

name µå¶óÀ̹ö À̸§
id_table µå¶óÀ̹ö°¡ ó¸®ÇÏ´Â µð¹ÙÀ̽º ID ÀÇ Å×À̺íÀÇ Æ÷ÀÎÅÍ. ´ëºÎºÐÀÇ µå¶óÀ̹ö¿¡¼­´Â ÀÌ Å×À̺íÀ» MODULE_DEVICE_TABLE(pci,...) ¸ÅÅ©·Î¸¦ ÀÌ¿ëÇؼ­ °ø°³ (export) ÇØ¾ß ÇÑ´Ù. ½Ã½ºÅÛÀÌ ¾Ë°íÀÖ´Â ¸ðµç PCI ÀåÄ¡µéÀÇ probe() ÇÔ¼ö¸¦ È£ÃâÇÒ ¶§´Â NULL ·Î ¼³Á¤Ç϶ó..?
probe ID Å×À̺í°ú ¸ÅÄ¡µÇ°í ¾ÆÁ÷ ´Ù¸¥ µå¶óÀ̹ö¿¡ ÀÇÇØ Ã³¸®µÇÁö ¾ÊÀº ¸ðµç ÀåÄ¡µé¿¡ ´ëÇÑ ÀåÄ¡ °Ë»ö ÇÔ¼öÀÇ Æ÷ÀÎÅÍ (±âÁ¸¿¡ Á¸ÀçÇÏ´ø ÀåÄ¡³ª ÀÌÈÄ¿¡ »õ·Ó°Ô Ãß°¡µÈ ÀåÄ¡¿¡ ´ëÇÏ¿© pci_register_driver ÇÔ¼ö°¡ ½ÇÇàµÇ´Â °úÁ¤¿¡¼­ È£ÃâµÊ). ÀÌ ÇÔ¼ö´Â ÀåÄ¡¸¦ ³ªÅ¸³»´Â pci_dev ±¸Á¶Ã¼ÀÇ Æ÷ÀÎÅÍ¿Í ÀåÄ¡¿Í ¸ÅÄ¡µÇ´Â ID Å×À̺íÀÇ ¿£Æ®¸®ÀÇ Æ÷ÀÎÅ͸¦ ÀÎÀÚ·Î ¹Þ´Â´Ù. ÀåÄ¡°¡ µå¶óÀ̹ö¸¦ ¼ö¶ôÇϸé (accepted) 0 À» ¹ÝȯÇÏ°í ±×·¸Áö ¾ÊÀ¸¸é (À½¼ö°ªÀÎ) ¿¡·¯ Äڵ带 ¹ÝȯÇÑ´Ù. ÀÌ ÇÔ¼ö´Â ¾ðÁ¦³ª process context ¿¡¼­ È£ÃâµÇ±â ¶§¹®¿¡ sleep ÇÒ ¼ö ÀÖ´Ù.
remove ÀÌ µå¶óÀ̹ö¿¡ ÀÇÇØ Ã³¸®µÇ´ø ÀåÄ¡°¡ Á¦°ÅµÉ ¶§¿¡ È£ÃâµÇ´Â ÇÔ¼öÀÇ Æ÷ÀÎÅÍ (µå¶óÀ̹öÀÇ µî·ÏÇØÁ¦ (deregistration) °úÁ¤À̳ª hot-pluggable ½½·Ô¿¡¼­ ±â°èÀûÀ¸·Î Á¦°ÅÇÑ °æ¿ì¿¡ È£ÃâµÊ). ÀÌ ÇÔ¼ö´Â ¾ðÁ¦³ª process context ¿¡¼­ È£ÃâµÇ±â ¶§¹®¿¡ sleep ÇÒ ¼ö ÀÖ´Ù.
save_state ÀåÄ¡°¡ ´ë±â ¸ðµå (suspend) ·Î µé¾î°¡±â Àü¿¡ »óÅ Á¤º¸¸¦ ÀúÀåÇÑ´Ù.
suspend ÀåÄ¡¸¦ ÀýÀü »óÅ (low-power state) ·Î ¸¸µç´Ù.
resume ÀåÄ¡¸¦ ÀýÀü »óÅ¿¡¼­ ±ú¾î³ª°Ô ÇÑ´Ù
enable_wake wake event ¸¦ ¸¸µé¾î¼­ ÀåÄ¡¸¦ ÀýÀü »óÅ·κÎÅÍ È°¼ºÈ­ ½ÃŲ´Ù.
(PCI Àü¿ø °ü¸®¿Í ±×¿¡ °ü·ÃµÈ ÇÔ¼öµéÀº Documentation/power/pci.txt ¸¦ Âü°íÇϱ⠹ٶõ´Ù)

ID Å×À̺íÀº ¸¶Áö¸·ÀÌ ¸ðµÎ 0 ÀÎ ¿£Æ®¸®·Î ³¡³ª´Â struct pci_device_id ÀÇ ¹è¿­ÀÌ´Ù. ÀÌ ±¸Á¶Ã¼´Â ´ÙÀ½°ú °°Àº ¸â¹öµéÀ» °¡Áø´Ù:

vendor, device ¸ÅÄ¡½Ãų Á¦Ç° °ø±ÞÀÚ¿Í ÀåÄ¡ ID (ȤÀº PCI_ANI_ID °ªÀ» °¡Áü)
subvendor, subdevice ¸ÅÄ¡½Ãų subsystem ÀÇ Á¦Ç° °ø±ÞÀÚ¿Í ÀåÄ¡ ID (ȤÀº PCI_ANI_ID °ªÀ» °¡Áü)
class, class_mask ¸ÅÄ¡½Ãų ÀåÄ¡ÀÇ Å¬·¡½º. class_mask ´Â ºñ±³½Ã ¾î¶² ºñÆ®µéÀ» °Ë»çÇØ¾ß ÇÏ´ÂÁö¸¦ ³ªÅ¸³¿
driver_data µå¶óÀ̹ö¸¶´Ù ÀÚüÀûÀ¸·Î »ç¿ëÇÏ´Â µ¥ÀÌÅÍ
´ëºÎºÐÀÇ µå¶óÀ̹ö¿¡¼­´Â driver_data ¸¦ »ç¿ëÇÒ ÇÊ¿ä°¡ ¾ø´Ù. driver_data ¸¦ »ç¿ëÇÏ´Â °¡Àå ÁÁÀº ¿¹·Î´Â µ¿ÀÏÇÑ ÀåÄ¡ ŸÀÔÀÇ Á¤ÀûÀÎ ¸®½ºÆ®ÀÇ À妽º·Î »ç¿ëÇÏ´Â °ÍÀÌ´Ù (Æ÷ÀÎÅÍ·Î »ç¿ëÇÏ´Â °ÍÀÌ ¾Æ´Ï´Ù).

½Ã½ºÅÛÀÌ ¾Ë°íÀÖ´Â ¸ðµç PCI ÀåÄ¡¿¡°Ô probe() °¡ È£ÃâµÇµµ·Ï ÇÏ·Á¸é Å×À̺íÀÇ ¿£Æ®¸®¸¦ {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID} ·Î ¸¸µé¸é µÈ´Ù.

/sys/bus/pci/drivers/{driver}/new_id ÆÄÀÏ¿¡ ¾²´Â °ÍÀ¸·Î ·±Å¸ÀÓ¿¡ µð¹ÙÀ̽º µå¶óÀ̹ö¿¡°Ô »õ·Î¿î PCI ID °¡ Ãß°¡µÉ ¼ö ÀÖ´Ù. ÀÏ´Ü Ãß°¡µÇ¸é, µå¶óÀ̹ö´Â ÀÌ°ÍÀ» Áö¿øÇÏ´Â ¸ðµç ÀåÄ¡¸¦ °Ë»ö (probe) ÇÒ °ÍÀÌ´Ù.

echo "vendor device subvendor subdevice class class_mask driver_data" > \ 
   /sys/bus/pci/drivers/{driver}/new_id 
  


(À§ÀÇ ¸ðµç ÇʵåµéÀº (0x À» »ý·«ÇÑ ÇüÅÂÀÇ) 16 Áø¼ö·Î ³Ñ°ÜÁø´Ù.)

»ç¿ëÀÚ´Â ´ÜÁö ÇÊ¿äÇÑ Çʵ常À» ³Ñ±æ ÇÊ¿ä°¡ ÀÖ´Ù; vendor, device, subvendor, subdevice Çʵå´Â ±âº»°ªÀ¸·Î PCI_ANY_ID (FFFFFFFF) ¸¦ °¡Áö°í class ¿Í classmask ´Â 0 À», driver_data Çʵå´Â OUL À» °¢°¢ ±âº»°ªÀ¸·Î °¡Áø´Ù. µð¹ÙÀ̽º µå¶óÀ̹ö´Â ÀÎÀÚ·Î ³Ñ°ÜÁø driver_data Çʵ带 À§Çؼ­ ´ÙÀ½ ÇÔ¼ö¸¦ ¹Ýµå½Ã È£ÃâÇØ¾ß ÇÑ´Ù.

pci_dynids_set_use_driver_data(pci_driver *, 1) 
  


±×·¸Áö ¾ÊÀ¸¸é ÇØ´ç Çʵå·Î´Â ´ÜÁö 0 ÀÌ ³Ñ°ÜÁø´Ù.

µå¶óÀ̹ö°¡ Á¦°ÅµÉ (exit) ¶§´Â, ´ÜÁö pci_unregister_driver() ÇÔ¼ö¸¦ È£ÃâÇÏ°í PCI ·¹À̾î´Â ÀÚµ¿ÀûÀ¸·Î ÀÌ µå¶óÀ̹ö¿¡°Ô 󸮵ǰí ÀÖ´ø ¸ðµç ÀåÄ¡¿¡ ´ëÇؼ­ remove hook ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.

ÃʱâÈ­ (initialization) ÇÔ¼ö¿Í Á¦°Å (clean-up) ÇÔ¼ö´Â (<linux/init.h> ¿¡ Á¤ÀÇµÈ ¸ÅÅ©·Î µéÀ» ÀÌ¿ëÇÏ¿©) ÀûÀýÈ÷ Ç¥½ÃÇØ Áֱ⠹ٶõ´Ù:

__init ÃʱâÈ­ ÄÚµå. µå¶óÀ̹ö°¡ ÃʱâÈ­ µÈ ÀÌÈÄ¿¡´Â »ç¶óÁø´Ù.
__exit Á¾·á ÄÚµå. ¸ðµâ·Î ÄÄÆÄÀÏ µÇÁö ¾ÊÀº µå¶óÀ̹ö¿¡¼­´Â ¹«½ÃµÈ´Ù.
__devinit ÀåÄ¡ ÃʱâÈ­ ÄÚµå. Ä¿³ÎÀÌ CONFIG_HOTPLUG °¡ ¼³Á¤µÇÁö ¾ÊÀº »óÅ·ΠÄÄÆÄÀÏ µÇ¾ú´Ù¸é __init ¿Í µ¿ÀÏÇÏ´Ù. ±×·¸Áö ¾ÊÀ¸¸é ÀÏ¹Ý ÇÔ¼öÀÌ´Ù.
devexit exit ¿Í µ¿ÀÏÇÏ´Ù.
ÆÁ:

module_init()/module_exit() ÇÔ¼öµé (±×¸®°í ¿ÀÁ÷ ¿©±â¼­¸¸ È£ÃâµÇ´Â ¸ðµç ÃʱâÈ­ ÇÔ¼öµé) Àº __init/exit ·Î Ç¥½Ã (mark) µÇ¾î¾ß ÇÑ´Ù. struct pci_driver ´Â ÀÌ·¯ÇÑ Å±׵é·Î Ç¥½ÃµÇ¸é ¾ÈµÈ´Ù. ID Å×ÀÌºí ¹è¿­Àº __devinitdata ·Î Ç¥½ÃµÇ¾î¾ß ÇÑ´Ù. probe() ¿Í remove() ÇÔ¼öµé (±×¸®°í ¿ÀÁ÷ ¿©±â¼­¸¸ È£ÃâµÇ´Â ¸ðµç ÃʱâÈ­ ÇÔ¼öµé) Àº __devinit/exit ·Î Ç¥½ÃµÇ¾î¾ß ÇÑ´Ù. ¸¸¾à µå¶óÀ̹ö°¡ hotplug ¸¦ Áö¿øÇÏ´Â µå¶óÀ̹ö°¡ ¾Æ´Ï¶ó°í È®½ÅÇÑ´Ù¸é ±×³É __init/exit ¿Í __initdata/exitdata ¸¸À» »ç¿ëÇ϶ó.

__devexit ·Î Ç¥½ÃµÈ ÇÔ¼ö¿¡ ´ëÇÑ Æ÷ÀÎÅÍ´Â ¹Ýµå½Ã __devexit_p(ÇÔ¼öÀ̸§) À» »ç¿ëÇÏ¿© »ý¼ºµÇ¾î¾ß ÇÑ´Ù. ÀÌ ¸ÅÅ©·Î´Â ÇÔ¼öÀ̸§À» »ý¼ºÇϰųª __devexit ·Î Ç¥½ÃµÈ ÇÔ¼ö°¡ ¹ö·ÁÁú (discard) °æ¿ì NULL À» ¹ÝȯÇÑ´Ù.

3. ¼öµ¿À¸·Î PCI ÀåÄ¡¸¦ °Ë»öÇÏ´Â ¹æ¹ý (±¸½Ä µå¶óÀ̹ö)


pci_register_driver() ÀÎÅÍÆäÀ̽º¸¦ ÀÌ¿ëÇÏÁö ¾Ê´Â PCI µå¶óÀ̹öÀÇ °æ¿ì¿¡´Â ´ÙÀ½°ú °°Àº ¹æ½ÄÀ¸·Î ¼öµ¿À¸·Î (manually) PCI ÀåÄ¡¸¦ °Ë»öÇÒ ¼ö ÀÖ´Ù:

Á¦Ç° °ø±ÞÀÚ¿Í ÀåÄ¡ ID °Ë»ö:

struct pci_dev *dev = NULL; 
while (dev = pci_find_device(VENDOR_ID, DEVICE_ID, dev)) 
    configure_device(dev); 
  


Ŭ·¡½º ID °Ë»ö (µ¿ÀÏÇÑ ¹æ½ÄÀ¸·Î ·çÇÁ¸¦ ÀÌ¿ë):

    pci_find_class(CLASS_ID, dev) 
  


Á¦Ç° °ø±ÞÀÚ/ÀåÄ¡ ID ¹× subsystem ÀÇ Á¦Ç° °ø±ÞÀÚ/ÀåÄ¡ ID °Ë»ö:

    pci_find_subsys(VENDOR_ID, DEVICE_ID, SUBSYS_VENDOR_ID, SUBSYS_DEVICE_ID, dev) 
  


VENDOR_ID ³ª DEVICE_ID À§Ä¡¿¡´Â ¿ÍÀϵå Ä«µå·Î PCI_ANY_ID ¶ó´Â »ó¼ö¸¦ ÀÌ¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì¿¡´Â ¿¹¸¦ µé¾î 'ƯÁ¤ °ø±ÞÀÚ°¡ Á¦°øÇÏ´Â ¸ðµç ÀåÄ¡' ¿Í °°Àº °Ë»öÀÌ °¡´ÉÇÏ°Ô µÈ´Ù.

ÀÌ ÇÔ¼öµéÀº hotplug ¿¡ ´ëÇؼ­ ¾ÈÀüÇÏÁö ¾Ê´Ù´Â (not hotplug-safe) °ÍÀ» ÁÖÀÇÇϱ⠹ٶõ´Ù. À§ÀÇ °¢ ÇÔ¼öµé¿¡ ´ëÇؼ­ hotplug ¸¦ ¾ÈÀüÇÏ°Ô Áö¿øÇÏ´Â ¹öÀüÀº pci_get_device(), pci_get_class(), pci_get_subsys() ÀÌ´Ù. ÀÌ ÇÔ¼öµéÀº ÀÚ½ÅÀÌ ¹ÝȯÇÏ´Â ÀåÄ¡¿¡ ÇØ´çÇÏ´Â pci_dev ±¸Á¶Ã¼ÀÇ ÂüÁ¶ Ƚ¼ö (reference count) ¸¦ Áõ°¡½ÃŲ´Ù. ÇØ´ç ÀåÄ¡¸¦ »ç¿ëÇÏÁö ¾ÊÀ» °æ¿ì¿¡´Â (¾Æ¸¶µµ ¸ðµâ ¾ð·Îµå½Ã) pci_dev_put() ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© ¹Ýµå½Ã ÀÌ ÀåÄ¡ÀÇ ÂüÁ¶ Ƚ¼ö¸¦ °¨¼Ò½ÃÄÑ¾ß ÇÑ´Ù.

4. ÀåÄ¡ È°¼ºÈ­Çϱâ


°Ë»öÇÑ ÀåÄ¡¸¦ ÀÌ¿ëÇؼ­ ¾î¶² ÀÛ¾÷À» ¼öÇàÇϱâ Àü¿¡, pci_enable_device() ÇÔ¼ö¸¦ ÀÌ¿ëÇØ ÀåÄ¡¸¦ È°¼ºÈ­ ½Ãų ÇÊ¿ä°¡ ÀÖ´Ù. ÀÌ ÇÔ¼ö´Â I/O ¿Í ¸Þ¸ð¸® ¿µ¿ªÀ» È°¼ºÈ­½ÃÅ°°í, ÇÊ¿äÇÑ °æ¿ì ÀÒÀº ÀÚ¿øµéÀ» ÇÒ´çÇϸç, ÀåÄ¡°¡ ÀýÀü »óÅ¿¡ ÀÖ¾ú´ø °æ¿ì¿¡´Â ±ú¾î³ªµµ·Ï ÇÑ´Ù. ÀÌ ÇÔ¼ö°¡ ½ÇÆÐÇÒ ¼öµµ ÀÖ´Ù´Â »ç½Ç¿¡ ÁÖÀÇÇϱ⠹ٶõ´Ù.

¸¸¾à ÀåÄ¡¸¦ buf mastering mode ·Î »ç¿ëÇÏ°í ½ÍÀº °æ¿ì¿¡´Â, pci_set_master() ÇÔ¼ö¸¦ È£ÃâÇؼ­ PCI_COMMAND ·¹Áö½ºÅÍÀÇ bus master ºñÆ®¸¦ È°¼ºÈ­ÇÏ°í, BIOS ¿¡ ÀÇÇØ ¾î¶² bogus ·Î ¼³Á¤µÈ °æ¿ì?? ·¹ÀÌÅϽà ŸÀÌ¸Ó °ªÀ» ¼öÁ¤ÇÑ´Ù.

¸¸¾à PCI Memory-Write-Invalidate Æ®·£Àè¼ÇÀ» »ç¿ëÇÏ°í ½ÍÀº °æ¿ì¿¡´Â pci_set_mwi() ÇÔ¼ö¸¦ È£ÃâÇ϶ó. ÀÌ ÇÔ¼ö´Â Mem-Wr-Inval ÀÇ PCI_COMMAND ºñÆ®¸¦ È°¼ºÈ­ÇÏ°í, cache inline size ·¹Áö½ºÅÍ°¡ ÀûÀýÇÏ°Ô ¼³Á¤µÇµµ·Ï ÇØÁØ´Ù. ¸ðµç ¾ÆÅ°ÅØó¿¡¼­ Memory-Write-Invalidate ¸¦ Áö¿øÇÏÁö´Â ¾Ê±â ¶§¹®¿¡, pci_set_mwi() ÀÇ ¸®ÅÏ°ªÀ» üũÇØ¾ß ÇÑ´Ù.

5. PCI ¼³Á¤ °ø°£¿¡ Á¢±ÙÇÏ´Â ¹æ¹ý


struct pci_dev * ·Î Ç¥ÇöµÇ´Â ÀåÄ¡ÀÇ ¼³Á¤ °ø°£¿¡ Á¢±ÙÇϱâ À§Çؼ­ pci_(read/write)_config_(byte|word|dword) ÇÔ¼ö¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ ÇÔ¼öµéÀº ¸ðµÎ ¼º°øÀÎ °æ¿ì¿¡ 0 À» ¸®ÅÏÇÏ°í, ½ÇÆÐÀÎ °æ¿ì pcibios_strerror ¿¡ ÀÇÇØ ¹®ÀÚ¿­·Î º¯È¯µÉ ¼ö ÀÖ´Â ¿¡·¯ ÄÚµå (PCIBIOS_... ÀÇ ÇüÅÂ) ¸¦ ¸®ÅÏÇÑ´Ù. ´ëºÎºÐÀÇ µå¶óÀ̹ö¿¡¼­ ¿Ã¹Ù¸¥ PCI ÀåÄ¡¿¡ Á¢±ÙÇÏ´Â °æ¿ì¿¡´Â ½ÇÆÐÇÏÁö ¾ÊÀ» °ÍÀÌ´Ù.

¸¸¾à °¡´ÉÇÑ struct pci_dev °¡ ¾ø´Â °æ¿ì¿¡´Â pci_bus(read|write)_config(byte|word|dword) ÇÔ¼ö¸¦ ÀÌ¿ëÇؼ­ ÇØ´ç ¹ö½º»óÀÇ ÀåÄ¡¿Í function ? ¿¡ Á¢±ÙÇÒ ¼ö ÀÖ´Ù.

¸¸¾à config header ÀÇ standard portion ÀÇ Çʵ忡 Á¢±ÙÇÏ´Â °æ¿ì¿¡´Â <linux/pci.h> ¿¡ ¼±¾ðµÈ ½Éº¼µéÀ» ÀÌ¿ëÇϱ⠹ٶõ´Ù.

¸¸¾à Extended PCI Capability ·¹Áö½ºÅÍ¿¡ Á¢±ÙÇÒ ÇÊ¿ä°¡ ÀÖ´Â °æ¿ì¿¡´Â ´ÜÁö ƯÁ¤ÇÑ capability ¸¦ À§ÇØ pci_find_capability() ¸¦ È£ÃâÇ϶ó. ±×·¯¸é ÀÌ ÇÔ¼ö´Â ÇØ´çÇÏ´Â ·¹Áö½ºÅÍ ºí·°À» ã¾ÆÁÙ °ÍÀÌ´Ù.

6. ÁÖ¼Ò¿Í ÀÎÅÍ·´Æ®


¸Þ¸ð¸®¿Í Æ÷Æ® ÁÖ¼Ò¿Í ÀÎÅÍ·´Æ® ¹øÈ£´Â ¼³Á¤ °ø°£À¸·Î ºÎÅÍ ÀÐÇôÁ®¼­´Â ¾ÈµÈ´Ù. ´ë½Å¿¡ Ä¿³Î¿¡ ÀÇÇØ ¸ÅÇÎµÈ struct pci_dev ÀÇ °ªÀ» »ç¿ëÇØ¾ß ÇÑ´Ù.

ÀåÄ¡ÀÇ ¸Þ¸ð¸®¿¡ Á¢±ÙÇÏ´Â ¹æ¹ýÀº Documentation/IO-mapping.txt ¸¦ ÂüÁ¶Çϱ⠹ٶõ´Ù.

´Ù¸¥ ´©±º°¡°¡ °°Àº ÀåÄ¡¸¦ »ç¿ëÇÏÁö ¾ÊÀ½À» ³ªÅ¸³»±â À§ÇØ I/O ¿µ¿ª¿¡ ´ëÇؼ­ request_region() ÇÔ¼ö¸¦, ¸Þ¸ð¸® ¿µ¿ª¿¡ ´ëÇؼ­ request_mem_region() ÇÔ¼ö¸¦ È£ÃâÇÒ ÇÊ¿ä°¡ ÀÖ´Ù.

¸ðµç ÀÎÅÍ·´Æ® Çڵ鷯´Â SA_SHIRQ Ç÷¡±×¿Í ÇÔ²² µî·ÏµÇ¾î ÀÖ¾î¾ß Çϸç, IRQ ¿Í ÀåÄ¡¸¦ ¸ÅÇÎÇϱâ À§Çؼ­ devid ¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù (¸ðµç PCI ÀÎÅÍ·´Æ®´Â °øÀ¯µÈ´Ù´Â °ÍÀ» ±â¾ïÇ϶ó).

7. ´Ù¸¥ Èï¹Ì·Î¿î ÇÔ¼öµé


pci_fiind_slot() ÁÖ¾îÁø ¹ö½º¿Í ½½·Ô ¹øÈ£¿¡ ´ëÀÀÇÏ´Â pci_dev ¸¦ ã´Â´Ù.
pci_set_power_state() PCI Power Management state (0=D0 ... 3=D3) ¸¦ ¼³Á¤ÇÑ´Ù.
pci_find_capability() ÀåÄ¡ÀÇ capability ¸®½ºÆ®·Î ºÎÅÍ Æ¯Á¤ÇÑ capability ¸¦ ã´Â´Ù.
pci_module_init() ¿Ã¹Ù¸¥ pci_driver ÀÇ ÃʱâÈ­¿Í ¿¡·¯ 󸮸¦ µµ¿ÍÁÖ´Â ÀζóÀÎ ÇÔ¼öÀÌ´Ù.
pci_resource_start() ÁÖ¾îÁø PCI ¿µ¿ª¿¡ ÇØ´çÇÏ´Â ¹ö½ºÀÇ ½ÃÀÛ ÁÖ¼Ò¸¦ ¸®ÅÏÇÑ´Ù.
pci_resource_end() ÁÖ¾îÁø PCI ¿µ¿ª¿¡ ÇØ´çÇÏ´Â ¹ö½ºÀÇ ¸¶Áö¸· ÁÖ¼Ò¸¦ ¸®ÅÏÇÑ´Ù.
pci_resource_len() PCI ¿µ¿ªÀÇ ¹ÙÀÌÆ® ±æÀ̸¦ ¸®ÅÏÇÑ´Ù.
pci_set_drvdata() pci_dev ¿¡ ´ëÇÑ private driver data Æ÷ÀÎÅ͸¦ ¼³Á¤ÇÑ´Ù.
pci_get_drvdata() pci_dev ¿¡ ´ëÇÑ private driver data Æ÷ÀÎÅ͸¦ ¾ò¾î¿Â´Ù.
pci_set_mwi() Memory-Write-Invalidate Æ®·£Àè¼ÇÀ» È°¼ºÈ­ÇÑ´Ù.
pci_clear_mwi() Memory-Write-Invalidate Æ®·£Àè¼ÇÀ» ºñÈ°¼ºÈ­ÇÑ´Ù.

8. ±× ¹ÛÀÇ ÈùÆ®µé


(µå¶óÀ̹ö¿¡¼­ »ç¿ëÀÚ¿¡°Ô ¾î¶² Ä«µå°¡ ¹ß°ßµÇ¾ú´ÂÁö¸¦ º¸¿©ÁÖ°í ½ÍÀº °æ¿ì¿Í °°ÀÌ) »ç¿ëÀÚ¿¡°Ô PCI ½½·Ô ³×ÀÓÀ» º¸¿©ÁÙ ¶§¿¡´Â pci_name(pci_dev) ¸¦ »ç¿ëÇϱ⠹ٶõ´Ù.

PCI ÀåÄ¡¸¦ ÂüÁ¶ÇÒ °æ¿ì¿¡´Â Ç×»ó struct pci_dev ÀÇ Æ÷ÀÎÅ͸¦ ÀÌ¿ëÇ϶ó. ¸ðµç PCI ·¹À̾î ÇÔ¼öµéÀº ÀÌ Á¤º¸¸¦ »ç¿ëÇϸç, ÀÌ°ÍÀÌ ¿ÀÁ÷ ¿Ã¹Ù¸¥ °ÍÀÌ´Ù. (semantics °¡ »ó´çÈ÷ º¹ÀâÇÑ multiple primary bus ¸¦ »ç¿ëÇÏ´Â ½Ã½ºÅÛ¿¡¼­¿Í °°ÀÌ) ¾ÆÁÖ Æ¯º°ÇÑ °æ¿ì°¡ ¾Æ´Ï¶ó¸é bus/slot/function ¹øÈ£¸¦ »ç¿ëÇÏÁö ¸»ÀÚ.

¸¸¾à PCI bus mastering DMA ¸¦ »ç¿ëÇÏ°íÀÚ ÇÒ °æ¿ì¿¡´Â, Documentation/DMA-mapping.txt ¸¦ Àо±â ¹Ù¶õ´Ù.

´ç½ÅÀÌ »ç¿ëÇÏ´Â ÀåÄ¡¿¡¼­ Fast Back to Back write ¸¦ ÄÑ·Á°í (turn on) ½ÃµµÇÏÁö ¸¶¶ó. ¹ö½º»óÀÇ ¸ðµç ÀåÄ¡µéÀÌ À̸¦ Áö¿øÇØ¾ß ÇϹǷÎ, ÀÌ°ÍÀº Ç÷§Æû°ú ÀϹÝÀûÀÎ ÄÚµå (generic code) ·Î ó¸®ÇÒ ÇÊ¿ä°¡ ÀÖ´Â °ÍÀÌÁö ÇϳªÀÇ µå¶óÀ̹ö Â÷¿ø¿¡¼­ ´Ù·ç¾î Á®¼­´Â ¾ÈµÈ´Ù.

9. »ç¿ëµÇÁö ¾Ê´Â ÇÔ¼öµé


¿À·¡µÈ µå¶óÀ̹ö¸¦ »õ·Î¿î PCI ÀÎÅÍÆäÀ̽º·Î Æ÷ÆÃÇÏ·Á°í ÇÒ ¶§ ÁÖÀÇÇØ¾ß ÇÒ ¸î°¡Áö ÇÔ¼öµéÀÌ ÀÖµû. À̵éÀº hotplug ³ª PCI domain À̳ª locking ¿¡ ȣȯµÇÁö ¾Ê±â ¶§¹®¿¡ ´õÀÌ»ó Ä¿³Î¿¡ Á¸ÀçÇÏÁö ¾Ê´Â °ÍµéÀÌ´Ù.

pcibios_present(), pci_present() ¿¹ÀüºÎÅÍ, PCI subsystem °ú Åë½ÅÇÏ·Á°í ÇÒ ¶§ ±×°ÍÀÌ Á¸ÀçÇÏ´ÂÁö Å×½ºÆ®ÇÒ ÇÊ¿ä°¡ ¾ø¾ú´Ù. ¸¸¾à Á¸ÀçÇÏÁö ¾Ê´Â´Ù¸é PCI ÀåÄ¡ÀÇ ¸®½ºÆ®´Â ºñ¾î ÀÖÀ» °ÍÀÌ°í ÀåÄ¡¸¦ °Ë»öÇÏ´Â ¸ðµç ÇÔ¼öµéÀº ´ÜÁö NULL À» ¸®ÅÏÇÒ °ÍÀÌ´Ù.
pcibios_(read|write)_* ´ëÀÀµÇ´Â pci_(read|write)_* ÇÔ¼öµé·Î ´ëüµÇ¾ú´Ù.
pcibios_find_* ´ëÀÀµÇ´Â pci_find_* ÇÔ¼öµé·Î ´ëüµÇ¾ú´Ù.
pci_for_each_dev() pci_find_device() ·Î ´ëüµÇ¾ú´Ù.
pci_for_each_dev_reverse() pci_find_device_reverse() ·Î ´ëüµÇ¾ú´Ù.
pci_for_each_bus() pci_find_next_bus() ·Î ´ëüµÇ¾ú´Ù.
pci_find_device() pci_get_device() ·Î ´ëüµÇ¾ú´Ù.
pci_find_subsys() pci_get_subsys() ·Î ´ëüµÇ¾ú´Ù.
pcibios_find_class() pci_find_class() ·Î ´ëüµÇ¾ú´Ù.
pci_(read|write)_*_nodev() pci_bus_(read|write)_*() ·Î ´ëüµÇ¾ú´Ù.




sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2005-05-01 21:20:29
Processing time 0.0087 sec