# SOME DESCRIPTIVE TITLE # Copyright (C) YEAR The FreeBSD Project # This file is distributed under the same license as the FreeBSD Documentation package. # Vladlen Popolitov , 2025. msgid "" msgstr "" "Project-Id-Version: FreeBSD Documentation VERSION\n" "POT-Creation-Date: 2025-05-01 19:56-0300\n" "PO-Revision-Date: 2025-07-03 04:45+0000\n" "Last-Translator: Vladlen Popolitov \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.17\n" #. type: Title = #: documentation/content/en/books/arch-handbook/pci/_index.adoc:1 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:14 #, no-wrap msgid "PCI Devices" msgstr "Устройства PCI" #. type: YAML Front Matter: title #: documentation/content/en/books/arch-handbook/pci/_index.adoc:1 #, no-wrap msgid "Chapter 11. PCI Devices" msgstr "Глава 11. Устройства PCI" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:52 msgid "" "This chapter will talk about the FreeBSD mechanisms for writing a device " "driver for a device on a PCI bus." msgstr "" "Эта глава расскажет о механизмах FreeBSD для написания драйвера устройства " "на шине PCI." #. type: Title == #: documentation/content/en/books/arch-handbook/pci/_index.adoc:54 #, no-wrap msgid "Probe and Attach" msgstr "Обнаружение и подключение" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:57 msgid "" "Information here about how the PCI bus code iterates through the unattached " "devices and see if a newly loaded kld will attach to any of them." msgstr "" "Информация о том, как код шины PCI перебирает неприсоединённые устройства и " "проверяет, сможет ли только что загруженный kld присоединиться к любому из " "них." #. type: Title === #: documentation/content/en/books/arch-handbook/pci/_index.adoc:58 #, no-wrap msgid "Sample Driver Source ([.filename]#mypci.c#)" msgstr "Пример исходного кода драйвера ([.filename]#mypci.c#)" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:67 #, no-wrap msgid "" "/*\n" " * Simple KLD to play with the PCI functions.\n" " *\n" " * Murray Stokely\n" " */\n" msgstr "" "/*\n" " * Simple KLD to play with the PCI functions.\n" " *\n" " * Murray Stokely\n" " */\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:77 #, no-wrap msgid "" "#include \t\t/* defines used in kernel.h */\n" "#include \n" "#include \n" "#include \n" "#include \t\t/* types used in module initialization */\n" "#include \t\t/* cdevsw struct */\n" "#include \t\t/* uio struct */\n" "#include \n" "#include \t\t/* structs, prototypes for pci bus stuff and DEVMETHOD macros! */\n" msgstr "" "#include \t\t/* defines used in kernel.h */\n" "#include \n" "#include \n" "#include \n" "#include \t\t/* types used in module initialization */\n" "#include \t\t/* cdevsw struct */\n" "#include \t\t/* uio struct */\n" "#include \n" "#include \t\t/* structs, prototypes for pci bus stuff and " "DEVMETHOD macros! */\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:81 #, no-wrap msgid "" "#include \n" "#include \n" "#include \n" msgstr "" "#include \n" "#include \n" "#include \n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:84 #, no-wrap msgid "" "#include \t/* For pci_get macros! */\n" "#include \n" msgstr "" "#include \t/* For pci_get macros! */\n" "#include \n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:90 #, no-wrap msgid "" "/* The softc holds our per-instance data. */\n" "struct mypci_softc {\n" "\tdevice_t\tmy_dev;\n" "\tstruct cdev\t*my_cdev;\n" "};\n" msgstr "" "/* The softc holds our per-instance data. */\n" "struct mypci_softc {\n" "\tdevice_t\tmy_dev;\n" "\tstruct cdev\t*my_cdev;\n" "};\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:96 #, no-wrap msgid "" "/* Function prototypes */\n" "static d_open_t\t\tmypci_open;\n" "static d_close_t\tmypci_close;\n" "static d_read_t\t\tmypci_read;\n" "static d_write_t\tmypci_write;\n" msgstr "" "/* Function prototypes */\n" "static d_open_t\t\tmypci_open;\n" "static d_close_t\tmypci_close;\n" "static d_read_t\t\tmypci_read;\n" "static d_write_t\tmypci_write;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:98 #, no-wrap msgid "/* Character device entry points */\n" msgstr "/* Character device entry points */\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:107 #, no-wrap msgid "" "static struct cdevsw mypci_cdevsw = {\n" "\t.d_version =\tD_VERSION,\n" "\t.d_open =\tmypci_open,\n" "\t.d_close =\tmypci_close,\n" "\t.d_read =\tmypci_read,\n" "\t.d_write =\tmypci_write,\n" "\t.d_name =\t\"mypci\",\n" "};\n" msgstr "" "static struct cdevsw mypci_cdevsw = {\n" "\t.d_version =\tD_VERSION,\n" "\t.d_open =\tmypci_open,\n" "\t.d_close =\tmypci_close,\n" "\t.d_read =\tmypci_read,\n" "\t.d_write =\tmypci_write,\n" "\t.d_name =\t\"mypci\",\n" "};\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:113 #, no-wrap msgid "" "/*\n" " * In the cdevsw routines, we find our softc by using the si_drv1 member\n" " * of struct cdev. We set this variable to point to our softc in our\n" " * attach routine when we create the /dev entry.\n" " */\n" msgstr "" "/*\n" " * In the cdevsw routines, we find our softc by using the si_drv1 member\n" " * of struct cdev. We set this variable to point to our softc in our\n" " * attach routine when we create the /dev entry.\n" " */\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:118 #, no-wrap msgid "" "int\n" "mypci_open(struct cdev *dev, int oflags, int devtype, struct thread *td)\n" "{\n" "\tstruct mypci_softc *sc;\n" msgstr "" "int\n" "mypci_open(struct cdev *dev, int oflags, int devtype, struct thread *td)\n" "{\n" "\tstruct mypci_softc *sc;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:124 #, no-wrap msgid "" "\t/* Look up our softc. */\n" "\tsc = dev->si_drv1;\n" "\tdevice_printf(sc->my_dev, \"Opened successfully.\\n\");\n" "\treturn (0);\n" "}\n" msgstr "" "\t/* Look up our softc. */\n" "\tsc = dev->si_drv1;\n" "\tdevice_printf(sc->my_dev, \"Opened successfully.\\n" "\");\n" "\treturn (0);\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:129 #, no-wrap msgid "" "int\n" "mypci_close(struct cdev *dev, int fflag, int devtype, struct thread *td)\n" "{\n" "\tstruct mypci_softc *sc;\n" msgstr "" "int\n" "mypci_close(struct cdev *dev, int fflag, int devtype, struct thread *td)\n" "{\n" "\tstruct mypci_softc *sc;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:135 #, no-wrap msgid "" "\t/* Look up our softc. */\n" "\tsc = dev->si_drv1;\n" "\tdevice_printf(sc->my_dev, \"Closed.\\n\");\n" "\treturn (0);\n" "}\n" msgstr "" "\t/* Look up our softc. */\n" "\tsc = dev->si_drv1;\n" "\tdevice_printf(sc->my_dev, \"Closed.\\n" "\");\n" "\treturn (0);\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:140 #, no-wrap msgid "" "int\n" "mypci_read(struct cdev *dev, struct uio *uio, int ioflag)\n" "{\n" "\tstruct mypci_softc *sc;\n" msgstr "" "int\n" "mypci_read(struct cdev *dev, struct uio *uio, int ioflag)\n" "{\n" "\tstruct mypci_softc *sc;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:146 #, no-wrap msgid "" "\t/* Look up our softc. */\n" "\tsc = dev->si_drv1;\n" "\tdevice_printf(sc->my_dev, \"Asked to read %zd bytes.\\n\", uio->uio_resid);\n" "\treturn (0);\n" "}\n" msgstr "" "\t/* Look up our softc. */\n" "\tsc = dev->si_drv1;\n" "\tdevice_printf(sc->my_dev, \"Asked to read %zd bytes.\\n" "\", uio->uio_resid);\n" "\treturn (0);\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:151 #, no-wrap msgid "" "int\n" "mypci_write(struct cdev *dev, struct uio *uio, int ioflag)\n" "{\n" "\tstruct mypci_softc *sc;\n" msgstr "" "int\n" "mypci_write(struct cdev *dev, struct uio *uio, int ioflag)\n" "{\n" "\tstruct mypci_softc *sc;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:157 #, no-wrap msgid "" "\t/* Look up our softc. */\n" "\tsc = dev->si_drv1;\n" "\tdevice_printf(sc->my_dev, \"Asked to write %zd bytes.\\n\", uio->uio_resid);\n" "\treturn (0);\n" "}\n" msgstr "" "\t/* Look up our softc. */\n" "\tsc = dev->si_drv1;\n" "\tdevice_printf(sc->my_dev, \"Asked to write %zd bytes.\\n" "\", uio->uio_resid);\n" "\treturn (0);\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:159 #, no-wrap msgid "/* PCI Support Functions */\n" msgstr "/* PCI Support Functions */\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:167 #, no-wrap msgid "" "/*\n" " * Compare the device ID of this device against the IDs that this driver\n" " * supports. If there is a match, set the description and return success.\n" " */\n" "static int\n" "mypci_probe(device_t dev)\n" "{\n" msgstr "" "/*\n" " * Compare the device ID of this device against the IDs that this driver\n" " * supports. If there is a match, set the description and return success.\n" " */\n" "static int\n" "mypci_probe(device_t dev)\n" "{\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:170 #, no-wrap msgid "" "\tdevice_printf(dev, \"MyPCI Probe\\nVendor ID : 0x%x\\nDevice ID : 0x%x\\n\",\n" "\t pci_get_vendor(dev), pci_get_device(dev));\n" msgstr "" "\tdevice_printf(dev, \"MyPCI Probe\\n" "Vendor ID : 0x%x\\n" "Device ID : 0x%x\\n" "\",\n" "\t pci_get_vendor(dev), pci_get_device(dev));\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:178 #, no-wrap msgid "" "\tif (pci_get_vendor(dev) == 0x11c1) {\n" "\t\tprintf(\"We've got the Winmodem, probe successful!\\n\");\n" "\t\tdevice_set_desc(dev, \"WinModem\");\n" "\t\treturn (BUS_PROBE_DEFAULT);\n" "\t}\n" "\treturn (ENXIO);\n" "}\n" msgstr "" "\tif (pci_get_vendor(dev) == 0x11c1) {\n" "\t\tprintf(\"We've got the Winmodem, probe successful!\\n" "\");\n" "\t\tdevice_set_desc(dev, \"WinModem\");\n" "\t\treturn (BUS_PROBE_DEFAULT);\n" "\t}\n" "\treturn (ENXIO);\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:180 #, no-wrap msgid "/* Attach function is only called if the probe is successful. */\n" msgstr "/* Attach function is only called if the probe is successful. */\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:185 #, no-wrap msgid "" "static int\n" "mypci_attach(device_t dev)\n" "{\n" "\tstruct mypci_softc *sc;\n" msgstr "" "static int\n" "mypci_attach(device_t dev)\n" "{\n" "\tstruct mypci_softc *sc;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:187 #, no-wrap msgid "\tprintf(\"MyPCI Attach for : deviceID : 0x%x\\n\", pci_get_devid(dev));\n" msgstr "" "\tprintf(\"MyPCI Attach for : deviceID : 0x%x\\n" "\", pci_get_devid(dev));\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:191 #, no-wrap msgid "" "\t/* Look up our softc and initialize its fields. */\n" "\tsc = device_get_softc(dev);\n" "\tsc->my_dev = dev;\n" msgstr "" "\t/* Look up our softc and initialize its fields. */\n" "\tsc = device_get_softc(dev);\n" "\tsc->my_dev = dev;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:204 #, no-wrap msgid "" "\t/*\n" "\t * Create a /dev entry for this device. The kernel will assign us\n" "\t * a major number automatically. We use the unit number of this\n" "\t * device as the minor number and name the character device\n" "\t * \"mypci\".\n" "\t */\n" "\tsc->my_cdev = make_dev(&mypci_cdevsw, device_get_unit(dev),\n" "\t UID_ROOT, GID_WHEEL, 0600, \"mypci%u\", device_get_unit(dev));\n" "\tsc->my_cdev->si_drv1 = sc;\n" "\tprintf(\"Mypci device loaded.\\n\");\n" "\treturn (0);\n" "}\n" msgstr "" "\t/*\n" "\t * Create a /dev entry for this device. The kernel will assign us\n" "\t * a major number automatically. We use the unit number of this\n" "\t * device as the minor number and name the character device\n" "\t * \"mypci\".\n" "\t */\n" "\tsc->my_cdev = make_dev(&mypci_cdevsw, device_get_unit(dev),\n" "\t UID_ROOT, GID_WHEEL, 0600, \"mypci%u\", device_get_unit(dev));\n" "\tsc->my_cdev->si_drv1 = sc;\n" "\tprintf(\"Mypci device loaded.\\n" "\");\n" "\treturn (0);\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:206 #, no-wrap msgid "/* Detach device. */\n" msgstr "/* Detach device. */\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:211 #, no-wrap msgid "" "static int\n" "mypci_detach(device_t dev)\n" "{\n" "\tstruct mypci_softc *sc;\n" msgstr "" "static int\n" "mypci_detach(device_t dev)\n" "{\n" "\tstruct mypci_softc *sc;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:218 #, no-wrap msgid "" "\t/* Teardown the state in our softc created in our attach routine. */\n" "\tsc = device_get_softc(dev);\n" "\tdestroy_dev(sc->my_cdev);\n" "\tprintf(\"Mypci detach!\\n\");\n" "\treturn (0);\n" "}\n" msgstr "" "\t/* Teardown the state in our softc created in our attach routine. */\n" "\tsc = device_get_softc(dev);\n" "\tdestroy_dev(sc->my_cdev);\n" "\tprintf(\"Mypci detach!\\n" "\");\n" "\treturn (0);\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:220 #, no-wrap msgid "/* Called during system shutdown after sync. */\n" msgstr "/* Called during system shutdown after sync. */\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:224 #, no-wrap msgid "" "static int\n" "mypci_shutdown(device_t dev)\n" "{\n" msgstr "" "static int\n" "mypci_shutdown(device_t dev)\n" "{\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:228 #, no-wrap msgid "" "\tprintf(\"Mypci shutdown!\\n\");\n" "\treturn (0);\n" "}\n" msgstr "" "\tprintf(\"Mypci shutdown!\\n" "\");\n" "\treturn (0);\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:235 #, no-wrap msgid "" "/*\n" " * Device suspend routine.\n" " */\n" "static int\n" "mypci_suspend(device_t dev)\n" "{\n" msgstr "" "/*\n" " * Device suspend routine.\n" " */\n" "static int\n" "mypci_suspend(device_t dev)\n" "{\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:239 #, no-wrap msgid "" "\tprintf(\"Mypci suspend!\\n\");\n" "\treturn (0);\n" "}\n" msgstr "" "\tprintf(\"Mypci suspend!\\n" "\");\n" "\treturn (0);\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:246 #, no-wrap msgid "" "/*\n" " * Device resume routine.\n" " */\n" "static int\n" "mypci_resume(device_t dev)\n" "{\n" msgstr "" "/*\n" " * Device resume routine.\n" " */\n" "static int\n" "mypci_resume(device_t dev)\n" "{\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:250 #, no-wrap msgid "" "\tprintf(\"Mypci resume!\\n\");\n" "\treturn (0);\n" "}\n" msgstr "" "\tprintf(\"Mypci resume!\\n" "\");\n" "\treturn (0);\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:259 #, no-wrap msgid "" "static device_method_t mypci_methods[] = {\n" "\t/* Device interface */\n" "\tDEVMETHOD(device_probe,\t\tmypci_probe),\n" "\tDEVMETHOD(device_attach,\tmypci_attach),\n" "\tDEVMETHOD(device_detach,\tmypci_detach),\n" "\tDEVMETHOD(device_shutdown,\tmypci_shutdown),\n" "\tDEVMETHOD(device_suspend,\tmypci_suspend),\n" "\tDEVMETHOD(device_resume,\tmypci_resume),\n" msgstr "" "static device_method_t mypci_methods[] = {\n" "\t/* Device interface */\n" "\tDEVMETHOD(device_probe,\t\tmypci_probe),\n" "\tDEVMETHOD(device_attach,\tmypci_attach),\n" "\tDEVMETHOD(device_detach,\tmypci_detach),\n" "\tDEVMETHOD(device_shutdown,\tmypci_shutdown),\n" "\tDEVMETHOD(device_suspend,\tmypci_suspend),\n" "\tDEVMETHOD(device_resume,\tmypci_resume),\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:262 #, no-wrap msgid "" "\tDEVMETHOD_END\n" "};\n" msgstr "" "\tDEVMETHOD_END\n" "};\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:264 #, no-wrap msgid "static devclass_t mypci_devclass;\n" msgstr "static devclass_t mypci_devclass;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:267 #, no-wrap msgid "" "DEFINE_CLASS_0(mypci, mypci_driver, mypci_methods, sizeof(struct mypci_softc));\n" "DRIVER_MODULE(mypci, pci, mypci_driver, mypci_devclass, 0, 0);\n" msgstr "" "DEFINE_CLASS_0(mypci, mypci_driver, mypci_methods, sizeof(struct " "mypci_softc));\n" "DRIVER_MODULE(mypci, pci, mypci_driver, mypci_devclass, 0, 0);\n" #. type: Title === #: documentation/content/en/books/arch-handbook/pci/_index.adoc:269 #, no-wrap msgid "[.filename]#Makefile# for Sample Driver" msgstr "[.filename]#Makefile# для примера драйвера" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:274 #, no-wrap msgid "# Makefile for mypci driver\n" msgstr "# Makefile for mypci driver\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:278 #, no-wrap msgid "" "KMOD=\tmypci\n" "SRCS=\tmypci.c\n" "SRCS+=\tdevice_if.h bus_if.h pci_if.h\n" msgstr "" "KMOD=\tmypci\n" "SRCS=\tmypci.c\n" "SRCS+=\tdevice_if.h bus_if.h pci_if.h\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:280 #, no-wrap msgid ".include \n" msgstr ".include \n" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:283 msgid "" "If you place the above source file and [.filename]#Makefile# into a " "directory, you may run `make` to compile the sample driver. Additionally, " "you may run `make load` to load the driver into the currently running kernel " "and `make unload` to unload the driver after it is loaded." msgstr "" "Если вы поместите исходный файл выше и [.filename]#Makefile# в каталог, вы " "можете запустить `make` для компиляции примера драйвера. Дополнительно можно " "выполнить `make load` для загрузки драйвера в текущее ядро и `make unload` " "для выгрузки драйвера после его загрузки." #. type: Title === #: documentation/content/en/books/arch-handbook/pci/_index.adoc:284 #, no-wrap msgid "Additional Resources" msgstr "Дополнительные ресурсы" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:287 msgid "http://www.pcisig.org/[PCI Special Interest Group]" msgstr "http://www.pcisig.org/[Группа по стандартам PCI]" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:288 msgid "PCI System Architecture, Fourth Edition by Tom Shanley, et al." msgstr "PCI System Architecture, Fourth Edition by Tom Shanley, et al." #. type: Title == #: documentation/content/en/books/arch-handbook/pci/_index.adoc:290 #, no-wrap msgid "Bus Resources" msgstr "Ресурсы шины" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:293 msgid "" "FreeBSD provides an object-oriented mechanism for requesting resources from " "a parent bus. Almost all devices will be a child member of some sort of bus " "(PCI, ISA, USB, SCSI, etc) and these devices need to acquire resources from " "their parent bus (such as memory segments, interrupt lines, or DMA channels)." msgstr "" "FreeBSD предоставляет объектно-ориентированный механизм для запроса ресурсов " "от родительской шины. Почти все устройства будут дочерними элементами какого-" "либо типа шины (PCI, ISA, USB, SCSI и т.д.), и этим устройствам необходимо " "получать ресурсы от своей родительской шины (такие как сегменты памяти, " "линии прерываний или каналы DMA)." #. type: Title === #: documentation/content/en/books/arch-handbook/pci/_index.adoc:294 #, no-wrap msgid "Base Address Registers" msgstr "Регистры базовых адресов" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:297 msgid "" "To do anything particularly useful with a PCI device you will need to obtain " "the _Base Address Registers_ (BARs) from the PCI Configuration space. The " "PCI-specific details of obtaining the BAR are abstracted in the " "`bus_alloc_resource()` function." msgstr "" "Для выполнения каких-либо полезных действий с устройством PCI необходимо " "получить _регистры базовых адресов_ (BAR) из конфигурационного пространства " "PCI. Специфичные для PCI детали получения BAR абстрагированы в функции " "`bus_alloc_resource()`." #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:299 msgid "" "For example, a typical driver might have something similar to this in the " "`attach()` function:" msgstr "" "Например, типичный драйвер может содержать что-то подобное в функции " "`attach()`:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:310 #, no-wrap msgid "" " sc->bar0id = PCIR_BAR(0);\n" " sc->bar0res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->bar0id,\n" "\t\t\t\t 0, ~0, 1, RF_ACTIVE);\n" " if (sc->bar0res == NULL) {\n" " printf(\"Memory allocation of PCI base register 0 failed!\\n\");\n" " error = ENXIO;\n" " goto fail1;\n" " }\n" msgstr "" " sc->bar0id = PCIR_BAR(0);\n" " sc->bar0res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->bar0id,\n" "\t\t\t\t 0, ~0, 1, RF_ACTIVE);\n" " if (sc->bar0res == NULL) {\n" " printf(\"Memory allocation of PCI base register 0 failed!\\n" "\");\n" " error = ENXIO;\n" " goto fail1;\n" " }\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:323 #, no-wrap msgid "" " sc->bar1id = PCIR_BAR(1);\n" " sc->bar1res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->bar1id,\n" "\t\t\t\t 0, ~0, 1, RF_ACTIVE);\n" " if (sc->bar1res == NULL) {\n" " printf(\"Memory allocation of PCI base register 1 failed!\\n\");\n" " error = ENXIO;\n" " goto fail2;\n" " }\n" " sc->bar0_bt = rman_get_bustag(sc->bar0res);\n" " sc->bar0_bh = rman_get_bushandle(sc->bar0res);\n" " sc->bar1_bt = rman_get_bustag(sc->bar1res);\n" " sc->bar1_bh = rman_get_bushandle(sc->bar1res);\n" msgstr "" " sc->bar1id = PCIR_BAR(1);\n" " sc->bar1res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->bar1id,\n" "\t\t\t\t 0, ~0, 1, RF_ACTIVE);\n" " if (sc->bar1res == NULL) {\n" " printf(\"Memory allocation of PCI base register 1 failed!\\n" "\");\n" " error = ENXIO;\n" " goto fail2;\n" " }\n" " sc->bar0_bt = rman_get_bustag(sc->bar0res);\n" " sc->bar0_bh = rman_get_bushandle(sc->bar0res);\n" " sc->bar1_bt = rman_get_bustag(sc->bar1res);\n" " sc->bar1_bh = rman_get_bushandle(sc->bar1res);\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:326 msgid "" "Handles for each base address register are kept in the `softc` structure so " "that they can be used to write to the device later." msgstr "" "Дескрипторы для каждого регистра базовых адресов хранятся в структуре `softc`" ", чтобы их можно было использовать для записи на устройство в дальнейшем." #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:328 msgid "" "These handles can then be used to read or write from the device registers " "with the `bus_space_*` functions. For example, a driver might contain a " "shorthand function to read from a board specific register like this:" msgstr "" "Эти дескрипторы затем могут быть использованы для чтения или записи из " "регистров устройства с помощью функций `bus_space_*`. Например, драйвер " "может содержать сокращённую функцию для чтения из специфичного для платы " "регистра, как показано ниже:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:336 #, no-wrap msgid "" "uint16_t\n" "board_read(struct ni_softc *sc, uint16_t address)\n" "{\n" " return bus_space_read_2(sc->bar1_bt, sc->bar1_bh, address);\n" "}\n" msgstr "" "uint16_t\n" "board_read(struct ni_softc *sc, uint16_t address)\n" "{\n" " return bus_space_read_2(sc->bar1_bt, sc->bar1_bh, address);\n" "}\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:339 msgid "Similarly, one could write to the registers with:" msgstr "Аналогично, можно записать в регистры с помощью:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:347 #, no-wrap msgid "" "void\n" "board_write(struct ni_softc *sc, uint16_t address, uint16_t value)\n" "{\n" " bus_space_write_2(sc->bar1_bt, sc->bar1_bh, address, value);\n" "}\n" msgstr "" "void\n" "board_write(struct ni_softc *sc, uint16_t address, uint16_t value)\n" "{\n" " bus_space_write_2(sc->bar1_bt, sc->bar1_bh, address, value);\n" "}\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:350 msgid "" "These functions exist in 8bit, 16bit, and 32bit versions and you should use " "`bus_space_{read|write}_{1|2|4}` accordingly." msgstr "" "Эти функции существуют в 8-битных, 16-битных и 32-битных версиях, и вам " "следует использовать `bus_space_{read|write}_{1|2|4}` соответственно." #. type: delimited block = 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:354 msgid "" "In FreeBSD 7.0 and later, you can use the `bus_*` functions instead of " "`bus_space_*`. The `bus_*` functions take a struct resource * pointer " "instead of a bus tag and handle. Thus, you could drop the bus tag and bus " "handle members from the `softc` and rewrite the `board_read()` function as:" msgstr "" "В FreeBSD 7.0 и более поздних версиях вы можете использовать функции `bus_*` " "вместо `bus_space_*`. Функции `bus_*` принимают указатель на структуру " "resource * вместо тега шины и дескриптора. Таким образом, вы можете удалить " "тег шины и дескриптор шины из `softc` и переписать функцию `board_read()` " "как:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:362 #, no-wrap msgid "" "uint16_t\n" "board_read(struct ni_softc *sc, uint16_t address)\n" "{\n" "\treturn (bus_read(sc->bar1res, address));\n" "}\n" msgstr "" "uint16_t\n" "board_read(struct ni_softc *sc, uint16_t address)\n" "{\n" "\treturn (bus_read(sc->bar1res, address));\n" "}\n" #. type: Title === #: documentation/content/en/books/arch-handbook/pci/_index.adoc:366 #, no-wrap msgid "Interrupts" msgstr "Прерывания" #. type: delimited block = 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:369 msgid "" "Interrupts are allocated from the object-oriented bus code in a way similar " "to the memory resources. First an IRQ resource must be allocated from the " "parent bus, and then the interrupt handler must be set up to deal with this " "IRQ." msgstr "" "Прерывания выделяются объектно-ориентированным кодом шины аналогично " "ресурсам памяти. Сначала ресурс IRQ должен быть выделен из родительской " "шины, а затем должен быть настроен обработчик прерывания для работы с этим " "IRQ." #. type: delimited block = 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:371 msgid "Again, a sample from a device `attach()` function says more than words." msgstr "" "Вот пример из функции `attach()` устройства, который скажет больше, чем " "слова." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:375 #, no-wrap msgid "/* Get the IRQ resource */\n" msgstr "/* Get the IRQ resource */\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:384 #, no-wrap msgid "" " sc->irqid = 0x0;\n" " sc->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &(sc->irqid),\n" "\t\t\t\t 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);\n" " if (sc->irqres == NULL) {\n" "\tprintf(\"IRQ allocation failed!\\n\");\n" "\terror = ENXIO;\n" "\tgoto fail3;\n" " }\n" msgstr "" " sc->irqid = 0x0;\n" " sc->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &(sc->irqid),\n" "\t\t\t\t 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);\n" " if (sc->irqres == NULL) {\n" "\tprintf(\"IRQ allocation failed!\\n" "\");\n" "\terror = ENXIO;\n" "\tgoto fail3;\n" " }\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:386 #, no-wrap msgid " /* Now we should set up the interrupt handler */\n" msgstr " /* Now we should set up the interrupt handler */\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:393 #, no-wrap msgid "" " error = bus_setup_intr(dev, sc->irqres, INTR_TYPE_MISC,\n" "\t\t\t my_handler, sc, &(sc->handler));\n" " if (error) {\n" "\tprintf(\"Couldn't set up irq\\n\");\n" "\tgoto fail4;\n" " }\n" msgstr "" " error = bus_setup_intr(dev, sc->irqres, INTR_TYPE_MISC,\n" "\t\t\t my_handler, sc, &(sc->handler));\n" " if (error) {\n" "\tprintf(\"Couldn't set up irq\\n" "\");\n" "\tgoto fail4;\n" " }\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:396 msgid "" "Some care must be taken in the detach routine of the driver. You must " "quiesce the device's interrupt stream, and remove the interrupt handler. " "Once `bus_teardown_intr()` has returned, you know that your interrupt " "handler will no longer be called and that all threads that might have been " "executing this interrupt handler have returned. Since this function can " "sleep, you must not hold any mutexes when calling this function." msgstr "" "Некоторые меры предосторожности должны быть приняты в процедуре отключения " "драйвера. Необходимо остановить поток прерываний устройства и удалить " "обработчик прерываний. Как только `bus_teardown_intr()` завершится, можно " "быть уверенным, что обработчик прерываний больше не будет вызываться и все " "потоки, которые могли выполнять этот обработчик, завершили работу. Поскольку " "эта функция может засыпать, нельзя удерживать какие-либо мьютексы при её " "вызове." #. type: Title === #: documentation/content/en/books/arch-handbook/pci/_index.adoc:397 #, no-wrap msgid "DMA" msgstr "DMA" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:400 msgid "" "This section is obsolete, and present only for historical reasons. The " "proper methods for dealing with these issues is to use the " "`bus_space_dma*()` functions instead. This paragraph can be removed when " "this section is updated to reflect that usage. However, at the moment, the " "API is in a bit of flux, so once that settles down, it would be good to " "update this section to reflect that." msgstr "" "Этот раздел устарел и приведён только в исторических целях. Правильный " "способ решения этих проблем — использование функций `bus_space_dma*()`. Этот " "абзац можно удалить, когда раздел будет обновлён с учётом данного подхода. " "Однако на данный момент API находится в состоянии изменения, поэтому, когда " "он стабилизируется, будет полезно обновить этот раздел соответствующим " "образом." #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:402 msgid "" "On the PC, peripherals that want to do bus-mastering DMA must deal with " "physical addresses. This is a problem since FreeBSD uses virtual memory and " "deals almost exclusively with virtual addresses. Fortunately, there is a " "function, `vtophys()` to help." msgstr "" "На ПК периферийные устройства, которые хотят использовать DMA с управлением " "шиной, должны работать с физическими адресами. Это проблема, поскольку " "FreeBSD использует виртуальную память и работает почти исключительно с " "виртуальными адресами. К счастью, существует функция `vtophys()`, которая " "поможет." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:407 #, no-wrap msgid "" "#include \n" "#include \n" msgstr "" "#include \n" "#include \n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:409 #, no-wrap msgid "#define vtophys(virtual_address) (...)\n" msgstr "#define vtophys(virtual_address) (...)\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:412 msgid "" "The solution is a bit different on the alpha however, and what we really " "want is a function called `vtobus()`." msgstr "" "Однако решение немного отличается на alpha, и на самом деле нам нужна " "функция под названием `vtobus()`." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/pci/_index.adoc:420 #, no-wrap msgid "" "#if defined(__alpha__)\n" "#define vtobus(va) alpha_XXX_dmamap((vm_offset_t)va)\n" "#else\n" "#define vtobus(va) vtophys(va)\n" "#endif\n" msgstr "" "#if defined(__alpha__)\n" "#define vtobus(va) alpha_XXX_dmamap((vm_offset_t)va)\n" "#else\n" "#define vtobus(va) vtophys(va)\n" "#endif\n" #. type: Title === #: documentation/content/en/books/arch-handbook/pci/_index.adoc:422 #, no-wrap msgid "Deallocating Resources" msgstr "Освобождение ресурсов" #. type: Plain text #: documentation/content/en/books/arch-handbook/pci/_index.adoc:424 msgid "" "It is very important to deallocate all of the resources that were allocated " "during `attach()`. Care must be taken to deallocate the correct stuff even " "on a failure condition so that the system will remain usable while your " "driver dies." msgstr "" "Очень важно освободить все ресурсы, которые были выделены во время `attach()`" ". Необходимо внимательно следить за освобождением правильных ресурсов даже в " "случае ошибки, чтобы система оставалась работоспособной при завершении " "работы вашего драйвера."