---- '''''How to Write Linux PCI Drivers''''' ÀÌ ¹®¼­´Â /usr/src/linux-2.6.5/Documentation/pci.txt ¹®¼­¸¦ ¹ø¿ªÇÑ °ÍÀÔ´Ï´Ù. ¹ø¿ªÀÌ ¸Å²ô·´Áö ¸øÇÑ ºÎºÐµéÀº ¿ø¹®À» Âü°íÇϼż­ ÀÌÇØÇÏ½Ã±æ ¹Ù¶ø´Ï´Ù. :D ---- ÀúÀÚ Martin Mares < [mailto:mj_at_ucw.czmj_at_ucw.cz] > on 2000.02.07 ¹ø¿ª ±è³²Çü < [mailto:pastime_at_ece.uos.ac.krpastime_at_ece.uos.ac.kr] > on 2004.05.05 ---- PCI ÀÇ ¼¼°è´Â ±¤´ëÇÏ°í (º°·Î Áñ°ÌÁö ¾Ê°ÚÁö¸¸) ³î¶ó¿òÀ¸·Î °¡µæÇÏ´Ù. °¢°¢ÀÇ PCI ÀåÄ¡µéÀº ¼­·Î ´Ù¸¥ ¿ä±¸»çÇ×°ú ¹ö±×µéÀ» °¡Áø´Ù. À̶§¹®¿¡ ¸®´ª½º Ä¿³ÎÀÇ PCI Áö¿ø ·¹À̾î´Â ¿ì¸®°¡ ¹Ù¶ó´Â ¸¸Å­ °£´ÜÇÏÁö°¡ ¾Ê´Ù. ÀÌ ÂªÀº ±ÛÀº ÀáÀçÀûÀÎ ¸ðµç PCI µå¶óÀ̹ö °³¹ßÀڵ鿡°Ô PCI handling À̶ó´Â ±íÀº ½£¼Ó¿¡¼­ ÀڽŠ¸¸ÀÇ ±æÀ» ã¾Æ³»µµ·Ï µµ¿ÍÁÖ·Á°í ÇÑ´Ù. ---- [[TableOfContents]] == PCI µå¶óÀ̹öÀÇ ±¸Á¶ == 2°¡Áö Á¾·ùÀÇ PCI µå¶óÀ̹ö°¡ Á¸ÀçÇÑ´Ù: ½Å½Ä (new-style) µå¶óÀ̹ö´Â ÀåÄ¡¸¦ °Ë»ö (probe) ÇÏ´Â ´ëºÎºÐÀÇ °úÁ¤À» PCI ·¹À̾°Ô ³Ñ°ÜÁÖ¾ú°í ÀåÄ¡ÀÇ ¿Â¶óÀÎ »ðÀÔ°ú Á¦°Å¸¦ Áö¿øÇÑ´Ù. (Áï ''PCI, hot-pluggable PCI, CardBus'' ¸¦ ÇϳªÀÇ µå¶óÀ̹ö·Î Áö¿øÇÑ´Ù) ´Ù¸¥ Çϳª´Â ±¸½Ä (old-style) µå¶óÀ̹öÀε¥ ¸ðµç ÀåÄ¡ °Ë»ö °úÁ¤À» ½º½º·Î ó¸®ÇÑ´Ù. ¸¸¾à ²À ±×·¡¾ß ÇÒ ÀÌÀ¯°¡ ¾ø´Ù¸é, »õ·Î ÀÛ¼ºÇÏ´Â Äڵ忡¼­ ±¸½ÄÀÇ ¹æ½ÄÀ» ÀÌ¿ëÇÏ¿© ÀåÄ¡ °Ë»öÀ» ¼öÇàÇÏÁö ¾Êµµ·Ï ÇÏÀÚ. ÀåÄ¡°¡ °Ë»öµÇ°í ³ª¸é µå¶óÀ̹ö´Â (±¸½ÄÀÌ´ø ½Å½ÄÀÌ´ø °£¿¡) ÀåÄ¡¸¦ µ¿ÀÛ½ÃÅ°°í ½Í¾îÇÑ´Ù. ±×·¯±â À§Çؼ­´Â ´ÙÀ½ °úÁ¤ÀÌ ÇÊ¿äÇÏ´Ù: * ÀåÄ¡¸¦ È°¼ºÈ­ÇÑ´Ù * ÀåÄ¡ÀÇ ¼³Á¤ °ø°£¿¡ Á¢±ÙÇÑ´Ù * ÀåÄ¡°¡ Á¦°øÇÏ´Â ÀÚ¿ø (ÁÖ¼Ò¿Í IRQ ¹øÈ£) ¸¦ ¾Ë¾Æ³½´Ù * ÀÌ ÀÚ¿øµéÀ» ÇÒ´çÇÑ´Ù * ÀåÄ¡¿Í Åë½ÅÇÑ´Ù À̵éÀº ´ëºÎºÐ ´ÙÀ½ Àý¿¡¼­ ¼³¸íÇÑ´Ù. ³ª¸ÓÁö ºÎºÐÀº ÁÖ¼®ÀÌ Àß ´Þ·ÁÀÖ´Â Äڵ带 º¸°Ô µÉ °ÍÀÌ´Ù. ¸¸¾à PCI subsystem ÀÌ ¼³Á¤µÇÁö ¾Ê¾Ò´Ù¸é (CONFIG_PCI °¡ n °ªÀ» °¡Áü) ´ÙÀ½¿¡ ¼Ò°³ÇÏ´Â ´ëºÎºÐÀÇ ÇÔ¼öµéÀº ³»¿ëÀÌ ¾ø´Â ÀζóÀÎ ÇÔ¼ö ȤÀº µå¶óÀ̹ö »óÀÇ ¸¹Àº ifdef µéÀ» ÇÇÇϱâ À§ÇÑ ÀûÀýÇÑ ¿¡·¯Äڵ带 ¸®ÅÏÇÏ´Â ÇÔ¼ö·Î Á¤ÀÇµÉ °ÍÀÌ´Ù. == ½Å½Ä (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) ÇÔ¼ö´Â ( ¿¡ Á¤ÀÇµÈ ¸ÅÅ©·Î µéÀ» ÀÌ¿ëÇÏ¿©) ÀûÀýÈ÷ Ç¥½ÃÇØ Áֱ⠹ٶõ´Ù: ||__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 À» ¹ÝȯÇÑ´Ù. == ¼öµ¿À¸·Î 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() ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© ¹Ýµå½Ã ÀÌ ÀåÄ¡ÀÇ ÂüÁ¶ Ƚ¼ö¸¦ °¨¼Ò½ÃÄÑ¾ß ÇÑ´Ù. == ÀåÄ¡ È°¼ºÈ­Çϱâ == °Ë»öÇÑ ÀåÄ¡¸¦ ÀÌ¿ëÇؼ­ ¾î¶² ÀÛ¾÷À» ¼öÇàÇϱâ Àü¿¡, 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() ÀÇ ¸®ÅÏ°ªÀ» üũÇØ¾ß ÇÑ´Ù. == 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 ÀÇ Çʵ忡 Á¢±ÙÇÏ´Â °æ¿ì¿¡´Â ¿¡ ¼±¾ðµÈ ½Éº¼µéÀ» ÀÌ¿ëÇϱ⠹ٶõ´Ù. ¸¸¾à Extended PCI Capability ·¹Áö½ºÅÍ¿¡ Á¢±ÙÇÒ ÇÊ¿ä°¡ ÀÖ´Â °æ¿ì¿¡´Â ´ÜÁö ƯÁ¤ÇÑ capability ¸¦ À§ÇØ pci_find_capability() ¸¦ È£ÃâÇ϶ó. ±×·¯¸é ÀÌ ÇÔ¼ö´Â ÇØ´çÇÏ´Â ·¹Áö½ºÅÍ ºí·°À» ã¾ÆÁÙ °ÍÀÌ´Ù. == ÁÖ¼Ò¿Í ÀÎÅÍ·´Æ® == ¸Þ¸ð¸®¿Í Æ÷Æ® ÁÖ¼Ò¿Í ÀÎÅÍ·´Æ® ¹øÈ£´Â ¼³Á¤ °ø°£À¸·Î ºÎÅÍ ÀÐÇôÁ®¼­´Â '''¾ÈµÈ´Ù'''. ´ë½Å¿¡ Ä¿³Î¿¡ ÀÇÇØ ¸ÅÇÎµÈ struct pci_dev ÀÇ °ªÀ» »ç¿ëÇØ¾ß ÇÑ´Ù. ÀåÄ¡ÀÇ ¸Þ¸ð¸®¿¡ Á¢±ÙÇÏ´Â ¹æ¹ýÀº Documentation/IO-mapping.txt ¸¦ ÂüÁ¶Çϱ⠹ٶõ´Ù. ´Ù¸¥ ´©±º°¡°¡ °°Àº ÀåÄ¡¸¦ »ç¿ëÇÏÁö ¾ÊÀ½À» ³ªÅ¸³»±â À§ÇØ I/O ¿µ¿ª¿¡ ´ëÇؼ­ request_region() ÇÔ¼ö¸¦, ¸Þ¸ð¸® ¿µ¿ª¿¡ ´ëÇؼ­ request_mem_region() ÇÔ¼ö¸¦ È£ÃâÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. ¸ðµç ÀÎÅÍ·´Æ® Çڵ鷯´Â SA_SHIRQ Ç÷¡±×¿Í ÇÔ²² µî·ÏµÇ¾î ÀÖ¾î¾ß Çϸç, IRQ ¿Í ÀåÄ¡¸¦ ¸ÅÇÎÇϱâ À§Çؼ­ devid ¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù (¸ðµç PCI ÀÎÅÍ·´Æ®´Â °øÀ¯µÈ´Ù´Â °ÍÀ» ±â¾ïÇ϶ó). == ´Ù¸¥ Èï¹Ì·Î¿î ÇÔ¼öµé == ||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 Æ®·£Àè¼ÇÀ» ºñÈ°¼ºÈ­ÇÑ´Ù. || == ±× ¹ÛÀÇ ÈùÆ®µé == (µå¶óÀ̹ö¿¡¼­ »ç¿ëÀÚ¿¡°Ô ¾î¶² Ä«µå°¡ ¹ß°ßµÇ¾ú´ÂÁö¸¦ º¸¿©ÁÖ°í ½ÍÀº °æ¿ì¿Í °°ÀÌ) »ç¿ëÀÚ¿¡°Ô 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) ·Î ó¸®ÇÒ ÇÊ¿ä°¡ ÀÖ´Â °ÍÀÌÁö ÇϳªÀÇ µå¶óÀ̹ö Â÷¿ø¿¡¼­ ´Ù·ç¾î Á®¼­´Â ¾ÈµÈ´Ù. == »ç¿ëµÇÁö ¾Ê´Â ÇÔ¼öµé == ¿À·¡µÈ µå¶óÀ̹ö¸¦ »õ·Î¿î 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)_*() ·Î ´ëüµÇ¾ú´Ù. || ----