# 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, 2026. msgid "" msgstr "" "Project-Id-Version: FreeBSD Documentation VERSION\n" "POT-Creation-Date: 2025-05-01 19:56-0300\n" "PO-Revision-Date: 2026-03-04 20:01+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/isa/_index.adoc:1 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:14 #, no-wrap msgid "ISA Device Drivers" msgstr "Драйверы устройств ISA" #. type: YAML Front Matter: title #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1 #, no-wrap msgid "Chapter 10. ISA Device Drivers" msgstr "Глава 10. Драйверы устройств ISA" #. type: Title == #: documentation/content/en/books/arch-handbook/isa/_index.adoc:52 #, no-wrap msgid "Synopsis" msgstr "Обзор" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:55 msgid "" "This chapter introduces the issues relevant to writing a driver for an ISA " "device. The pseudo-code presented here is rather detailed and reminiscent of " "the real code but is still only pseudo-code. It avoids the details " "irrelevant to the subject of the discussion. The real-life examples can be " "found in the source code of real drivers. In particular the drivers `ep` and " "`aha` are good sources of information." msgstr "" "Эта глава знакомит с вопросами, относящимся к написанию драйвера устройства " "ISA. Представленный здесь псевдокод довольно детализирован и напоминает " "реальный код, но всё же остаётся псевдокодом. Он избегает деталей, не " "относящихся к теме обсуждения. Реальные примеры можно найти в исходном коде " "настоящих драйверов. В частности, драйверы `ep` и `aha` являются хорошими " "источниками информации." #. type: Title == #: documentation/content/en/books/arch-handbook/isa/_index.adoc:57 #, no-wrap msgid "Basic Information" msgstr "Основная информация" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:60 msgid "A typical ISA driver would need the following include files:" msgstr "Типичному драйверу ISA могут потребоваться следующие включаемые файлы:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:68 #, no-wrap msgid "" "#include \n" "#include \n" "#include \n" "#include \n" "#include \n" msgstr "" "#include \n" "#include \n" "#include \n" "#include \n" "#include \n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:71 #, no-wrap msgid "" "#include \n" "#include \n" msgstr "" "#include \n" "#include \n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:74 msgid "They describe the things specific to the ISA and generic bus subsystem." msgstr "" "Они описывают особенности, специфичные для подсистемы ISA и обобщенной шины." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:76 msgid "" "The bus subsystem is implemented in an object-oriented fashion, its main " "structures are accessed by associated method functions." msgstr "" "Подсистема шины реализована в объектно-ориентированном стиле, её основные " "структуры доступны через методы, связанные с объектами." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:78 msgid "" "The list of bus methods implemented by an ISA driver is like one for any " "other bus. For a hypothetical driver named \"xxx\" they would be:" msgstr "" "Список методов шины, реализуемых драйвером ISA, аналогичен списку для любой " "другой шины. Для гипотетического драйвера с именем \"xxx\" они будут:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:80 msgid "" "`static void xxx_isa_identify (driver_t *, device_t);` Normally used for bus " "drivers, not device drivers. But for ISA devices this method may have " "special use: if the device provides some device-specific (non-PnP) way to " "auto-detect devices this routine may implement it." msgstr "" "`static void xxx_isa_identify (driver_t *, device_t);` Обычно используется " "для драйверов шины, а не для драйверов устройств. Однако для устройств ISA " "этот метод может иметь особое применение: если устройство предоставляет " "специфический (не PnP) способ автоматического обнаружения устройств, эта " "процедура может его реализовывать." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:81 msgid "" "`static int xxx_isa_probe (device_t dev);` Probe for a device at a known (or " "PnP) location. This routine can also accommodate device-specific auto-" "detection of parameters for partially configured devices." msgstr "" "`static int xxx_isa_probe (device_t dev);` Проверка наличия устройства в " "известном (или PnP) расположении. Эта процедура также может учитывать " "автоопределение параметров, специфичных для устройства, в случае частично " "настроенных устройств." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:82 msgid "" "`static int xxx_isa_attach (device_t dev);` Attach and initialize device." msgstr "" "`static int xxx_isa_attach (device_t dev);` Подключение и инициализация " "устройства." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:83 msgid "" "`static int xxx_isa_detach (device_t dev);` Detach device before unloading " "the driver module." msgstr "" "`static int xxx_isa_detach (device_t dev);` Отсоединение устройства перед " "выгрузкой модуля драйвера." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:84 msgid "" "`static int xxx_isa_shutdown (device_t dev);` Execute shutdown of the device " "before system shutdown." msgstr "" "`static int xxx_isa_shutdown (device_t dev);` Выполняет завершение работы " "устройства перед выключением системы." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:85 msgid "" "`static int xxx_isa_suspend (device_t dev);` Suspend the device before the " "system goes to the power-save state. May also abort transition to the power-" "save state." msgstr "" "`static int xxx_isa_suspend (device_t dev);` Приостанавливает устройство " "перед переходом системы в энергосберегающий режим. Также может прервать " "переход в энергосберегающий режим." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:86 msgid "" "`static int xxx_isa_resume (device_t dev);` Resume the device activity after " "return from power-save state." msgstr "" "`static int xxx_isa_resume (device_t dev);` Возобновляет активность " "устройства после возврата из энергосберегающего состояния." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:88 msgid "" "`xxx_isa_probe()` and `xxx_isa_attach()` are mandatory, the rest of the " "routines are optional, depending on the device's needs." msgstr "" "`xxx_isa_probe()` и `xxx_isa_attach()` являются обязательными, остальные " "процедуры опциональны и зависят от потребностей устройства." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:90 msgid "" "The driver is linked to the system with the following set of descriptions." msgstr "Драйвер связан с системой следующим набором описаний." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:104 #, no-wrap msgid "" " /* table of supported bus methods */\n" " static device_method_t xxx_isa_methods[] = {\n" " /* list all the bus method functions supported by the driver */\n" " /* omit the unsupported methods */\n" " DEVMETHOD(device_identify, xxx_isa_identify),\n" " DEVMETHOD(device_probe, xxx_isa_probe),\n" " DEVMETHOD(device_attach, xxx_isa_attach),\n" " DEVMETHOD(device_detach, xxx_isa_detach),\n" " DEVMETHOD(device_shutdown, xxx_isa_shutdown),\n" " DEVMETHOD(device_suspend, xxx_isa_suspend),\n" " DEVMETHOD(device_resume, xxx_isa_resume),\n" msgstr "" " /* table of supported bus methods */\n" " static device_method_t xxx_isa_methods[] = {\n" " /* list all the bus method functions supported by the driver */\n" " /* omit the unsupported methods */\n" " DEVMETHOD(device_identify, xxx_isa_identify),\n" " DEVMETHOD(device_probe, xxx_isa_probe),\n" " DEVMETHOD(device_attach, xxx_isa_attach),\n" " DEVMETHOD(device_detach, xxx_isa_detach),\n" " DEVMETHOD(device_shutdown, xxx_isa_shutdown),\n" " DEVMETHOD(device_suspend, xxx_isa_suspend),\n" " DEVMETHOD(device_resume, xxx_isa_resume),\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:107 #, no-wrap msgid "" "\tDEVMETHOD_END\n" " };\n" msgstr "" "\tDEVMETHOD_END\n" " };\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:113 #, no-wrap msgid "" " static driver_t xxx_isa_driver = {\n" " \"xxx\",\n" " xxx_isa_methods,\n" " sizeof(struct xxx_softc),\n" " };\n" msgstr "" " static driver_t xxx_isa_driver = {\n" " \"xxx\",\n" " xxx_isa_methods,\n" " sizeof(struct xxx_softc),\n" " };\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:115 #, no-wrap msgid " static devclass_t xxx_devclass;\n" msgstr " static devclass_t xxx_devclass;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:118 #, no-wrap msgid "" " DRIVER_MODULE(xxx, isa, xxx_isa_driver, xxx_devclass,\n" " load_function, load_argument);\n" msgstr "" " DRIVER_MODULE(xxx, isa, xxx_isa_driver, xxx_devclass,\n" " load_function, load_argument);\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:121 msgid "" "Here struct `xxx_softc` is a device-specific structure that contains private " "driver data and descriptors for the driver's resources. The bus code " "automatically allocates one softc descriptor per device as needed." msgstr "" "Здесь структура `xxx_softc` — это специфичная для устройства структура, " "которая содержит приватные данные драйвера и дескрипторы ресурсов драйвера. " "Код шины автоматически выделяет один дескриптор softc для каждого устройства " "по мере необходимости." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:123 msgid "" "If the driver is implemented as a loadable module then `load_function()` is " "called to do driver-specific initialization or clean-up when the driver is " "loaded or unloaded and load_argument is passed as one of its arguments. If " "the driver does not support dynamic loading (in other words it must always " "be linked into the kernel) then these values should be set to 0 and the last " "definition would look like:" msgstr "" "Если драйвер реализован в виде загружаемого модуля, то `load_function()` " "вызывается для выполнения специфичной для драйвера инициализации или очистки " "при загрузке или выгрузке драйвера, а `load_argument` передаётся в качестве " "одного из её аргументов. Если драйвер не поддерживает динамическую загрузку (" "другими словами, он всегда должен быть связан с ядром), то эти значения " "должны быть установлены в 0, и последнее определение будет выглядеть " "следующим образом:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:128 #, no-wrap msgid "" " DRIVER_MODULE(xxx, isa, xxx_isa_driver,\n" " xxx_devclass, 0, 0);\n" msgstr "" " DRIVER_MODULE(xxx, isa, xxx_isa_driver,\n" " xxx_devclass, 0, 0);\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:131 msgid "" "If the driver is for a device which supports PnP then a table of supported " "PnP IDs must be defined. The table consists of a list of PnP IDs supported " "by this driver and human-readable descriptions of the hardware types and " "models having these IDs. It looks like:" msgstr "" "Если драйвер предназначен для устройства с поддержкой PnP, то должна быть " "определена таблица поддерживаемых PnP ID. Таблица состоит из списка PnP ID, " "поддерживаемых этим драйвером, и удобочитаемых описаний типов аппаратного " "обеспечения и моделей, имеющих эти ID. Это выглядит следующим образом:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:140 #, no-wrap msgid "" " static struct isa_pnp_id xxx_pnp_ids[] = {\n" " /* a line for each supported PnP ID */\n" " { 0x12345678, \"Our device model 1234A\" },\n" " { 0x12345679, \"Our device model 1234B\" },\n" " { 0, NULL }, /* end of table */\n" " };\n" msgstr "" " static struct isa_pnp_id xxx_pnp_ids[] = {\n" " /* a line for each supported PnP ID */\n" " { 0x12345678, \"Our device model 1234A\" },\n" " { 0x12345679, \"Our device model 1234B\" },\n" " { 0, NULL }, /* end of table */\n" " };\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:143 msgid "" "If the driver does not support PnP devices it still needs an empty PnP ID " "table, like:" msgstr "" "Если драйвер не поддерживает устройства PnP, ему все равно нужна пустая " "таблица идентификаторов PnP, например:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:149 #, no-wrap msgid "" " static struct isa_pnp_id xxx_pnp_ids[] = {\n" " { 0, NULL }, /* end of table */\n" " };\n" msgstr "" " static struct isa_pnp_id xxx_pnp_ids[] = {\n" " { 0, NULL }, /* end of table */\n" " };\n" #. type: Title == #: documentation/content/en/books/arch-handbook/isa/_index.adoc:152 #, no-wrap msgid "`device_t` Pointer" msgstr "Указатель `device_t`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:155 msgid "" "`device_t` is the pointer type for the device structure. Here we consider " "only the methods interesting from the device driver writer's standpoint. The " "methods to manipulate values in the device structure are:" msgstr "" "`device_t` — это тип указателя на структуру устройства. Здесь мы " "рассматриваем только методы, представляющие интерес с точки зрения " "разработчика драйверов устройств. Методы для работы со значениями в " "структуре устройства следующие:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:157 msgid "`device_t device_get_parent(dev)` Get the parent bus of a device." msgstr "" "`device_t device_get_parent(dev)` Получить родительскую шину устройства." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:158 msgid "`driver_t device_get_driver(dev)` Get pointer to its driver structure." msgstr "" "`driver_t device_get_driver(dev)` Получить указатель на структуру его " "драйвера." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:159 msgid "" "`char *device_get_name(dev)` Get the driver name, such as `\"xxx\"` for our " "example." msgstr "" "`char *device_get_name(dev)` Получить имя драйвера, например `\"xxx\"` в " "нашем примере." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:160 msgid "" "`int device_get_unit(dev)` Get the unit number (units are numbered from 0 " "for the devices associated with each driver)." msgstr "" "`int device_get_unit(dev)` Получить номер устройства (устройства нумеруются " "с 0 для устройств, связанных с каждым драйвером)." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:161 msgid "" "`char *device_get_nameunit(dev)` Get the device name including the unit " "number, such as \"xxx0\", \"xxx1\" and so on." msgstr "" "`char *device_get_nameunit(dev)` Получить имя устройства, включая номер " "юнита, например, \"xxx0\", \"xxx1\" и так далее." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:162 msgid "" "`char *device_get_desc(dev)` Get the device description. Normally it " "describes the exact model of device in human-readable form." msgstr "" "`char *device_get_desc(dev)` Получить описание устройства. Обычно оно " "описывает точную модель устройства в удобочитаемом виде." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:163 msgid "" "`device_set_desc(dev, desc)` Set the description. This makes the device " "description point to the string desc which may not be deallocated or changed " "after that." msgstr "" "`device_set_desc(dev, desc)` Установить описание. Это заставляет описание " "устройства указывать на строку desc, которая не может быть освобождена или " "изменена после этого." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:164 msgid "" "`device_set_desc_copy(dev, desc)` Set the description. The description is " "copied into an internal dynamically allocated buffer, so the string desc may " "be changed afterwards without adverse effects." msgstr "" "`device_set_desc_copy(dev, desc)` Установить описание. Описание копируется " "во внутренний динамически выделяемый буфер, поэтому строка desc может быть " "изменена впоследствии без негативных последствий." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:165 msgid "" "`void *device_get_softc(dev)` Get pointer to the device descriptor (struct " "`xxx_softc`) associated with this device." msgstr "" "`void *device_get_softc(dev)` Получить указатель на дескриптор устройства (" "структура `xxx_softc`), связанный с данным устройством." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:166 msgid "" "`u_int32_t device_get_flags(dev)` Get the flags specified for the device in " "the configuration file." msgstr "" "`u_int32_t device_get_flags(dev)` Получить флаги, указанные для устройства в " "файле конфигурации." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:168 msgid "" "A convenience function `device_printf(dev, fmt, ...)` may be used to print " "the messages from the device driver. It automatically prepends the unitname " "and colon to the message." msgstr "" "Функция для удобства `device_printf(dev, fmt, ...)` может использоваться для " "вывода сообщений из драйвера устройства. Она автоматически добавляет имя " "устройства и двоеточие перед сообщением." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:170 msgid "" "The device_t methods are implemented in the file [.filename]#kern/" "bus_subr.c#." msgstr "Методы device_t реализованы в файле [.filename]#kern/bus_subr.c#." #. type: Title == #: documentation/content/en/books/arch-handbook/isa/_index.adoc:172 #, no-wrap msgid "Configuration File and the Order of Identifying and Probing During Auto-Configuration" msgstr "" "Файл конфигурации и порядок определения и проверки при автоматической " "настройке" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:175 msgid "The ISA devices are described in the kernel configuration file like:" msgstr "Устройства ISA описываются в файле конфигурации ядра следующим образом:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:180 #, no-wrap msgid "" "device xxx0 at isa? port 0x300 irq 10 drq 5\n" " iomem 0xd0000 flags 0x1 sensitive\n" msgstr "" "device xxx0 at isa? port 0x300 irq 10 drq 5\n" " iomem 0xd0000 flags 0x1 sensitive\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:183 msgid "" "The values of port, IRQ and so on are converted to the resource values " "associated with the device. They are optional, depending on the device's " "needs and abilities for auto-configuration. For example, some devices do not " "need DRQ at all and some allow the driver to read the IRQ setting from the " "device configuration ports. If a machine has multiple ISA buses the exact " "bus may be specified in the configuration line, like `isa0` or `isa1`, " "otherwise the device would be searched for on all the ISA buses." msgstr "" "Значения порта, IRQ и т. д. преобразуются в ресурсы, связанные с " "устройством. Они являются необязательными, в зависимости от потребностей " "устройства и его способностей к автонастройке. Например, некоторым " "устройствам вообще не нужен DRQ, а некоторые позволяют драйверу читать " "настройку IRQ из портов конфигурации устройства. Если в машине несколько шин " "ISA, точная шина может быть указана в строке конфигурации, например `isa0` " "или `isa1`, иначе устройство будет искаться на всех шинах ISA." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:185 msgid "" "`sensitive` is a resource requesting that this device must be probed before " "all non-sensitive devices. It is supported but does not seem to be used in " "any current driver." msgstr "" "`sensitive` — это ресурс, указывающий, что данное устройство должно быть " "проверено перед всеми нечувствительными устройствами. Он поддерживается, но, " "похоже, не используется ни в одном текущем драйвере." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:187 msgid "" "For legacy ISA devices in many cases the drivers are still able to detect " "the configuration parameters. But each device to be configured in the system " "must have a config line. If two devices of some type are installed in the " "system but there is only one configuration line for the corresponding " "driver, ie:" msgstr "" "Для устаревших устройств ISA во многих случаях драйверы всё ещё могут " "определять параметры конфигурации. Однако каждое устройство, которое " "необходимо настроить в системе, должно иметь строку конфигурации. Если в " "системе установлено два устройства одного типа, но для соответствующего " "драйвера есть только одна строка конфигурации, например:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:190 #, no-wrap msgid "device xxx0 at isa?\n" msgstr "device xxx0 at isa?\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:192 #, no-wrap msgid " then only one device will be configured.\n" msgstr " тогда будет настроено только одно устройство.\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:194 msgid "" "But for the devices supporting automatic identification by the means of Plug-" "n-Play or some proprietary protocol one configuration line is enough to " "configure all the devices in the system, like the one above or just simply:" msgstr "" "Однако для устройств, поддерживающих автоматическую идентификацию с помощью " "Plug-n-Play или какого-либо проприетарного протокола, достаточно одной " "строки конфигурации для настройки всех устройств в системе, как в примере " "выше или просто:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:198 #, no-wrap msgid "device xxx at isa?\n" msgstr "device xxx at isa?\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:201 msgid "" "If a driver supports both auto-identified and legacy devices and both kinds " "are installed at once in one machine then it is enough to describe in the " "config file the legacy devices only. The auto-identified devices will be " "added automatically." msgstr "" "Если драйвер поддерживает как автоматически определяемые, так и устаревшие " "устройства, и оба типа установлены одновременно в одной машине, то " "достаточно описать в конфигурационном файле только устаревшие устройства. " "Автоматически определяемые устройства будут добавлены автоматически." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:203 msgid "When an ISA bus is auto-configured the events happen as follows:" msgstr "" "При автоматической настройке шины ISA события происходят в следующем порядке:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:205 msgid "" "All the drivers' identify routines (including the PnP identify routine which " "identifies all the PnP devices) are called in random order. As they identify " "the devices they add them to the list on the ISA bus. Normally the drivers' " "identify routines associate their drivers with the new devices. The PnP " "identify routine does not know about the other drivers yet so it does not " "associate any with the new devices it adds." msgstr "" "Все процедуры идентификации драйверов (включая процедуру идентификации PnP, " "которая определяет все устройства PnP) вызываются в случайном порядке. Когда " "они идентифицируют устройства, они добавляют их в список на шине ISA. Обычно " "процедуры идентификации драйверов связывают свои драйверы с новыми " "устройствами. Процедура идентификации PnP пока не знает о других драйверах, " "поэтому не связывает ни один из них с новыми устройствами, которые она " "добавляет." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:207 msgid "" "The PnP devices are put to sleep using the PnP protocol to prevent them from " "being probed as legacy devices." msgstr "" "Устройства PnP переводятся в режим сна с использованием протокола PnP, чтобы " "предотвратить их обнаружение как устаревших устройств." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:209 msgid "" "The probe routines of non-PnP devices marked as `sensitive` are called. If " "probe for a device went successfully, the attach routine is called for it." msgstr "" "Вызываются процедуры обнаружения для устройств, не поддерживающих PnP, " "помеченных как `sensitive`. Если процедура обнаружения для устройства " "завершилась успешно, вызывается процедура присоединения для него." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:211 msgid "" "The probe and attach routines of all non-PNP devices are called likewise." msgstr "" "Вызов процедур обнаружения и присоединения всех устройств, не поддерживающих " "PNP, выполняется аналогичным образом." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:213 msgid "" "The PnP devices are brought back from the sleep state and assigned the " "resources they request: I/O and memory address ranges, IRQs and DRQs, all of " "them not conflicting with the attached legacy devices." msgstr "" "Устройства PnP выводятся из состояния сна и получают запрошенные ресурсы: " "диапазоны адресов ввода-вывода и памяти, IRQ и DRQ, причем все они не " "конфликтуют с подключенными устаревшими устройствами." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:215 msgid "" "Then for each PnP device the probe routines of all the present ISA drivers " "are called. The first one that claims the device gets attached. It is " "possible that multiple drivers would claim the device with different " "priority; in this case, the highest-priority driver wins. The probe routines " "must call `ISA_PNP_PROBE()` to compare the actual PnP ID with the list of " "the IDs supported by the driver and if the ID is not in the table return " "failure. That means that absolutely every driver, even the ones not " "supporting any PnP devices must call `ISA_PNP_PROBE()`, at least with an " "empty PnP ID table to return failure on unknown PnP devices." msgstr "" "Затем для каждого устройства PnP вызываются процедуры обнаружения всех " "присутствующих драйверов ISA. Первый драйвер, который заявит о поддержке " "устройства, будет присоединен. Возможна ситуация, когда несколько драйверов " "заявят о поддержке устройства с разным приоритетом; в этом случае побеждает " "драйвер с наивысшим приоритетом. Процедуры обнаружения должны вызывать " "`ISA_PNP_PROBE()` для сравнения фактического PnP ID со списком ID, " "поддерживаемых драйвером, и если ID отсутствует в таблице, возвращать " "ошибку. Это означает, что абсолютно каждый драйвер, даже те, которые не " "поддерживают никакие PnP устройства, должны вызывать `ISA_PNP_PROBE()`, хотя " "бы с пустой таблицей PnP ID, чтобы возвращать ошибку для неизвестных PnP " "устройств." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:217 msgid "" "The probe routine returns a positive value (the error code) on error, zero " "or negative value on success." msgstr "" "Процедура обнаружения возвращает положительное значение (код ошибки) в " "случае ошибки, ноль или отрицательное значение в случае успеха." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:219 msgid "" "The negative return values are used when a PnP device supports multiple " "interfaces. For example, an older compatibility interface and a newer " "advanced interface which are supported by different drivers. Then both " "drivers would detect the device. The driver which returns a higher value in " "the probe routine takes precedence (in other words, the driver returning 0 " "has highest precedence, returning -1 is next, returning -2 is after it and " "so on). In result the devices which support only the old interface will be " "handled by the old driver (which should return -1 from the probe routine) " "while the devices supporting the new interface as well will be handled by " "the new driver (which should return 0 from the probe routine). If multiple " "drivers return the same value then the one called first wins. So if a driver " "returns value 0 it may be sure that it won the priority arbitration." msgstr "" "Отрицательные возвращаемые значения используются, когда устройство PnP " "поддерживает несколько интерфейсов. Например, старый совместимый интерфейс и " "новый расширенный интерфейс, которые поддерживаются разными драйверами. В " "этом случае оба драйвера обнаружат устройство. Драйвер, возвращающий большее " "значение в процедуре обнаружения, получает приоритет (другими словами, " "драйвер, возвращающий 0, имеет наивысший приоритет, возвращающий -1 — " "следующий, возвращающий -2 — за ним и так далее). В результате устройства, " "поддерживающие только старый интерфейс, будут обрабатываться старым " "драйвером (который должен возвращать -1 из процедуры обнаружения), тогда как " "устройства, поддерживающие также новый интерфейс, будут обрабатываться новым " "драйвером (который должен возвращать 0 из процедуры обнаружения). Если " "несколько драйверов возвращают одинаковое значение, побеждает тот, который " "был вызван первым. Таким образом, если драйвер возвращает значение 0, он " "может быть уверен, что выиграл арбитраж приоритетов." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:221 msgid "" "The device-specific identify routines can also assign not a driver but a " "class of drivers to the device. Then all the drivers in the class are probed " "for this device, like the case with PnP. This feature is not implemented in " "any existing driver and is not considered further in this document." msgstr "" "Процедуры идентификации, специфичные для устройства, также могут назначать " "устройству не драйвер, а класс драйверов. Затем все драйверы в этом классе " "проверяются на совместимость с устройством, как в случае с PnP. Эта " "возможность не реализована ни в одном существующем драйвере и далее в этом " "документе не рассматривается." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:223 msgid "" "As the PnP devices are disabled when probing the legacy devices they will " "not be attached twice (once as legacy and once as PnP). But in case of " "device-dependent identify routines it is the responsibility of the driver to " "make sure that the same device will not be attached by the driver twice: " "once as legacy user-configured and once as auto-identified." msgstr "" "Поскольку устройства PnP отключены при проверке устаревших устройств, они не " "будут присоединены дважды (один раз как устаревшие и один раз как PnP). " "Однако в случае процедур идентификации, зависящих от устройства, " "ответственность за то, чтобы одно и то же устройство не было присоединено " "драйвером дважды (один раз как настроенное пользователем устаревшее и один " "раз как автоматически идентифицированное), лежит на драйвере." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:225 msgid "" "Another practical consequence for the auto-identified devices (both PnP and " "device-specific) is that the flags can not be passed to them from the kernel " "configuration file. So they must either not use the flags at all or use the " "flags from the device unit 0 for all the auto-identified devices or use the " "sysctl interface instead of flags." msgstr "" "Еще одно практическое следствие для автоматически определяемых устройств (" "как PnP, так и специфичных для устройства) заключается в том, что флаги не " "могут быть переданы им из файла конфигурации ядра. Поэтому они либо не " "должны использовать флаги вообще, либо использовать флаги из устройства unit " "0 для всех автоматически определяемых устройств, либо использовать интерфейс " "sysctl вместо флагов." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:227 msgid "" "Other unusual configurations may be accommodated by accessing the " "configuration resources directly with functions of families " "`resource_query_*()` and `resource_*_value()`. Their implementations are " "located in [.filename]#kern/subr_bus.c#. The old IDE disk driver " "[.filename]#i386/isa/wd.c# contains examples of such use. But the standard " "means of configuration must always be preferred. Leave parsing the " "configuration resources to the bus configuration code." msgstr "" "Другие нестандартные конфигурации могут быть реализованы путем прямого " "доступа к ресурсам конфигурации с использованием функций семейств " "`resource_query_*()` и `resource_*_value()`. Их реализации находятся в [." "filename]#kern/subr_bus.c#. Примеры такого использования есть в старом " "драйвере диска IDE [.filename]#i386/isa/wd.c#. Однако стандартные методы " "конфигурации всегда должны быть предпочтительны. Оставьте разбор ресурсов " "конфигурации коду настройки шины." #. type: Title == #: documentation/content/en/books/arch-handbook/isa/_index.adoc:229 #, no-wrap msgid "Resources" msgstr "Ресурсы" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:232 msgid "" "The information that a user enters into the kernel configuration file is " "processed and passed to the kernel as configuration resources. This " "information is parsed by the bus configuration code and transformed into a " "value of structure device_t and the bus resources associated with it. The " "drivers may access the configuration resources directly using functions " "`resource_*` for more complex cases of configuration. However, generally " "this is neither needed nor recommended, so this issue is not discussed " "further here." msgstr "" "Информация, которую пользователь вводит в файл конфигурации ядра, " "обрабатывается и передаётся ядру в виде ресурсов конфигурации. Эта " "информация анализируется кодом конфигурации шины и преобразуется в значение " "структуры `device_t` и связанные с ней ресурсы шины. Драйверы могут напрямую " "обращаться к ресурсам конфигурации, используя функции `resource_*` для более " "сложных случаев конфигурации. Однако, как правило, в этом нет необходимости, " "и это не рекомендуется, поэтому данный вопрос далее не рассматривается." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:234 msgid "" "The bus resources are associated with each device. They are identified by " "type and number within the type. For the ISA bus the following types are " "defined:" msgstr "" "Ресурсы шины связаны с каждым устройством. Они идентифицируются по типу и " "номеру внутри типа. Для шины ISA определены следующие типы:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:236 msgid "_SYS_RES_IRQ_ - interrupt number" msgstr "_SYS_RES_IRQ_ - номер прерывания" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:237 msgid "_SYS_RES_DRQ_ - ISA DMA channel number" msgstr "_SYS_RES_DRQ_ - номер канала ISA DMA" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:238 msgid "" "_SYS_RES_MEMORY_ - range of device memory mapped into the system memory space" msgstr "" "_SYS_RES_MEMORY_ - диапазон памяти устройства, отображенный в системное " "адресное пространство" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:239 msgid "_SYS_RES_IOPORT_ - range of device I/O registers" msgstr "_SYS_RES_IOPORT_ - диапазон регистров ввода-вывода устройства" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:241 msgid "" "The enumeration within types starts from 0, so if a device has two memory " "regions it would have resources of type `SYS_RES_MEMORY` numbered 0 and 1. " "The resource type has nothing to do with the C language type, all the " "resource values have the C language type `unsigned long` and must be cast as " "necessary. The resource numbers do not have to be contiguous, although for " "ISA they normally would be. The permitted resource numbers for ISA devices " "are:" msgstr "" "Перечисление внутри типов начинается с 0, поэтому если устройство имеет две " "области памяти, оно будет иметь ресурсы типа `SYS_RES_MEMORY` с номерами 0 и " "1. Тип ресурса не связан с типом языка C, все значения ресурсов имеют тип `" "unsigned long` в языке C и должны быть приведены по мере необходимости. " "Номера ресурсов не обязательно должны быть последовательными, хотя для ISA " "они обычно таковыми являются. Допустимые номера ресурсов для устройств ISA:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:248 #, no-wrap msgid "" " IRQ: 0-1\n" " DRQ: 0-1\n" " MEMORY: 0-3\n" " IOPORT: 0-7\n" msgstr "" " IRQ: 0-1\n" " DRQ: 0-1\n" " MEMORY: 0-3\n" " IOPORT: 0-7\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:251 msgid "" "All the resources are represented as ranges, with a start value and count. " "For IRQ and DRQ resources the count would normally be equal to 1. The values " "for memory refer to the physical addresses." msgstr "" "Все ресурсы представлены в виде диапазонов с начальным значением и " "количеством. Для ресурсов IRQ и DRQ количество обычно равно 1. Значения для " "памяти относятся к физическим адресам." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:253 msgid "Three types of activities can be performed on resources:" msgstr "Три типа действий могут выполняться над ресурсами:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:255 msgid "set/get" msgstr "Установка — set/get" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:256 msgid "allocate/release" msgstr "Выделение — allocate/release" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:257 msgid "activate/deactivate" msgstr "Активация — activate/deactivate" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:259 msgid "" "Setting sets the range used by the resource. Allocation reserves the " "requested range that no other driver would be able to reserve it (and " "checking that no other driver reserved this range already). Activation makes " "the resource accessible to the driver by doing whatever is necessary for " "that (for example, for memory it would be mapping into the kernel virtual " "address space)." msgstr "" "Установка задает диапазон, используемый ресурсом. Выделение резервирует " "запрошенный диапазон, чтобы никакой другой драйвер не смог его " "зарезервировать (и проверяет, что никакой другой драйвер уже не " "зарезервировал этот диапазон). Активация делает ресурс доступным для " "драйвера, выполняя все необходимые для этого действия (например, для памяти " "это может быть отображение в виртуальное адресное пространство ядра)." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:261 msgid "The functions to manipulate resources are:" msgstr "Функции для управления ресурсами:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:263 msgid "" "`int bus_set_resource(device_t dev, int type, int rid, u_long start, u_long " "count)`" msgstr "" "`int bus_set_resource(device_t dev, int type, int rid, u_long start, u_long " "count)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:265 msgid "" "Set a range for a resource. Returns 0 if successful, error code otherwise. " "Normally, this function will return an error only if one of `type`, `rid`, " "`start` or `count` has a value that falls out of the permitted range." msgstr "" "Устанавливает диапазон для ресурса. Возвращает 0 при успешном выполнении, в " "противном случае — код ошибки. Обычно эта функция возвращает ошибку только в " "том случае, если одно из значений `type`, `rid`, `start` или `count` выходит " "за пределы допустимого диапазона." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:267 msgid "dev - driver's device" msgstr "dev - устройство драйвера" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:268 msgid "type - type of resource, SYS_RES_*" msgstr "тип - тип ресурса, SYS_RES_*" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:269 msgid "rid - resource number (ID) within type" msgstr "rid - номер ресурса (ID) в пределах типа" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:270 msgid "start, count - resource range" msgstr "начало, количество - диапазон ресурсов" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:272 msgid "" "`int bus_get_resource(device_t dev, int type, int rid, u_long *startp, " "u_long *countp)`" msgstr "" "`int bus_get_resource(device_t dev, int type, int rid, u_long *startp, " "u_long *countp)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:274 msgid "" "Get the range of resource. Returns 0 if successful, error code if the " "resource is not defined yet." msgstr "" "Получает диапазон ресурса. Возвращает 0 при успехе, код ошибки, если ресурс " "ещё не определён." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:275 msgid "" "`u_long bus_get_resource_start(device_t dev, int type, int rid) u_long " "bus_get_resource_count (device_t dev, int type, int rid)`" msgstr "" "`u_long bus_get_resource_start(device_t dev, int type, int rid) и u_long " "bus_get_resource_count (device_t dev, int type, int rid)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:277 msgid "" "Convenience functions to get only the start or count. Return 0 in case of " "error, so if the resource start has 0 among the legitimate values it would " "be impossible to tell if the value is 0 or an error occurred. Luckily, no " "ISA resources for add-on drivers may have a start value equal to 0." msgstr "" "Удобные функции для получения только начала или количества. Возвращают 0 в " "случае ошибки, поэтому если начало ресурса может законно содержать 0, " "невозможно определить, является ли значение 0 или произошла ошибка. К " "счастью, ни один ресурс ISA для дополнительных драйверов не может иметь " "начальное значение, равное 0." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:278 msgid "`void bus_delete_resource(device_t dev, int type, int rid)`" msgstr "`void bus_delete_resource(device_t dev, int type, int rid)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:280 msgid "Delete a resource, make it undefined." msgstr "Удаляет ресурс, делает его неопределённым." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:281 msgid "" "`struct resource * bus_alloc_resource(device_t dev, int type, int *rid, " "u_long start, u_long end, u_long count, u_int flags)`" msgstr "" "`struct resource * bus_alloc_resource(device_t dev, int type, int *rid, " "u_long start, u_long end, u_long count, u_int flags)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:283 msgid "" "Allocate a resource as a range of count values not allocated by anyone else, " "somewhere between start and end. Alas, alignment is not supported. If the " "resource was not set yet it is automatically created. The special values of " "start 0 and end ~0 (all ones) means that the fixed values previously set by " "`bus_set_resource()` must be used instead: start and count as themselves and " "end=(start+count), in this case if the resource was not defined before then " "an error is returned. Although rid is passed by reference it is not set " "anywhere by the resource allocation code of the ISA bus. (The other buses " "may use a different approach and modify it)." msgstr "" "Выделяет ресурс как диапазон значений count, не выделенных никем другим, где-" "то между start и end. Увы, выравнивание не поддерживается. Если ресурс ещё " "не был установлен, он автоматически создаётся. Специальные значения start " "равное 0 и end равное ~0 (все единицы) означают, что должны использоваться " "фиксированные значения, ранее установленные `bus_set_resource()`: start и " "count как есть, а end=(start+count). В этом случае, если ресурс не был " "определён ранее, возвращается ошибка. Хотя rid передаётся по ссылке, он " "нигде не устанавливается кодом выделения ресурсов шины ISA. Другие шины " "могут использовать иной подход и изменять его." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:285 msgid "Flags are a bitmap, the flags interesting for the caller are:" msgstr "" "Флаги представляют собой битовую карту. Интересные для вызывающей стороны " "флаги:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:287 msgid "" "_RF_ACTIVE_ - causes the resource to be automatically activated after " "allocation." msgstr "" "_RF_ACTIVE_ - приводит к автоматической активации ресурса после его " "выделения." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:288 msgid "" "_RF_SHAREABLE_ - resource may be shared at the same time by multiple drivers." msgstr "" "_RF_SHAREABLE_ - ресурс может использоваться одновременно несколькими " "драйверами." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:289 msgid "" "_RF_TIMESHARE_ - resource may be time-shared by multiple drivers, i.e., " "allocated at the same time by many but activated only by one at any given " "moment of time." msgstr "" "_RF_TIMESHARE_ - ресурс может разделяться по времени несколькими драйверами, " "т.е. выделяться одновременно многими, но активироваться только одним в любой " "момент времени." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:290 msgid "" "Returns 0 on error. The allocated values may be obtained from the returned " "handle using methods `rhand_*()`." msgstr "" "Возвращает 0 при ошибке. Выделенные значения могут быть получены из " "возвращённого дескриптора с использованием методов `rhand_*()`." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:291 msgid "" "`int bus_release_resource(device_t dev, int type, int rid, struct resource " "*r)`" msgstr "" "`int bus_release_resource(device_t dev, int type, int rid, struct resource " "*r)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:292 msgid "" "Release the resource, r is the handle returned by `bus_alloc_resource()`. " "Returns 0 on success, error code otherwise." msgstr "" "Освобождает ресурс, r — это дескриптор, возвращённый `bus_alloc_resource()`. " "Возвращает 0 при успехе, код ошибки в противном случае." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:293 msgid "" "`int bus_activate_resource(device_t dev, int type, int rid, struct resource " "*r) int bus_deactivate_resource(device_t dev, int type, int rid, struct " "resource *r)`" msgstr "" "`int bus_activate_resource(device_t dev, int type, int rid, struct resource " "*r) int bus_deactivate_resource(device_t dev, int type, int rid, struct " "resource *r)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:294 msgid "" "Activate or deactivate resource. Return 0 on success, error code otherwise. " "If the resource is time-shared and currently activated by another driver " "then `EBUSY` is returned." msgstr "" "Активирует или деактивирует ресурс. Возвращает 0 при успехе, в противном " "случае — код ошибки. Если ресурс разделяемый и в данный момент активирован " "другим драйвером, возвращается `EBUSY`." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:295 msgid "" "`int bus_setup_intr(device_t dev, struct resource *r, int flags, " "driver_intr_t *handler, void *arg, void **cookiep) int " "bus_teardown_intr(device_t dev, struct resource *r, void *cookie)`" msgstr "" "`int bus_setup_intr(device_t dev, struct resource *r, int flags, " "driver_intr_t *handler, void *arg, void **cookiep) int bus_teardown_intr(" "device_t dev, struct resource *r, void *cookie)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:296 msgid "" "Associate or de-associate the interrupt handler with a device. Return 0 on " "success, error code otherwise." msgstr "" "Связывает или разрывает связь обработчика прерывания с устройством. " "Возвращает 0 при успехе, код ошибки в противном случае." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:297 msgid "r - the activated resource handler describing the IRQ" msgstr "r - активированный обработчик ресурсов, описывающий IRQ" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:299 msgid "flags - the interrupt priority level, one of:" msgstr "flags - уровень приоритета прерывания, один из:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:301 msgid "" "`INTR_TYPE_TTY` - terminals and other likewise character-type devices. To " "mask them use `spltty()`." msgstr "" "`INTR_TYPE_TTY` - терминалы и другие аналогичные символьные устройства. Для " "их маскировки используйте `spltty()`." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:302 msgid "" "`(INTR_TYPE_TTY | INTR_TYPE_FAST)` - terminal type devices with small input " "buffer, critical to the data loss on input (such as the old-fashioned serial " "ports). To mask them use `spltty()`." msgstr "" "`(INTR_TYPE_TTY | INTR_TYPE_FAST)` - терминальные устройства с малым буфером " "ввода, критичные к потере данных на входе (например, устаревшие " "последовательные порты). Для их маскирования используйте `spltty()`." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:303 msgid "" "`INTR_TYPE_BIO` - block-type devices, except those on the CAM controllers. " "To mask them use `splbio()`." msgstr "" "`INTR_TYPE_BIO` - блочные устройства, за исключением тех, что подключены к " "контроллерам CAM. Для их маскирования используйте `splbio()`." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:304 msgid "" "`INTR_TYPE_CAM` - CAM (Common Access Method) bus controllers. To mask them " "use `splcam()`." msgstr "" "`INTR_TYPE_CAM` - контроллеры шины CAM (Common Access Method). Для их " "маскирования используйте `splcam()`." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:305 msgid "" "`INTR_TYPE_NET` - network interface controllers. To mask them use `splimp()`." msgstr "" "`INTR_TYPE_NET` - контроллеры сетевых интерфейсов. Для их маскирования " "используйте `splimp()`." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:306 msgid "" "`INTR_TYPE_MISC` - miscellaneous devices. There is no other way to mask them " "than by `splhigh()` which masks all interrupts." msgstr "" "`INTR_TYPE_MISC` — прочие устройства. Нет другого способа их маскировки, " "кроме `splhigh()`, который маскирует все прерывания." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:308 msgid "" "When an interrupt handler executes all the other interrupts matching its " "priority level will be masked. The only exception is the MISC level for " "which no other interrupts are masked and which is not masked by any other " "interrupt." msgstr "" "Когда обработчик прерывания выполняется, все другие прерывания, " "соответствующие его уровню приоритета, будут заблокированы. Единственное " "исключение — уровень MISC, для которого никакие другие прерывания не " "блокируются и который сам не блокируется другими прерываниями." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:310 msgid "" "_handler_ - pointer to the handler function, the type driver_intr_t is " "defined as `void driver_intr_t(void *)`" msgstr "" "_handler_ - указатель на функцию-обработчик, тип driver_intr_t определён как " "`void driver_intr_t(void *)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:311 msgid "" "_arg_ - the argument passed to the handler to identify this particular " "device. It is cast from void* to any real type by the handler. The old " "convention for the ISA interrupt handlers was to use the unit number as " "argument, the new (recommended) convention is using a pointer to the device " "softc structure." msgstr "" "_arg_ - аргумент, передаваемый обработчику для идентификации конкретного " "устройства. Приводится обработчиком от void* к фактическому типу. Старая " "конвенция для обработчиков прерываний ISA предполагала использование номера " "устройства в качестве аргумента, новая (рекомендуемая) конвенция " "предполагает использование указателя на структуру softc устройства." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:312 msgid "" "_cookie[p]_ - the value received from `setup()` is used to identify the " "handler when passed to `teardown()`" msgstr "" "_cookie[p]_ - значение, полученное из `setup()`, используется для " "идентификации обработчика при передаче в `teardown()`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:314 msgid "" "A number of methods are defined to operate on the resource handlers (struct " "resource *). Those of interest to the device driver writers are:" msgstr "" "Определены несколько методов для работы с обработчиками ресурсов (struct " "resource *). Вот те из них, которые представляют интерес для разработчиков " "драйверов устройств:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:316 msgid "" "`u_long rman_get_start(r) u_long rman_get_end(r)` Get the start and end of " "allocated resource range." msgstr "" "`u_long rman_get_start(r) u_long rman_get_end(r)` Получают начало и конец " "выделенного диапазона ресурсов." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:317 msgid "" "`void *rman_get_virtual(r)` Get the virtual address of activated memory " "resource." msgstr "" "`void *rman_get_virtual(r)` Получает виртуальный адрес активированного " "ресурса памяти." #. type: Title == #: documentation/content/en/books/arch-handbook/isa/_index.adoc:319 #, no-wrap msgid "Bus Memory Mapping" msgstr "Отображение памяти шины" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:322 msgid "" "In many cases data is exchanged between the driver and the device through " "the memory. Two variants are possible:" msgstr "" "Во многих случаях данные передаются между драйвером и устройством через " "память. Возможны два варианта:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:324 msgid "(a) memory is located on the device card" msgstr "(а) память расположена на карте устройства" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:326 msgid "(b) memory is the main memory of the computer" msgstr "(b) память — это основная память компьютера" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:328 msgid "" "In case (a) the driver always copies the data back and forth between the on-" "card memory and the main memory as necessary. To map the on-card memory into " "the kernel virtual address space the physical address and length of the on-" "card memory must be defined as a `SYS_RES_MEMORY` resource. That resource " "can then be allocated and activated, and its virtual address obtained using " "`rman_get_virtual()`. The older drivers used the function `pmap_mapdev()` " "for this purpose, which should not be used directly any more. Now it is one " "of the internal steps of resource activation." msgstr "" "В случае (a) драйвер всегда копирует данные между памятью на карте и " "основной памятью по мере необходимости. Для отображения памяти на карте в " "виртуальное адресное пространство ядра физический адрес и длина памяти на " "карте должны быть определены как ресурс `SYS_RES_MEMORY`. Этот ресурс может " "быть затем выделен и активирован, а его виртуальный адрес получен с помощью " "`rman_get_virtual()`. Более старые драйверы использовали для этой цели " "функцию `pmap_mapdev()`, которую больше не следует использовать напрямую. " "Теперь это один из внутренних шагов активации ресурса." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:330 msgid "" "Most of the ISA cards will have their memory configured for physical " "location somewhere in range 640KB-1MB. Some of the ISA cards require larger " "memory ranges which should be placed somewhere under 16MB (because of the 24-" "bit address limitation on the ISA bus). In that case if the machine has more " "memory than the start address of the device memory (in other words, they " "overlap) a memory hole must be configured at the address range used by " "devices. Many BIOSes allow configuration of a memory hole of 1MB starting at " "14MB or 15MB. FreeBSD can handle the memory holes properly if the BIOS " "reports them properly (this feature may be broken on old BIOSes)." msgstr "" "Большинство ISA-карт имеют память, настроенную на физическое расположение в " "диапазоне 640 КБ–1 МБ. Некоторые ISA-карты требуют большего диапазона " "памяти, который должен быть размещён ниже 16 МБ (из-за 24-битного " "ограничения адресации на шине ISA). В таком случае, если в машине больше " "памяти, чем начальный адрес памяти устройства (другими словами, они " "пересекаются), необходимо настроить \"дыру\" в памяти по диапазону адресов, " "используемому устройствами. Многие BIOS позволяют настроить \"дыру\" в " "памяти размером 1 МБ, начиная с 14 МБ или 15 МБ. FreeBSD корректно " "обрабатывает \"дыры\" в памяти, если BIOS правильно их сообщает (эта функция " "может не работать в старых BIOS)." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:332 msgid "" "In case (b) just the address of the data is sent to the device, and the " "device uses DMA to actually access the data in the main memory. Two " "limitations are present: First, ISA cards can only access memory below 16MB. " "Second, the contiguous pages in virtual address space may not be contiguous " "in physical address space, so the device may have to do scatter/gather " "operations. The bus subsystem provides ready solutions for some of these " "problems, the rest has to be done by the drivers themselves." msgstr "" "В случае (b) только адрес данных отправляется на устройство, и устройство " "использует DMA для фактического доступа к данным в основной памяти. " "Существуют два ограничения: во-первых, карты ISA могут обращаться только к " "памяти ниже 16 МБ. Во-вторых, непрерывные страницы в виртуальном адресном " "пространстве могут не быть непрерывными в физическом адресном пространстве, " "поэтому устройству может потребоваться выполнять операции scatter/gather. " "Подсистема шины предоставляет готовые решения для некоторых из этих проблем, " "остальное должно быть реализовано самими драйверами." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:334 msgid "" "Two structures are used for DMA memory allocation, `bus_dma_tag_t` and " "`bus_dmamap_t`. Tag describes the properties required for the DMA memory. " "Map represents a memory block allocated according to these properties. " "Multiple maps may be associated with the same tag." msgstr "" "Для выделения памяти DMA используются две структуры: `bus_dma_tag_t` и " "`bus_dmamap_t`. Тег (`tag`) описывает свойства, необходимые для памяти DMA. " "Карта (`map`) представляет собой блок памяти, выделенный в соответствии с " "этими свойствами. С одним тегом может быть связано несколько карт." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:336 msgid "" "Tags are organized into a tree-like hierarchy with inheritance of the " "properties. A child tag inherits all the requirements of its parent tag, and " "may make them more strict but never more loose." msgstr "" "Теги организованы в иерархию в виде дерева с наследованием свойств. Дочерний " "тег наследует все требования родительского тега и может делать их более " "строгими, но никогда более мягкими." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:338 msgid "" "Normally one top-level tag (with no parent) is created for each device unit. " "If multiple memory areas with different requirements are needed for each " "device then a tag for each of them may be created as a child of the parent " "tag." msgstr "" "Обычно создается один корневой тег (без родителя) для каждого устройства. " "Если для каждого устройства требуется несколько областей памяти с разными " "требованиями, то для каждой из них может быть создан тег как дочерний по " "отношению к родительскому тегу." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:340 msgid "The tags can be used to create a map in two ways." msgstr "Теги могут быть использованы для создания карты двумя способами." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:342 msgid "" "First, a chunk of contiguous memory conformant with the tag requirements may " "be allocated (and later may be freed). This is normally used to allocate " "relatively long-living areas of memory for communication with the device. " "Loading of such memory into a map is trivial: it is always considered as one " "chunk in the appropriate physical memory range." msgstr "" "Сначала может быть выделен (а затем освобожден) блок непрерывной памяти, " "соответствующий требованиям тега. Обычно это используется для выделения " "относительно долгоживущих областей памяти для взаимодействия с устройством. " "Загрузка такой памяти в карту тривиальна: она всегда рассматривается как " "один блок в соответствующем диапазоне физической памяти." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:344 msgid "" "Second, an arbitrary area of virtual memory may be loaded into a map. Each " "page of this memory will be checked for conformance to the map requirement. " "If it conforms then it is left at its original location. If it is not then a " "fresh conformant \"bounce page\" is allocated and used as intermediate " "storage. When writing the data from the non-conformant original pages they " "will be copied to their bounce pages first and then transferred from the " "bounce pages to the device. When reading the data would go from the device " "to the bounce pages and then copied to their non-conformant original pages. " "The process of copying between the original and bounce pages is called " "synchronization. This is normally used on a per-transfer basis: buffer for " "each transfer would be loaded, transfer done and buffer unloaded." msgstr "" "Второй момент: произвольная область виртуальной памяти может быть загружена " "в карту. Каждая страница этой памяти будет проверяться на соответствие " "требованиям карты. Если она соответствует, то остаётся на своём исходном " "месте. Если нет, то выделяется новая соответствующая промежуточная страница (" "bounce page), которая используется как промежуточное хранилище. При записи " "данных с несоответствующих исходных страниц они сначала копируются на свои " "промежуточные страницы, а затем передаются с промежуточных страниц на " "устройство. При чтении данные поступают с устройства на промежуточные " "страницы, а затем копируются на свои несоответствующие исходные страницы. " "Процесс копирования между исходными и промежуточными страницами называется " "синхронизацией. Обычно это используется для каждой передачи: буфер для " "каждой передачи загружается, передача выполняется, и буфер выгружается." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:346 msgid "The functions working on the DMA memory are:" msgstr "Функции, работающие с памятью DMA:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:348 msgid "" "`int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, " "bus_size_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr, " "bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize, int " "nsegments, bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat)`" msgstr "" "`int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, " "bus_size_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr, " "bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize, int " "nsegments, bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:350 msgid "Create a new tag. Returns 0 on success, the error code otherwise." msgstr "" "Создать новый тег. Возвращает 0 при успехе, код ошибки в противном случае." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:352 msgid "_parent_ - parent tag, or NULL to create a top-level tag." msgstr "" "_parent_ - родительский тег, или NULL для создания тега верхнего уровня." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:353 msgid "" "_alignment_ - required physical alignment of the memory area to be allocated " "for this tag. Use value 1 for \"no specific alignment\". Applies only to the " "future `bus_dmamem_alloc()` but not `bus_dmamap_create()` calls." msgstr "" "_alignment_ - требуемое физическое выравнивание области памяти, которая " "будет выделена для этого тега. Используйте значение 1 для \"без " "специфического выравнивания\". Применяется только к будущим вызовам " "`bus_dmamem_alloc()`, но не `bus_dmamap_create()`." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:354 msgid "" "_boundary_ - physical address boundary that must not be crossed when " "allocating the memory. Use value 0 for \"no boundary\". Applies only to the " "future `bus_dmamem_alloc()` but not `bus_dmamap_create()` calls. Must be " "power of 2. If the memory is planned to be used in non-cascaded DMA mode " "(i.e., the DMA addresses will be supplied not by the device itself but by " "the ISA DMA controller) then the boundary must be no larger than 64KB " "(64*1024) due to the limitations of the DMA hardware." msgstr "" "_boundary_ - физическая граница адреса, которую нельзя пересекать при " "выделении памяти. Используйте значение 0 для обозначения \"нет границы\". " "Применяется только к будущим вызовам `bus_dmamem_alloc()`, но не " "`bus_dmamap_create()`. Должна быть степенью 2. Если память планируется " "использовать в некаскадном режиме DMA (т.е. адреса DMA будут предоставляться " "не самим устройством, а контроллером DMA ISA), то граница не должна " "превышать 64 КБ (64*1024) из-за ограничений аппаратного обеспечения DMA." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:355 msgid "" "_lowaddr, highaddr_ - the names are slightly misleading; these values are " "used to limit the permitted range of physical addresses used to allocate the " "memory. The exact meaning varies depending on the planned future use:" msgstr "" "_lowaddr, highaddr_ - названия немного вводят в заблуждение; эти значения " "используются для ограничения допустимого диапазона физических адресов, " "используемых для выделения памяти. Точное значение зависит от " "предполагаемого будущего использования:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:357 msgid "" "For `bus_dmamem_alloc()` all the addresses from 0 to lowaddr-1 are " "considered permitted, the higher ones are forbidden." msgstr "" "Для `bus_dmamem_alloc()` все адреса от 0 до lowaddr-1 считаются " "разрешёнными, а более высокие — запрещёнными." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:358 msgid "" "For `bus_dmamap_create()` all the addresses outside the inclusive range " "[lowaddr; highaddr] are considered accessible. The addresses of pages inside " "the range are passed to the filter function which decides if they are " "accessible. If no filter function is supplied then all the range is " "considered unaccessible." msgstr "" "Для `bus_dmamap_create()` все адреса вне включительного диапазона [lowaddr; " "highaddr] считаются доступными. Адреса страниц внутри диапазона передаются в " "функцию-фильтр, которая определяет, доступны ли они. Если функция-фильтр не " "предоставлена, то весь диапазон считается недоступным." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:359 msgid "For the ISA devices the normal values (with no filter function) are:" msgstr "Для устройств ISA обычные значения (без функции фильтрации) следующие:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:361 msgid "lowaddr = BUS_SPACE_MAXADDR_24BIT" msgstr "lowaddr = BUS_SPACE_MAXADDR_24BIT" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:363 msgid "highaddr = BUS_SPACE_MAXADDR" msgstr "highaddr = BUS_SPACE_MAXADDR" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:365 msgid "" "_filter, filterarg_ - the filter function and its argument. If NULL is " "passed for filter then the whole range [lowaddr, highaddr] is considered " "unaccessible when doing `bus_dmamap_create()`. Otherwise the physical " "address of each attempted page in range [lowaddr; highaddr] is passed to the " "filter function which decides if it is accessible. The prototype of the " "filter function is: `int filterfunc(void *arg, bus_addr_t paddr)`. It must " "return 0 if the page is accessible, non-zero otherwise." msgstr "" "_filter, filterarg_ - функция фильтра и её аргумент. Если передаётся NULL " "для filter, то весь диапазон [lowaddr, highaddr] считается недоступным при " "выполнении `bus_dmamap_create()`. В противном случае физический адрес каждой " "страницы в диапазоне [lowaddr; highaddr] передаётся в функцию фильтра, " "которая определяет, доступна ли она. Прототип функции фильтра: `int " "filterfunc(void *arg, bus_addr_t paddr)`. Функция должна вернуть 0, если " "страница доступна, и ненулевое значение в противном случае." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:366 msgid "" "_maxsize_ - the maximal size of memory (in bytes) that may be allocated " "through this tag. In case it is difficult to estimate or could be " "arbitrarily big, the value for ISA devices would be " "`BUS_SPACE_MAXSIZE_24BIT`." msgstr "" "_maxsize_ - максимальный размер памяти (в байтах), который может быть " "выделен через этот тег. Если сложно оценить или он может быть произвольно " "большим, для устройств ISA следует использовать значение " "`BUS_SPACE_MAXSIZE_24BIT`." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:367 msgid "" "_nsegments_ - maximal number of scatter-gather segments supported by the " "device. If unrestricted then the value `BUS_SPACE_UNRESTRICTED` should be " "used. This value is recommended for the parent tags, the actual restrictions " "would then be specified for the descendant tags. Tags with nsegments equal " "to `BUS_SPACE_UNRESTRICTED` may not be used to actually load maps, they may " "be used only as parent tags. The practical limit for nsegments seems to be " "about 250-300, higher values will cause kernel stack overflow (the hardware " "can not normally support that many scatter-gather buffers anyway)." msgstr "" "_nsegments_ - максимальное количество сегментов scatter-gather, " "поддерживаемых устройством. Если ограничений нет, следует использовать " "значение `BUS_SPACE_UNRESTRICTED`. Это значение рекомендуется для " "родительских тегов, фактические ограничения затем будут указаны для дочерних " "тегов. Теги с nsegments равным `BUS_SPACE_UNRESTRICTED` не могут " "использоваться для фактической загрузки отображений, они могут применяться " "только как родительские теги. Практический предел для nsegments составляет " "около 250-300, более высокие значения вызовут переполнение стека ядра (" "аппаратное обеспечение обычно не поддерживает такое большое количество " "scatter-gather буферов в любом случае)." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:368 msgid "" "_maxsegsz_ - maximal size of a scatter-gather segment supported by the " "device. The maximal value for ISA device would be `BUS_SPACE_MAXSIZE_24BIT`." msgstr "" "_maxsegsz_ — максимальный размер сегмента scatter-gather, поддерживаемый " "устройством. Максимальное значение для устройства ISA будет " "`BUS_SPACE_MAXSIZE_24BIT`." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:369 msgid "_flags_ - a bitmap of flags. The only interesting flag is:" msgstr "_flags_ - битовая маска флагов. Единственный интересный флаг:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:371 msgid "" "_BUS_DMA_ALLOCNOW_ - requests to allocate all the potentially needed bounce " "pages when creating the tag." msgstr "" "_BUS_DMA_ALLOCNOW_ - запрашивает выделение всех потенциально необходимых " "промежуточных страниц при создании тега." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:373 msgid "_dmat_ - pointer to the storage for the new tag to be returned." msgstr "_dmat_ - указатель на хранилище для нового возвращаемого тега." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:375 msgid "`int bus_dma_tag_destroy(bus_dma_tag_t dmat)`" msgstr "`int bus_dma_tag_destroy(bus_dma_tag_t dmat)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:377 msgid "Destroy a tag. Returns 0 on success, the error code otherwise." msgstr "Уничтожить тег. Возвращает 0 при успехе, код ошибки в противном случае." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:379 msgid "dmat - the tag to be destroyed." msgstr "dmat - тег, который должен быть уничтожен." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:380 msgid "" "`int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, " "bus_dmamap_t *mapp)`" msgstr "" "`int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, " "bus_dmamap_t *mapp)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:382 msgid "" "Allocate an area of contiguous memory described by the tag. The size of " "memory to be allocated is tag's maxsize. Returns 0 on success, the error " "code otherwise. The result still has to be loaded by `bus_dmamap_load()` " "before being used to get the physical address of the memory." msgstr "" "Выделить область непрерывной памяти, описанную тегом. Размер выделяемой " "памяти соответствует maxsize тега. Возвращает 0 при успехе, иначе код " "ошибки. Результат всё ещё должен быть загружен с помощью `bus_dmamap_load()` " "перед использованием для получения физического адреса памяти." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:384 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:396 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:404 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:419 msgid "_dmat_ - the tag" msgstr "_dmat_ - тег" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:385 msgid "" "_vaddr_ - pointer to the storage for the kernel virtual address of the " "allocated area to be returned." msgstr "" "_vaddr_ - указатель на хранилище для возвращаемого виртуального адреса ядра " "выделенной области." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:386 msgid "flags - a bitmap of flags. The only interesting flag is:" msgstr "flags - битовая карта флагов. Единственный интересный флаг:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:388 msgid "" "_BUS_DMA_NOWAIT_ - if the memory is not immediately available return the " "error. If this flag is not set then the routine is allowed to sleep until " "the memory becomes available." msgstr "" "_BUS_DMA_NOWAIT_ - если память недоступна немедленно, вернуть ошибку. Если " "этот флаг не установлен, то процедуре разрешено ожидать до тех пор, пока " "память не станет доступной." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:390 msgid "_mapp_ - pointer to the storage for the new map to be returned." msgstr "_mapp_ - указатель на хранилище для возвращаемой новой карты." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:392 msgid "" "`void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)`" msgstr "" "`void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:394 msgid "" "Free the memory allocated by `bus_dmamem_alloc()`. At present, freeing of " "the memory allocated with ISA restrictions is not implemented. Due to this " "the recommended model of use is to keep and re-use the allocated areas for " "as long as possible. Do not lightly free some area and then shortly allocate " "it again. That does not mean that `bus_dmamem_free()` should not be used at " "all: hopefully it will be properly implemented soon." msgstr "" "Освободить память, выделенную `bus_dmamem_alloc()`. В настоящее время " "освобождение памяти, выделенной с ограничениями ISA, не реализовано. В связи " "с этим рекомендуется сохранять и повторно использовать выделенные области " "как можно дольше. Не следует без необходимости освобождать область и вскоре " "снова её выделять. Это не означает, что `bus_dmamem_free()` не следует " "использовать вовсе: есть надежда, что вскоре она будет реализована должным " "образом." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:397 msgid "_vaddr_ - the kernel virtual address of the memory" msgstr "_vaddr_ - виртуальный адрес памяти ядра" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:398 msgid "_map_ - the map of the memory (as returned from `bus_dmamem_alloc()`)" msgstr "_map_ - карта памяти (как возвращается из `bus_dmamem_alloc()`)" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:400 msgid "" "`int bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)`" msgstr "" "`int bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:402 msgid "" "Create a map for the tag, to be used in `bus_dmamap_load()` later. Returns 0 " "on success, the error code otherwise." msgstr "" "Создать карту для тега, которая будет использоваться в `bus_dmamap_load()` " "позже. Возвращает 0 при успехе, в противном случае — код ошибки." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:405 msgid "" "_flags_ - theoretically, a bit map of flags. But no flags are defined yet, " "so at present it will be always 0." msgstr "" "_flags_ - теоретически, битовая карта флагов. Однако пока никакие флаги не " "определены, поэтому в настоящее время значение всегда будет 0." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:406 msgid "_mapp_ - pointer to the storage for the new map to be returned" msgstr "" "_mapp_ - указатель на хранилище для новой карты, которая будет возвращена" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:408 msgid "`int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)`" msgstr "`int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:410 msgid "Destroy a map. Returns 0 on success, the error code otherwise." msgstr "" "Уничтожить карту. Возвращает 0 при успехе, в противном случае — код ошибки." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:412 msgid "dmat - the tag to which the map is associated" msgstr "dmat - тег, с которым ассоциирована карта" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:413 msgid "map - the map to be destroyed" msgstr "map - карта, подлежащая уничтожению" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:415 msgid "" "`int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, " "bus_size_t buflen, bus_dmamap_callback_t *callback, void *callback_arg, int " "flags)`" msgstr "" "`int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, " "bus_size_t buflen, bus_dmamap_callback_t *callback, void *callback_arg, int " "flags)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:417 msgid "" "Load a buffer into the map (the map must be previously created by " "`bus_dmamap_create()` or `bus_dmamem_alloc()`). All the pages of the buffer " "are checked for conformance to the tag requirements and for those not " "conformant the bounce pages are allocated. An array of physical segment " "descriptors is built and passed to the callback routine. This callback " "routine is then expected to handle it in some way. The number of bounce " "buffers in the system is limited, so if the bounce buffers are needed but " "not immediately available the request will be queued and the callback will " "be called when the bounce buffers will become available. Returns 0 if the " "callback was executed immediately or `EINPROGRESS` if the request was queued " "for future execution. In the latter case the synchronization with queued " "callback routine is the responsibility of the driver." msgstr "" "Загрузить буфер в карту (карта должна быть предварительно создана с помощью " "`bus_dmamap_create()` или `bus_dmamem_alloc()`). Все страницы буфера " "проверяются на соответствие требованиям тега, и для несоответствующих " "выделяются промежуточные страницы. Создается массив дескрипторов физических " "сегментов и передаётся в подпрограмму обратного вызова. Ожидается, что эта " "подпрограмма обработает его каким-либо образом. Количество промежуточных " "буферов в системе ограничено, поэтому, если эти буферы требуются, но " "недоступны немедленно, запрос будет поставлен в очередь, и обратный вызов " "будет выполнен, когда промежуточные буферы станут доступны. Возвращает 0, " "если обратный вызов был выполнен немедленно, или `EINPROGRESS`, если запрос " "был поставлен в очередь для выполнения в будущем. В последнем случае " "синхронизация с подпрограммой обратного вызова, поставленной в очередь, " "является обязанностью драйвера." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:420 msgid "_map_ - the map" msgstr "_map_ - карта" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:421 msgid "_buf_ - kernel virtual address of the buffer" msgstr "_buf_ - виртуальный адрес буфера в пространстве ядра" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:422 msgid "_buflen_ - length of the buffer" msgstr "_buflen_ - длина буфера" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:423 msgid "_callback_, `callback_arg` - the callback function and its argument" msgstr "_callback_, `callback_arg` - функция обратного вызова и её аргумент" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:425 msgid "" "The prototype of callback function is: `void callback(void *arg, " "bus_dma_segment_t *seg, int nseg, int error)`" msgstr "" "Прототип функции обратного вызова: `void callback(void *arg, " "bus_dma_segment_t *seg, int nseg, int error)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:427 msgid "_arg_ - the same as callback_arg passed to `bus_dmamap_load()`" msgstr "" "_arg_ - то же самое, что и callback_arg, переданный в `bus_dmamap_load()`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:428 msgid "_seg_ - array of the segment descriptors" msgstr "_seg_ - массив дескрипторов сегментов" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:429 msgid "_nseg_ - number of descriptors in array" msgstr "_nseg_ - количество дескрипторов в массиве" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:430 msgid "" "_error_ - indication of the segment number overflow: if it is set to `EFBIG` " "then the buffer did not fit into the maximal number of segments permitted by " "the tag. In this case only the permitted number of descriptors will be in " "the array. Handling of this situation is up to the driver: depending on the " "desired semantics it can either consider this an error or split the buffer " "in two and handle the second part separately" msgstr "" "_error_ - указание на переполнение номера сегмента: если установлено " "значение `EFBIG`, значит буфер не поместился в максимальное количество " "сегментов, разрешённых тегом. В этом случае в массиве будет только " "разрешённое количество дескрипторов. Обработка этой ситуации зависит от " "драйвера: в зависимости от желаемой семантики он может либо считать это " "ошибкой, либо разделить буфер на две части и обработать вторую часть отдельно" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:432 msgid "Each entry in the segments array contains the fields:" msgstr "Каждая запись в массиве segments содержит поля:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:434 msgid "_ds_addr_ - physical bus address of the segment" msgstr "_ds_addr_ - физический адрес шины сегмента" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:435 msgid "_ds_len_ - length of the segment" msgstr "_ds_len_ - длина сегмента" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:437 msgid "`void bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)`" msgstr "`void bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:439 msgid "unload the map." msgstr "выгрузить карту." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:441 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:448 msgid "_dmat_ - tag" msgstr "_dmat_ - тег" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:442 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:449 msgid "_map_ - loaded map" msgstr "_map_ - загруженная карта" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:444 msgid "" "`void bus_dmamap_sync (bus_dma_tag_t dmat, bus_dmamap_t map, " "bus_dmasync_op_t op)`" msgstr "" "`void bus_dmamap_sync (bus_dma_tag_t dmat, bus_dmamap_t map, " "bus_dmasync_op_t op)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:446 msgid "" "Synchronise a loaded buffer with its bounce pages before and after physical " "transfer to or from device. This is the function that does all the necessary " "copying of data between the original buffer and its mapped version. The " "buffers must be synchronized both before and after doing the transfer." msgstr "" "Синхронизировать загруженный буфер с его промежуточными страницами до и " "после физической передачи на устройство или с устройства. Это функция, " "которая выполняет все необходимое копирование данных между исходным буфером " "и его отображенной версией. Буферы должны быть синхронизированы как до, так " "и после выполнения передачи." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:450 msgid "_op_ - type of synchronization operation to perform:" msgstr "_op_ - тип операции синхронизации для выполнения:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:452 msgid "`BUS_DMASYNC_PREREAD` - before reading from device into buffer" msgstr "`BUS_DMASYNC_PREREAD` - перед чтением с устройства в буфер" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:453 msgid "`BUS_DMASYNC_POSTREAD` - after reading from device into buffer" msgstr "`BUS_DMASYNC_POSTREAD` - после чтения из устройства в буфер" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:454 msgid "`BUS_DMASYNC_PREWRITE` - before writing the buffer to device" msgstr "`BUS_DMASYNC_PREWRITE` - перед записью буфера в устройство" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:455 msgid "`BUS_DMASYNC_POSTWRITE` - after writing the buffer to device" msgstr "`BUS_DMASYNC_POSTWRITE` - после записи буфера в устройство" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:457 msgid "" "As of now PREREAD and POSTWRITE are null operations but that may change in " "the future, so they must not be ignored in the driver. Synchronization is " "not needed for the memory obtained from `bus_dmamem_alloc()`." msgstr "" "На данный момент PREREAD и POSTWRITE являются пустыми операциями, но это " "может измениться в будущем, поэтому их нельзя игнорировать в драйвере. " "Синхронизация не требуется для памяти, полученной из `bus_dmamem_alloc()`." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:459 msgid "" "Before calling the callback function from `bus_dmamap_load()` the segment " "array is stored in the stack. And it gets pre-allocated for the maximal " "number of segments allowed by the tag. As a result of this the practical " "limit for the number of segments on i386 architecture is about 250-300 (the " "kernel stack is 4KB minus the size of the user structure, size of a segment " "array entry is 8 bytes, and some space must be left). Since the array is " "allocated based on the maximal number this value must not be set higher than " "really needed. Fortunately, for most of hardware the maximal supported " "number of segments is much lower. But if the driver wants to handle buffers " "with a very large number of scatter-gather segments it should do that in " "portions: load part of the buffer, transfer it to the device, load next part " "of the buffer, and so on." msgstr "" "Перед вызовом функции обратного вызова из `bus_dmamap_load()` массив " "сегментов сохраняется в стеке. Он предварительно выделяется для " "максимального количества сегментов, разрешенного тегом. В результате этого " "практический предел количества сегментов на архитектуре i386 составляет " "около 250-300 (размер стека ядра — 4 КБ минус размер структуры пользователя, " "размер элемента массива сегментов — 8 байт, и необходимо оставить некоторое " "пространство). Поскольку массив выделяется исходя из максимального числа, " "это значение не должно быть установлено выше, чем действительно необходимо. " "К счастью, для большинства оборудования максимально поддерживаемое " "количество сегментов значительно ниже. Но если драйвер должен обрабатывать " "буферы с очень большим количеством сегментов scatter-gather, он должен " "делать это по частям: загрузить часть буфера, передать его устройству, " "загрузить следующую часть буфера и так далее." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:461 msgid "" "Another practical consequence is that the number of segments may limit the " "size of the buffer. If all the pages in the buffer happen to be physically " "non-contiguous then the maximal supported buffer size for that fragmented " "case would be (nsegments * page_size). For example, if a maximal number of " "10 segments is supported then on i386 maximal guaranteed supported buffer " "size would be 40K. If a higher size is desired then special tricks should be " "used in the driver." msgstr "" "Еще одно практическое следствие заключается в том, что количество сегментов " "может ограничивать размер буфера. Если все страницы в буфере окажутся " "физически несмежными, то максимальный поддерживаемый размер буфера для " "такого фрагментированного случая будет равен (nsegments * page_size). " "Например, если поддерживается максимальное количество сегментов, равное 10, " "то на i386 максимальный гарантированно поддерживаемый размер буфера составит " "40K. Если требуется больший размер, то в драйвере следует использовать " "специальные приемы." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:463 msgid "" "If the hardware does not support scatter-gather at all or the driver wants " "to support some buffer size even if it is heavily fragmented then the " "solution is to allocate a contiguous buffer in the driver and use it as " "intermediate storage if the original buffer does not fit." msgstr "" "Если оборудование не поддерживает scatter-gather вообще или драйвер хочет " "поддерживать некоторый размер буфера, даже если он сильно фрагментирован, то " "решение состоит в выделении непрерывного буфера в драйвере и использовании " "его в качестве промежуточного хранилища, если исходный буфер не подходит." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:465 msgid "" "Below are the typical call sequences when using a map depend on the use of " "the map. The characters -> are used to show the flow of time." msgstr "" "Ниже представлены типичные последовательности вызовов при использовании " "карты в зависимости от её назначения. Символы -> используются для " "обозначения последовательности во времени." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:467 msgid "" "For a buffer which stays practically fixed during all the time between " "attachment and detachment of a device:" msgstr "" "Для буфера, который остаётся практически неизменным в течение всего времени " "между присоединением и отсоединением устройства:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:469 msgid "" "bus_dmamem_alloc -> bus_dmamap_load -> ...use buffer... -> -> " "bus_dmamap_unload -> bus_dmamem_free" msgstr "" "bus_dmamem_alloc -> bus_dmamap_load -> ...use buffer... -> -> " "bus_dmamap_unload -> bus_dmamem_free" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:471 msgid "" "For a buffer that changes frequently and is passed from outside the driver:" msgstr "Для буфера, который часто изменяется и передаётся извне драйвера:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:480 #, no-wrap msgid "" " bus_dmamap_create ->\n" " -> bus_dmamap_load -> bus_dmamap_sync(PRE...) -> do transfer ->\n" " -> bus_dmamap_sync(POST...) -> bus_dmamap_unload ->\n" " ...\n" " -> bus_dmamap_load -> bus_dmamap_sync(PRE...) -> do transfer ->\n" " -> bus_dmamap_sync(POST...) -> bus_dmamap_unload ->\n" " -> bus_dmamap_destroy\n" msgstr "" " bus_dmamap_create ->\n" " -> bus_dmamap_load -> bus_dmamap_sync(PRE...) -> do transfer ->\n" " -> bus_dmamap_sync(POST...) -> bus_dmamap_unload ->\n" " ...\n" " -> bus_dmamap_load -> bus_dmamap_sync(PRE...) -> do transfer ->\n" " -> bus_dmamap_sync(POST...) -> bus_dmamap_unload ->\n" " -> bus_dmamap_destroy\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:483 msgid "" "When loading a map created by `bus_dmamem_alloc()` the passed address and " "size of the buffer must be the same as used in `bus_dmamem_alloc()`. In this " "case it is guaranteed that the whole buffer will be mapped as one segment " "(so the callback may be based on this assumption) and the request will be " "executed immediately (EINPROGRESS will never be returned). All the callback " "needs to do in this case is to save the physical address." msgstr "" "При загрузке карты, созданной `bus_dmamem_alloc()`, переданные адрес и " "размер буфера должны быть такими же, как использованные в " "`bus_dmamem_alloc()`. В этом случае гарантируется, что весь буфер будет " "отображен как один сегмент (так что обратный вызов может основываться на " "этом предположении) и запрос будет выполнен немедленно (EINPROGRESS никогда " "не будет возвращен). Все, что нужно сделать обратному вызову в этом случае, —" " это сохранить физический адрес." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:485 msgid "A typical example would be:" msgstr "Типичный пример:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:493 #, no-wrap msgid "" " static void\n" " alloc_callback(void *arg, bus_dma_segment_t *seg, int nseg, int error)\n" " {\n" " *(bus_addr_t *)arg = seg[0].ds_addr;\n" " }\n" msgstr "" " static void\n" " alloc_callback(void *arg, bus_dma_segment_t *seg, int nseg, int " "error)\n" " {\n" " *(bus_addr_t *)arg = seg[0].ds_addr;\n" " }\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:504 #, no-wrap msgid "" " ...\n" " int error;\n" " struct somedata {\n" " ....\n" " };\n" " struct somedata *vsomedata; /* virtual address */\n" " bus_addr_t psomedata; /* physical bus-relative address */\n" " bus_dma_tag_t tag_somedata;\n" " bus_dmamap_t map_somedata;\n" " ...\n" msgstr "" " ...\n" " int error;\n" " struct somedata {\n" " ....\n" " };\n" " struct somedata *vsomedata; /* virtual address */\n" " bus_addr_t psomedata; /* physical bus-relative address */\n" " bus_dma_tag_t tag_somedata;\n" " bus_dmamap_t map_somedata;\n" " ...\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:512 #, no-wrap msgid "" " error=bus_dma_tag_create(parent_tag, alignment,\n" " boundary, lowaddr, highaddr, /*filter*/ NULL, /*filterarg*/ NULL,\n" " /*maxsize*/ sizeof(struct somedata), /*nsegments*/ 1,\n" " /*maxsegsz*/ sizeof(struct somedata), /*flags*/ 0,\n" " &tag_somedata);\n" " if(error)\n" " return error;\n" msgstr "" " error=bus_dma_tag_create(parent_tag, alignment,\n" " boundary, lowaddr, highaddr, /*filter*/ NULL, /*filterarg*/ NULL," "\n" " /*maxsize*/ sizeof(struct somedata), /*nsegments*/ 1,\n" " /*maxsegsz*/ sizeof(struct somedata), /*flags*/ 0,\n" " &tag_somedata);\n" " if(error)\n" " return error;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:517 #, no-wrap msgid "" " error = bus_dmamem_alloc(tag_somedata, &vsomedata, /* flags*/ 0,\n" " &map_somedata);\n" " if(error)\n" " return error;\n" msgstr "" " error = bus_dmamem_alloc(tag_somedata, &vsomedata, /* flags*/ 0,\n" " &map_somedata);\n" " if(error)\n" " return error;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:521 #, no-wrap msgid "" " bus_dmamap_load(tag_somedata, map_somedata, (void *)vsomedata,\n" " sizeof (struct somedata), alloc_callback,\n" " (void *) &psomedata, /*flags*/0);\n" msgstr "" " bus_dmamap_load(tag_somedata, map_somedata, (void *)vsomedata,\n" " sizeof (struct somedata), alloc_callback,\n" " (void *) &psomedata, /*flags*/0);\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:524 msgid "" "Looks a bit long and complicated but that is the way to do it. The practical " "consequence is: if multiple memory areas are allocated always together it " "would be a really good idea to combine them all into one structure and " "allocate as one (if the alignment and boundary limitations permit)." msgstr "" "Выглядит немного длинно и сложно, но это правильный способ. Практическое " "следствие таково: если несколько областей памяти выделяются всегда вместе, " "было бы отличной идеей объединить их все в одну структуру и выделять как " "единое целое (если ограничения выравнивания и границ позволяют)." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:526 msgid "" "When loading an arbitrary buffer into the map created by " "`bus_dmamap_create()` special measures must be taken to synchronize with the " "callback in case it would be delayed. The code would look like:" msgstr "" "При загрузке произвольного буфера в карту, созданную `bus_dmamap_create()`, " "необходимо принять специальные меры для синхронизации с обратным вызовом, " "если он будет задержан. Код будет выглядеть следующим образом:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:532 #, no-wrap msgid "" " {\n" " int s;\n" " int error;\n" msgstr "" " {\n" " int s;\n" " int error;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:551 #, no-wrap msgid "" " s = splsoftvm();\n" " error = bus_dmamap_load(\n" " dmat,\n" " dmamap,\n" " buffer_ptr,\n" " buffer_len,\n" " callback,\n" " /*callback_arg*/ buffer_descriptor,\n" " /*flags*/0);\n" " if (error == EINPROGRESS) {\n" " /*\n" " * Do whatever is needed to ensure synchronization\n" " * with callback. Callback is guaranteed not to be started\n" " * until we do splx() or tsleep().\n" " */\n" " }\n" " splx(s);\n" " }\n" msgstr "" " s = splsoftvm();\n" " error = bus_dmamap_load(\n" " dmat,\n" " dmamap,\n" " buffer_ptr,\n" " buffer_len,\n" " callback,\n" " /*callback_arg*/ buffer_descriptor,\n" " /*flags*/0);\n" " if (error == EINPROGRESS) {\n" " /*\n" " * Do whatever is needed to ensure synchronization\n" " * with callback. Callback is guaranteed not to be started\n" " * until we do splx() or tsleep().\n" " */\n" " }\n" " splx(s);\n" " }\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:554 msgid "Two possible approaches for the processing of requests are:" msgstr "Два возможных подхода для обработки запросов:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:556 msgid "" "If requests are completed by marking them explicitly as done (such as the " "CAM requests) then it would be simpler to put all the further processing " "into the callback driver which would mark the request when it is done. Then " "not much extra synchronization is needed. For the flow control reasons it " "may be a good idea to freeze the request queue until this request gets " "completed." msgstr "" "Если запросы завершаются путём явной пометки их как выполненных (например, " "запросы CAM), то было бы проще поместить всю дальнейшую обработку в драйвер " "обратного вызова, который отмечал бы запрос по его завершении. В этом случае " "не потребуется много дополнительной синхронизации. По соображениям " "управления потоком может быть полезно заморозить очередь запросов до " "завершения этого запроса." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:558 msgid "" "If requests are completed when the function returns (such as classic read or " "write requests on character devices) then a synchronization flag should be " "set in the buffer descriptor and `tsleep()` called. Later when the callback " "gets called it will do its processing and check this synchronization flag. " "If it is set then the callback should issue a wakeup. In this approach the " "callback function could either do all the needed processing (just like the " "previous case) or simply save the segments array in the buffer descriptor. " "Then after callback completes the calling function could use this saved " "segments array and do all the processing." msgstr "" "Если запросы завершаются при возврате функции (например, классические " "запросы на чтение или запись для символьных устройств), то в дескрипторе " "буфера должен быть установлен флаг синхронизации и вызвана функция `tsleep()`" ". Позже, когда будет вызван обратный вызов, он выполнит свою обработку и " "проверит этот флаг синхронизации. Если флаг установлен, обратный вызов " "должен инициировать пробуждение. При таком подходе функция обратного вызова " "может либо выполнить всю необходимую обработку (как в предыдущем случае), " "либо просто сохранить массив сегментов в дескрипторе буфера. Затем после " "завершения обратного вызова вызывающая функция может использовать этот " "сохранённый массив сегментов и выполнить всю обработку." #. type: Title == #: documentation/content/en/books/arch-handbook/isa/_index.adoc:560 #, no-wrap msgid "DMA" msgstr "DMA" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:563 msgid "" "The Direct Memory Access (DMA) is implemented in the ISA bus through the DMA " "controller (actually, two of them but that is an irrelevant detail). To make " "the early ISA devices simple and cheap the logic of the bus control and " "address generation was concentrated in the DMA controller. Fortunately, " "FreeBSD provides a set of functions that mostly hide the annoying details of " "the DMA controller from the device drivers." msgstr "" "Прямой доступ к памяти (DMA) реализован в шине ISA через контроллер DMA (на " "самом деле их два, но это несущественная деталь). Чтобы сделать ранние " "устройства ISA простыми и дешёвыми, логика управления шиной и генерации " "адресов была сосредоточена в контроллере DMA. К счастью, FreeBSD " "предоставляет набор функций, которые в основном скрывают раздражающие детали " "работы контроллера DMA от драйверов устройств." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:565 msgid "" "The simplest case is for the fairly intelligent devices. Like the bus master " "devices on PCI they can generate the bus cycles and memory addresses all by " "themselves. The only thing they really need from the DMA controller is bus " "arbitration. So for this purpose they pretend to be cascaded slave DMA " "controllers. And the only thing needed from the system DMA controller is to " "enable the cascaded mode on a DMA channel by calling the following function " "when attaching the driver:" msgstr "" "Самый простой случай — для достаточно интеллектуальных устройств. Например, " "устройства с bus mastering на PCI могут сами генерировать шинные циклы и " "адреса памяти. Единственное, что им действительно нужно от контроллера DMA, —" " это арбитраж шины. Для этой цели они притворяются каскадированными " "подчинёнными контроллерами DMA. И единственное, что требуется от системного " "контроллера DMA, — это включить каскадный режим на канале DMA, вызвав " "следующую функцию при присоединении драйвера:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:567 msgid "`void isa_dmacascade(int channel_number)`" msgstr "`void isa_dmacascade(int channel_number)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:569 msgid "" "All the further activity is done by programming the device. When detaching " "the driver no DMA-related functions need to be called." msgstr "" "Все последующие действия выполняются путем программирования устройства. При " "отсоединении драйвера нет необходимости вызывать функции, связанные с DMA." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:571 msgid "" "For the simpler devices things get more complicated. The functions used are:" msgstr "" "Для более простых устройств всё становится сложнее. Используются следующие " "функции:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:573 msgid "`int isa_dma_acquire(int chanel_number)`" msgstr "`int isa_dma_acquire(int chanel_number)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:575 msgid "" "Reserve a DMA channel. Returns 0 on success or EBUSY if the channel was " "already reserved by this or a different driver. Most of the ISA devices are " "not able to share DMA channels anyway, so normally this function is called " "when attaching a device. This reservation was made redundant by the modern " "interface of bus resources but still must be used in addition to the latter. " "If not used then later, other DMA routines will panic." msgstr "" "Зарезервировать канал DMA. Возвращает 0 при успехе или EBUSY, если канал уже " "зарезервирован этим или другим драйвером. Большинство устройств ISA не " "способны совместно использовать каналы DMA, поэтому обычно эта функция " "вызывается при присоединении устройства. Это резервирование стало избыточным " "с появлением современного интерфейса ресурсов шины, но всё ещё должно " "использоваться в дополнение к последнему. Если резервирование не " "использовать, то в дальнейшем другие процедуры DMA вызовут панику ядра." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:576 msgid "`int isa_dma_release(int chanel_number)`" msgstr "`int isa_dma_release(int chanel_number)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:578 msgid "" "Release a previously reserved DMA channel. No transfers must be in progress " "when the channel is released (in addition the device must not try to " "initiate transfer after the channel is released)." msgstr "" "Освободить ранее зарезервированный канал DMA. На момент освобождения канала " "не должно быть активных передач (дополнительно устройство не должно пытаться " "инициировать передачу после освобождения канала)." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:579 msgid "`void isa_dmainit(int chan, u_int bouncebufsize)`" msgstr "`void isa_dmainit(int chan, u_int bouncebufsize)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:581 msgid "" "Allocate a bounce buffer for use with the specified channel. The requested " "size of the buffer can not exceed 64KB. This bounce buffer will be " "automatically used later if a transfer buffer happens to be not physically " "contiguous or outside of the memory accessible by the ISA bus or crossing " "the 64KB boundary. If the transfers will be always done from buffers which " "conform to these conditions (such as those allocated by `bus_dmamem_alloc()` " "with proper limitations) then `isa_dmainit()` does not have to be called. " "But it is quite convenient to transfer arbitrary data using the DMA " "controller. The bounce buffer will automatically care of the scatter-gather " "issues." msgstr "" "Выделить промежуточный буфер для использования с указанным каналом. " "Запрашиваемый размер буфера не может превышать 64 КБ. Этот промежуточный " "буфер будет автоматически использован в дальнейшем, если передаваемый буфер " "окажется не физически непрерывным, находится вне памяти, доступной шине ISA, " "или пересекает границу 64 КБ. Если передача всегда будет выполняться из " "буферов, соответствующих этим условиям (например, выделенных с помощью " "`bus_dmamem_alloc()` с соответствующими ограничениями), то вызов " "`isa_dmainit()` не требуется. Однако довольно удобно передавать произвольные " "данные с использованием контроллера DMA. Промежуточный буфер автоматически " "решит проблемы в ситуациях, когда данные разбросаны в памяти, и их надо " "собирать." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:583 msgid "_chan_ - channel number" msgstr "_chan_ - номер канала" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:584 msgid "_bouncebufsize_ - size of the bounce buffer in bytes" msgstr "_bouncebufsize_ - размер промежуточного буфера в байтах" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:586 msgid "`void isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)`" msgstr "`void isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:588 msgid "" "Prepare to start a DMA transfer. This function must be called to set up the " "DMA controller before actually starting transfer on the device. It checks " "that the buffer is contiguous and falls into the ISA memory range, if not " "then the bounce buffer is automatically used. If bounce buffer is required " "but not set up by `isa_dmainit()` or too small for the requested transfer " "size then the system will panic. In case of a write request with bounce " "buffer the data will be automatically copied to the bounce buffer." msgstr "" "Подготовка к началу передачи DMA. Эта функция должна быть вызвана для " "настройки контроллера DMA перед фактическим началом передачи на устройстве. " "Она проверяет, что буфер является непрерывным и попадает в диапазон памяти " "ISA, если нет, то автоматически используется промежуточный буфер. Если " "требуется промежуточный буфер, но он не настроен с помощью `isa_dmainit()` " "или слишком мал для запрошенного размера передачи, система перейдет в " "состояние паники. В случае запроса на запись с промежуточным буфером данные " "будут автоматически скопированы в этот буфер." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:589 msgid "" "flags - a bitmask determining the type of operation to be done. The " "direction bits B_READ and B_WRITE are mutually exclusive." msgstr "" "flags - битовая маска, определяющая тип выполняемой операции. Бит " "направления B_READ и B_WRITE являются взаимоисключающими." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:591 msgid "B_READ - read from the ISA bus into memory" msgstr "B_READ - чтение с шины ISA в память" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:592 msgid "B_WRITE - write from the memory to the ISA bus" msgstr "B_WRITE - запись из памяти на шину ISA" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:593 msgid "" "B_RAW - if set then the DMA controller will remember the buffer and after " "the end of transfer will automatically re-initialize itself to repeat " "transfer of the same buffer again (of course, the driver may change the data " "in the buffer before initiating another transfer in the device). If not set " "then the parameters will work only for one transfer, and `isa_dmastart()` " "will have to be called again before initiating the next transfer. Using " "B_RAW makes sense only if the bounce buffer is not used." msgstr "" "B_RAW - если установлен, то контроллер DMA запомнит буфер и после завершения " "передачи автоматически переинициализирует себя для повторной передачи того " "же буфера (конечно, драйвер может изменить данные в буфере перед " "инициированием следующей передачи на устройстве). Если не установлен, то " "параметры будут работать только для одной передачи, и перед инициированием " "следующей передачи снова потребуется вызвать `isa_dmastart()`. Использование " "B_RAW имеет смысл только если промежуточный буфер не используется." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:595 msgid "addr - virtual address of the buffer" msgstr "addr - виртуальный адрес буфера" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:596 msgid "" "nbytes - length of the buffer. Must be less or equal to 64KB. Length of 0 is " "not allowed: the DMA controller will understand it as 64KB while the kernel " "code will understand it as 0 and that would cause unpredictable effects. For " "channels number 4 and higher the length must be even because these channels " "transfer 2 bytes at a time. In case of an odd length the last byte will not " "be transferred." msgstr "" "nbytes - длина буфера. Должна быть меньше или равна 64 КБ. Длина 0 не " "допускается: контроллер DMA интерпретирует это как 64 КБ, в то время как код " "ядра поймёт это как 0, что приведёт к непредсказуемым последствиям. Для " "каналов номер 4 и выше длина должна быть чётной, так как эти каналы передают " "по 2 байта за раз. В случае нечётной длины последний байт не будет передан." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:597 msgid "chan - channel number" msgstr "chan - номер канала" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:598 msgid "`void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)`" msgstr "`void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:600 msgid "" "Synchronize the memory after device reports that transfer is done. If that " "was a read operation with a bounce buffer then the data will be copied from " "the bounce buffer to the original buffer. Arguments are the same as for " "`isa_dmastart()`. Flag B_RAW is permitted but it does not affect " "`isa_dmadone()` in any way." msgstr "" "Синхронизировать память после того, как устройство сообщает о завершении " "передачи. Если это была операция чтения с промежуточным буфером, то данные " "будут скопированы из этого буфера в исходный буфер. Аргументы такие же, как " "у `isa_dmastart()`. Флаг B_RAW разрешён, но он никак не влияет на " "`isa_dmadone()`." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:601 msgid "`int isa_dmastatus(int channel_number)`" msgstr "`int isa_dmastatus(int channel_number)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:603 msgid "" "Returns the number of bytes left in the current transfer to be transferred. " "In case the flag B_READ was set in `isa_dmastart()` the number returned will " "never be equal to zero. At the end of transfer it will be automatically " "reset back to the length of buffer. The normal use is to check the number of " "bytes left after the device signals that the transfer is completed. If the " "number of bytes is not 0 then something probably went wrong with that " "transfer." msgstr "" "Возвращает количество оставшихся для передачи байт в текущей передаче. Если " "флаг B_READ был установлен в `isa_dmastart()`, возвращаемое значение никогда " "не будет равно нулю. В конце передачи оно автоматически сбрасывается обратно " "к длине буфера. Обычное использование — проверка количества оставшихся байт " "после того, как устройство сигнализирует о завершении передачи. Если " "количество байт не равно 0, то, вероятно, в передаче произошла ошибка." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:604 msgid "`int isa_dmastop(int channel_number)`" msgstr "`int isa_dmastop(int channel_number)`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:606 msgid "" "Aborts the current transfer and returns the number of bytes left " "untransferred." msgstr "Прерывает текущую передачу и возвращает количество непереданных байтов." #. type: Title == #: documentation/content/en/books/arch-handbook/isa/_index.adoc:608 #, no-wrap msgid "xxx_isa_probe" msgstr "xxx_isa_probe" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:611 msgid "" "This function probes if a device is present. If the driver supports auto-" "detection of some part of device configuration (such as interrupt vector or " "memory address) this auto-detection must be done in this routine." msgstr "" "Эта функция проверяет наличие устройства. Если драйвер поддерживает " "автоматическое определение некоторых параметров конфигурации устройства (" "таких как вектор прерывания или адрес памяти), это автоматическое " "определение должно выполняться в данной процедуре." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:613 msgid "" "As for any other bus, if the device cannot be detected or is detected but " "failed the self-test or some other problem happened then it returns a " "positive value of error. The value `ENXIO` must be returned if the device is " "not present. Other error values may mean other conditions. Zero or negative " "values mean success. Most of the drivers return zero as success." msgstr "" "Как и для любой другой шины, если устройство не может быть обнаружено, или " "обнаружено, но не прошло самопроверку, или возникла другая проблема, то " "возвращается положительное значение ошибки. Значение `ENXIO` должно " "возвращаться, если устройство отсутствует. Другие значения ошибок могут " "означать иные условия. Нулевые или отрицательные значения означают успех. " "Большинство драйверов возвращают ноль в случае успеха." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:615 msgid "" "The negative return values are used when a PnP device supports multiple " "interfaces. For example, an older compatibility interface and a newer " "advanced interface which are supported by different drivers. Then both " "drivers would detect the device. The driver which returns a higher value in " "the probe routine takes precedence (in other words, the driver returning 0 " "has highest precedence, one returning -1 is next, one returning -2 is after " "it and so on). In result the devices which support only the old interface " "will be handled by the old driver (which should return -1 from the probe " "routine) while the devices supporting the new interface as well will be " "handled by the new driver (which should return 0 from the probe routine)." msgstr "" "Отрицательные возвращаемые значения используются, когда устройство PnP " "поддерживает несколько интерфейсов. Например, старый совместимый интерфейс и " "новый расширенный интерфейс, которые поддерживаются разными драйверами. В " "этом случае оба драйвера обнаружат устройство. Драйвер, который возвращает " "большее значение в процедуре обнаружения, получает приоритет (другими " "словами, драйвер, возвращающий 0, имеет наивысший приоритет, возвращающий -1 " "— следующий, возвращающий -2 — за ним и так далее). В результате устройства, " "поддерживающие только старый интерфейс, будут обрабатываться старым " "драйвером (который должен возвращать -1 из процедуры probe), а устройства, " "поддерживающие также новый интерфейс, будут обрабатываться новым драйвером (" "который должен возвращать 0 из процедуры обнаружения)." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:617 msgid "" "The device descriptor struct xxx_softc is allocated by the system before " "calling the probe routine. If the probe routine returns an error the " "descriptor will be automatically deallocated by the system. So if a probing " "error occurs the driver must make sure that all the resources it used during " "probe are deallocated and that nothing keeps the descriptor from being " "safely deallocated. If the probe completes successfully the descriptor will " "be preserved by the system and later passed to the routine " "`xxx_isa_attach()`. If a driver returns a negative value it can not be sure " "that it will have the highest priority and its attach routine will be " "called. So in this case it also must release all the resources before " "returning and if necessary allocate them again in the attach routine. When " "`xxx_isa_probe()` returns 0 releasing the resources before returning is also " "a good idea and a well-behaved driver should do so. But in cases where there " "is some problem with releasing the resources the driver is allowed to keep " "resources between returning 0 from the probe routine and execution of the " "attach routine." msgstr "" "Структура дескриптора устройства `xxx_softc` выделяется системой до вызова " "процедуры обнаружения. Если процедура обнаружения возвращает ошибку, " "дескриптор автоматически освобождается системой. Поэтому при возникновении " "ошибки обнаружения драйвер должен убедиться, что все ресурсы, использованные " "во время обнаружения, освобождены и ничто не мешает безопасному освобождению " "дескриптора.Если обнаружение завершается успешно, дескриптор сохраняется " "системой и позже передаётся в процедуру `xxx_isa_attach()`. Если драйвер " "возвращает отрицательное значение, он не может быть уверен, что получит " "наивысший приоритет и его процедура присоединения будет вызвана. Поэтому в " "этом случае он также должен освободить все ресурсы перед возвратом и, если " "необходимо, выделить их снова в процедуре присоединения. Когда " "`xxx_isa_probe()` возвращает 0, освобождение ресурсов перед возвратом также " "является хорошей практикой, и корректно работающий драйвер должен так " "поступать. Однако в случаях, когда возникают проблемы с освобождением " "ресурсов, драйверу разрешается сохранять ресурсы между возвратом 0 из " "процедуры обнаружения и выполнением процедуры присоединения." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:619 msgid "" "A typical probe routine starts with getting the device descriptor and unit:" msgstr "" "Типичная процедура обнаружения начинается с получения дескриптора устройства " "и номера устройства:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:626 #, no-wrap msgid "" " struct xxx_softc *sc = device_get_softc(dev);\n" " int unit = device_get_unit(dev);\n" " int pnperror;\n" " int error = 0;\n" msgstr "" " struct xxx_softc *sc = device_get_softc(dev);\n" " int unit = device_get_unit(dev);\n" " int pnperror;\n" " int error = 0;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:629 #, no-wrap msgid "" " sc->dev = dev; /* link it back */\n" " sc->unit = unit;\n" msgstr "" " sc->dev = dev; /* link it back */\n" " sc->unit = unit;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:632 msgid "" "Then check for the PnP devices. The check is carried out by a table " "containing the list of PnP IDs supported by this driver and human-readable " "descriptions of the device models corresponding to these IDs." msgstr "" "Затем проверьте устройства PnP. Проверка осуществляется с помощью таблицы, " "содержащей список PnP ID, поддерживаемых этим драйвером, и удобочитаемые " "описания моделей устройств, соответствующих этим ID." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:638 #, no-wrap msgid "" " pnperror=ISA_PNP_PROBE(device_get_parent(dev), dev,\n" " xxx_pnp_ids); if(pnperror == ENXIO) return ENXIO;\n" msgstr "" " pnperror=ISA_PNP_PROBE(device_get_parent(dev), dev,\n" " xxx_pnp_ids); if(pnperror == ENXIO) return ENXIO;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:641 msgid "" "The logic of ISA_PNP_PROBE is the following: If this card (device unit) was " "not detected as PnP then ENOENT will be returned. If it was detected as PnP " "but its detected ID does not match any of the IDs in the table then ENXIO is " "returned. Finally, if it has PnP support and it matches on of the IDs in the " "table, 0 is returned and the appropriate description from the table is set " "by `device_set_desc()`." msgstr "" "Логика работы `ISA_PNP_PROBE` следующая: если данная карта (устройство) не " "была обнаружена как PnP, то будет возвращено `ENOENT`. Если она была " "обнаружена как PnP, но её обнаруженный ID не совпадает ни с одним из ID в " "таблице, то возвращается `ENXIO`. Наконец, если устройство поддерживает PnP " "и его ID совпадает с одним из ID в таблице, возвращается `0`, а " "соответствующее описание из таблицы устанавливается с помощью " "`device_set_desc()`." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:643 msgid "" "If a driver supports only PnP devices then the condition would look like:" msgstr "" "Если драйвер поддерживает только устройства PnP, то условие будет выглядеть " "следующим образом:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:648 #, no-wrap msgid "" " if(pnperror != 0)\n" " return pnperror;\n" msgstr "" " if(pnperror != 0)\n" " return pnperror;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:651 msgid "" "No special treatment is required for the drivers which do not support PnP " "because they pass an empty PnP ID table and will always get ENXIO if called " "on a PnP card." msgstr "" "Для драйверов, которые не поддерживают PnP, не требуется специальной " "обработки, так как они передают пустую таблицу идентификаторов PnP и всегда " "будут получать ENXIO при вызове на PnP-карте." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:653 msgid "" "The probe routine normally needs at least some minimal set of resources, " "such as I/O port number to find the card and probe it. Depending on the " "hardware the driver may be able to discover the other necessary resources " "automatically. The PnP devices have all the resources pre-set by the PnP " "subsystem, so the driver does not need to discover them by itself." msgstr "" "Функция обнаружения обычно требует как минимум некоторый минимальный набор " "ресурсов, например, номер порта ввода-вывода, чтобы найти карту и проверить " "её. В зависимости от оборудования драйвер может автоматически обнаружить " "другие необходимые ресурсы. Устройства PnP имеют все ресурсы, предварительно " "установленные подсистемой PnP, поэтому драйверу не нужно обнаруживать их " "самостоятельно." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:655 msgid "" "Typically the minimal information required to get access to the device is " "the I/O port number. Then some devices allow to get the rest of information " "from the device configuration registers (though not all devices do that). So " "first we try to get the port start value:" msgstr "" "Обычно минимальная информация, необходимая для доступа к устройству, — это " "номер порта ввода-вывода. Затем некоторые устройства позволяют получить " "остальную информацию из регистров конфигурации устройства (хотя не все " "устройства это поддерживают). Поэтому сначала мы пытаемся получить начальное " "значение порта:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:660 #, no-wrap msgid "" " sc->port0 = bus_get_resource_start(dev,\n" " SYS_RES_IOPORT, 0 /*rid*/); if(sc->port0 == 0) return ENXIO;\n" msgstr "" " sc->port0 = bus_get_resource_start(dev,\n" " SYS_RES_IOPORT, 0 /*rid*/); if(sc->port0 == 0) return ENXIO;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:663 msgid "" "The base port address is saved in the structure softc for future use. If it " "will be used very often then calling the resource function each time would " "be prohibitively slow. If we do not get a port we just return an error. Some " "device drivers can instead be clever and try to probe all the possible " "ports, like this:" msgstr "" "Базовый адрес порта сохраняется в структуре softc для последующего " "использования. Если он будет использоваться очень часто, то вызов функции " "ресурса каждый раз будет неприемлемо медленным. Если мы не получаем порт, мы " "просто возвращаем ошибку. Некоторые драйверы устройств могут вместо этого " "быть умнее и попытаться обнаружить все возможные порты, например:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:677 #, no-wrap msgid "" " /* table of all possible base I/O port addresses for this device */\n" " static struct xxx_allports {\n" " u_short port; /* port address */\n" " short used; /* flag: if this port is already used by some unit */\n" " } xxx_allports = {\n" " { 0x300, 0 },\n" " { 0x320, 0 },\n" " { 0x340, 0 },\n" " { 0, 0 } /* end of table */\n" " };\n" msgstr "" " /* table of all possible base I/O port addresses for this device */" "\n" " static struct xxx_allports {\n" " u_short port; /* port address */\n" " short used; /* flag: if this port is already used by some unit " "*/\n" " } xxx_allports = {\n" " { 0x300, 0 },\n" " { 0x320, 0 },\n" " { 0x340, 0 },\n" " { 0, 0 } /* end of table */\n" " };\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:681 #, no-wrap msgid "" " ...\n" " int port, i;\n" " ...\n" msgstr "" " ...\n" " int port, i;\n" " ...\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:687 #, no-wrap msgid "" " port = bus_get_resource_start(dev, SYS_RES_IOPORT, 0 /*rid*/);\n" " if(port !=0 ) {\n" " for(i=0; xxx_allports[i].port!=0; i++) {\n" " if(xxx_allports[i].used || xxx_allports[i].port != port)\n" " continue;\n" msgstr "" " port = bus_get_resource_start(dev, SYS_RES_IOPORT, 0 /*rid*/);\n" " if(port !=0 ) {\n" " for(i=0; xxx_allports[i].port!=0; i++) {\n" " if(xxx_allports[i].used || xxx_allports[i].port != port)\n" " continue;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:695 #, no-wrap msgid "" " /* found it */\n" " xxx_allports[i].used = 1;\n" " /* do probe on a known port */\n" " return xxx_really_probe(dev, port);\n" " }\n" " return ENXIO; /* port is unknown or already used */\n" " }\n" msgstr "" " /* found it */\n" " xxx_allports[i].used = 1;\n" " /* do probe on a known port */\n" " return xxx_really_probe(dev, port);\n" " }\n" " return ENXIO; /* port is unknown or already used */\n" " }\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:700 #, no-wrap msgid "" " /* we get here only if we need to guess the port */\n" " for(i=0; xxx_allports[i].port!=0; i++) {\n" " if(xxx_allports[i].used)\n" " continue;\n" msgstr "" " /* we get here only if we need to guess the port */\n" " for(i=0; xxx_allports[i].port!=0; i++) {\n" " if(xxx_allports[i].used)\n" " continue;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:705 #, no-wrap msgid "" " /* mark as used - even if we find nothing at this port\n" " * at least we won't probe it in future\n" " */\n" " xxx_allports[i].used = 1;\n" msgstr "" " /* mark as used - even if we find nothing at this port\n" " * at least we won't probe it in future\n" " */\n" " xxx_allports[i].used = 1;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:712 #, no-wrap msgid "" " error = xxx_really_probe(dev, xxx_allports[i].port);\n" " if(error == 0) /* found a device at that port */\n" " return 0;\n" " }\n" " /* probed all possible addresses, none worked */\n" " return ENXIO;\n" msgstr "" " error = xxx_really_probe(dev, xxx_allports[i].port);\n" " if(error == 0) /* found a device at that port */\n" " return 0;\n" " }\n" " /* probed all possible addresses, none worked */\n" " return ENXIO;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:715 msgid "" "Of course, normally the driver's `identify()` routine should be used for " "such things. But there may be one valid reason why it may be better to be " "done in `probe()`: if this probe would drive some other sensitive device " "crazy. The probe routines are ordered with consideration of the `sensitive` " "flag: the sensitive devices get probed first and the rest of the devices " "later. But the `identify()` routines are called before any probes, so they " "show no respect to the sensitive devices and may upset them." msgstr "" "Конечно, обычно для таких вещей следует использовать процедуру `identify()` " "драйвера. Однако может быть одна веская причина, почему лучше сделать это в " "`probe()`: если этот обнаружение может привести к сбою другого " "чувствительного устройства. Процедуры обнаружения упорядочены с учётом флага " "`sensitive`: чувствительные устройства проверяются первыми, а остальные " "устройства — позже. Но процедуры `identify()` вызываются до любого " "обнаружения, поэтому они не учитывают чувствительные устройства и могут " "вызвать их сбой." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:717 msgid "" "Now, after we got the starting port we need to set the port count (except " "for PnP devices) because the kernel does not have this information in the " "configuration file." msgstr "" "Вот, после того как мы получили начальный порт, необходимо установить " "количество портов (за исключением устройств PnP), так как в файле " "конфигурации ядра эта информация отсутствует." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:725 #, no-wrap msgid "" " if(pnperror /* only for non-PnP devices */\n" " && bus_set_resource(dev, SYS_RES_IOPORT, 0, sc->port0,\n" " XXX_PORT_COUNT)<0)\n" " return ENXIO;\n" msgstr "" " if(pnperror /* only for non-PnP devices */\n" " && bus_set_resource(dev, SYS_RES_IOPORT, 0, sc->port0,\n" " XXX_PORT_COUNT)<0)\n" " return ENXIO;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:728 msgid "" "Finally allocate and activate a piece of port address space (special values " "of start and end mean \"use those we set by ``bus_set_resource()``\"):" msgstr "" "Наконец, выделите и активируйте часть адресного пространства порта (" "специальные значения start и end означают \"используйте те, что мы " "установили через ``bus_set_resource()``\"):" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:736 #, no-wrap msgid "" " sc->port0_rid = 0;\n" " sc->port0_r = bus_alloc_resource(dev, SYS_RES_IOPORT,\n" " &sc->port0_rid,\n" " /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE);\n" msgstr "" " sc->port0_rid = 0;\n" " sc->port0_r = bus_alloc_resource(dev, SYS_RES_IOPORT,\n" " &sc->port0_rid,\n" " /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE);\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:739 #, no-wrap msgid "" " if(sc->port0_r == NULL)\n" " return ENXIO;\n" msgstr "" " if(sc->port0_r == NULL)\n" " return ENXIO;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:742 msgid "" "Now having access to the port-mapped registers we can poke the device in " "some way and check if it reacts like it is expected to. If it does not then " "there is probably some other device or no device at all at this address." msgstr "" "Теперь, имея доступ к регистрам с отображением на порты, мы можем каким-либо " "образом взаимодействовать с устройством и проверить, реагирует ли оно так, " "как ожидается. Если этого не происходит, вероятно, по этому адресу находится " "другое устройство или его там нет вовсе." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:744 msgid "" "Normally drivers do not set up the interrupt handlers until the attach " "routine. Instead they do probes in the polling mode using the `DELAY()` " "function for timeout. The probe routine must never hang forever, all the " "waits for the device must be done with timeouts. If the device does not " "respond within the time it is probably broken or misconfigured and the " "driver must return error. When determining the timeout interval give the " "device some extra time to be on the safe side: although `DELAY()` is " "supposed to delay for the same amount of time on any machine it has some " "margin of error, depending on the exact CPU." msgstr "" "Обычно драйверы не настраивают обработчики прерываний до вызова процедуры " "присоединения. Вместо этого они выполняют проверки в режиме опроса, " "используя функцию `DELAY()` для таймаута. Процедура проверки никогда не " "должна зависать навсегда, все ожидания ответа от устройства должны " "выполняться с таймаутами. Если устройство не отвечает в течение заданного " "времени, вероятно, оно неисправно или неправильно настроено, и драйвер " "должен вернуть ошибку. При определении интервала таймаута следует давать " "устройству дополнительное время для надёжности: хотя предполагается, что " "`DELAY()` задерживает выполнение на одинаковое время на любой машине, " "существует некоторая погрешность, зависящая от конкретного процессора." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:746 msgid "" "If the probe routine really wants to check that the interrupts really work " "it may configure and probe the interrupts too. But that is not recommended." msgstr "" "Если процедура проверки действительно хочет убедиться, что прерывания " "работают, она может также настроить и провести обнаружение прерываний. " "Однако это не рекомендуется." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:753 #, no-wrap msgid "" " /* implemented in some very device-specific way */\n" " if(error = xxx_probe_ports(sc))\n" " goto bad; /* will deallocate the resources before returning */\n" msgstr "" " /* implemented in some very device-specific way */\n" " if(error = xxx_probe_ports(sc))\n" " goto bad; /* will deallocate the resources before returning */" "\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:756 msgid "" "The function `xxx_probe_ports()` may also set the device description " "depending on the exact model of device it discovers. But if there is only " "one supported device model this can be as well done in a hardcoded way. Of " "course, for the PnP devices the PnP support sets the description from the " "table automatically." msgstr "" "Функция `xxx_probe_ports()` также может устанавливать описание устройства в " "зависимости от конкретной модели обнаруженного устройства. Но если " "поддерживается только одна модель устройства, это можно сделать и жёстко " "заданным способом. Конечно, для PnP-устройств поддержка PnP автоматически " "устанавливает описание из таблицы." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:761 #, no-wrap msgid "" " if(pnperror)\n" " device_set_desc(dev, \"Our device model 1234\");\n" msgstr "" " if(pnperror)\n" " device_set_desc(dev, \"Our device model 1234\");\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:764 msgid "" "Then the probe routine should either discover the ranges of all the " "resources by reading the device configuration registers or make sure that " "they were set explicitly by the user. We will consider it with an example of " "on-board memory. The probe routine should be as non-intrusive as possible, " "so allocation and check of functionality of the rest of resources (besides " "the ports) would be better left to the attach routine." msgstr "" "Затем процедура обнаружения должна либо определить диапазоны всех ресурсов, " "читая регистры конфигурации устройства, либо убедиться, что они были явно " "заданы пользователем. Мы рассмотрим это на примере встроенной памяти. " "Процедура обнаружения должна быть как можно менее навязчивой, поэтому " "выделение и проверку функциональности остальных ресурсов (кроме портов) " "лучше оставить для процедуры присоединения." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:766 msgid "" "The memory address may be specified in the kernel configuration file or on " "some devices it may be pre-configured in non-volatile configuration " "registers. If both sources are available and different, which one should be " "used? Probably if the user bothered to set the address explicitly in the " "kernel configuration file they know what they are doing and this one should " "take precedence. An example of implementation could be:" msgstr "" "Адрес памяти может быть указан в конфигурационном файле ядра, а на некоторых " "устройствах он может быть предварительно настроен в энергонезависимых " "конфигурационных регистрах. Если доступны оба источника, и они различаются, " "какой из них следует использовать? Вероятно, если пользователь явно указал " "адрес в конфигурационном файле ядра, он знает, что делает, и этот адрес " "должен иметь приоритет. Пример реализации может выглядеть так:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:774 #, no-wrap msgid "" " /* try to find out the config address first */\n" " sc->mem0_p = bus_get_resource_start(dev, SYS_RES_MEMORY, 0 /*rid*/);\n" " if(sc->mem0_p == 0) { /* nope, not specified by user */\n" " sc->mem0_p = xxx_read_mem0_from_device_config(sc);\n" msgstr "" " /* try to find out the config address first */\n" " sc->mem0_p = bus_get_resource_start(dev, SYS_RES_MEMORY, 0 " "/*rid*/);\n" " if(sc->mem0_p == 0) { /* nope, not specified by user */\n" " sc->mem0_p = xxx_read_mem0_from_device_config(sc);\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:782 #, no-wrap msgid "" " if(sc->mem0_p == 0)\n" " /* can't get it from device config registers either */\n" " goto bad;\n" " } else {\n" " if(xxx_set_mem0_address_on_device(sc) < 0)\n" " goto bad; /* device does not support that address */\n" " }\n" msgstr "" " if(sc->mem0_p == 0)\n" " /* can't get it from device config registers either */\n" " goto bad;\n" " } else {\n" " if(xxx_set_mem0_address_on_device(sc) < 0)\n" " goto bad; /* device does not support that address */\n" " }\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:794 #, no-wrap msgid "" " /* just like the port, set the memory size,\n" " * for some devices the memory size would not be constant\n" " * but should be read from the device configuration registers instead\n" " * to accommodate different models of devices. Another option would\n" " * be to let the user set the memory size as \"msize\" configuration\n" " * resource which will be automatically handled by the ISA bus.\n" " */\n" " if(pnperror) { /* only for non-PnP devices */\n" " sc->mem0_size = bus_get_resource_count(dev, SYS_RES_MEMORY, 0 /*rid*/);\n" " if(sc->mem0_size == 0) /* not specified by user */\n" " sc->mem0_size = xxx_read_mem0_size_from_device_config(sc);\n" msgstr "" " /* just like the port, set the memory size,\n" " * for some devices the memory size would not be constant\n" " * but should be read from the device configuration registers " "instead\n" " * to accommodate different models of devices. Another option " "would\n" " * be to let the user set the memory size as \"msize\" " "configuration\n" " * resource which will be automatically handled by the ISA bus.\n" " */\n" " if(pnperror) { /* only for non-PnP devices */\n" " sc->mem0_size = bus_get_resource_count(dev, SYS_RES_MEMORY, 0 " "/*rid*/);\n" " if(sc->mem0_size == 0) /* not specified by user */\n" " sc->mem0_size = xxx_read_mem0_size_from_device_config(sc);" "\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:803 #, no-wrap msgid "" " if(sc->mem0_size == 0) {\n" " /* suppose this is a very old model of device without\n" " * auto-configuration features and the user gave no preference,\n" " * so assume the minimalistic case\n" " * (of course, the real value will vary with the driver)\n" " */\n" " sc->mem0_size = 8*1024;\n" " }\n" msgstr "" " if(sc->mem0_size == 0) {\n" " /* suppose this is a very old model of device without\n" " * auto-configuration features and the user gave no " "preference,\n" " * so assume the minimalistic case\n" " * (of course, the real value will vary with the driver)\n" " */\n" " sc->mem0_size = 8*1024;\n" " }\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:806 #, no-wrap msgid "" " if(xxx_set_mem0_size_on_device(sc) < 0)\n" " goto bad; /* device does not support that size */\n" msgstr "" " if(xxx_set_mem0_size_on_device(sc) < 0)\n" " goto bad; /* device does not support that size */\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:813 #, no-wrap msgid "" " if(bus_set_resource(dev, SYS_RES_MEMORY, /*rid*/0,\n" " sc->mem0_p, sc->mem0_size)<0)\n" " goto bad;\n" " } else {\n" " sc->mem0_size = bus_get_resource_count(dev, SYS_RES_MEMORY, 0 /*rid*/);\n" " }\n" msgstr "" " if(bus_set_resource(dev, SYS_RES_MEMORY, /*rid*/0,\n" " sc->mem0_p, sc->mem0_size)<0)\n" " goto bad;\n" " } else {\n" " sc->mem0_size = bus_get_resource_count(dev, SYS_RES_MEMORY, 0 " "/*rid*/);\n" " }\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:816 msgid "Resources for IRQ and DRQ are easy to check by analogy." msgstr "Ресурсы для IRQ и DRQ легко проверить по аналогии." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:818 msgid "If all went well then release all the resources and return success." msgstr "" "Если всё прошло успешно, то освободите все ресурсы и верните успешный статус." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:823 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1086 #, no-wrap msgid "" " xxx_free_resources(sc);\n" " return 0;\n" msgstr "" " xxx_free_resources(sc);\n" " return 0;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:826 msgid "" "Finally, handle the troublesome situations. All the resources should be " "deallocated before returning. We make use of the fact that before the " "structure softc is passed to us it gets zeroed out, so we can find out if " "some resource was allocated: then its descriptor is non-zero." msgstr "" "Наконец, обработайте проблемные ситуации. Все ресурсы должны быть " "освобождены перед возвратом. Мы используем тот факт, что перед передачей нам " "структуры `softc` она обнуляется, поэтому мы можем определить, был ли " "выделен какой-либо ресурс: если его дескриптор не равен нулю." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:830 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1047 #, no-wrap msgid " bad:\n" msgstr " bad:\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:836 #, no-wrap msgid "" " xxx_free_resources(sc);\n" " if(error)\n" " return error;\n" " else /* exact error is unknown */\n" " return ENXIO;\n" msgstr "" " xxx_free_resources(sc);\n" " if(error)\n" " return error;\n" " else /* exact error is unknown */\n" " return ENXIO;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:839 msgid "" "That would be all for the probe routine. Freeing of resources is done from " "multiple places, so it is moved to a function which may look like:" msgstr "" "Вот и всё для процедуры обнаружения. Освобождение ресурсов выполняется из " "нескольких мест, поэтому оно вынесено в функцию, которая может выглядеть так:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:847 #, no-wrap msgid "" "static void\n" " xxx_free_resources(sc)\n" " struct xxx_softc *sc;\n" " {\n" " /* check every resource and free if not zero */\n" msgstr "" "static void\n" " xxx_free_resources(sc)\n" " struct xxx_softc *sc;\n" " {\n" " /* check every resource and free if not zero */\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:855 #, no-wrap msgid "" " /* interrupt handler */\n" " if(sc->intr_r) {\n" " bus_teardown_intr(sc->dev, sc->intr_r, sc->intr_cookie);\n" " bus_release_resource(sc->dev, SYS_RES_IRQ, sc->intr_rid,\n" " sc->intr_r);\n" " sc->intr_r = 0;\n" " }\n" msgstr "" " /* interrupt handler */\n" " if(sc->intr_r) {\n" " bus_teardown_intr(sc->dev, sc->intr_r, sc->intr_cookie);\n" " bus_release_resource(sc->dev, SYS_RES_IRQ, sc->intr_rid,\n" " sc->intr_r);\n" " sc->intr_r = 0;\n" " }\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:870 #, no-wrap msgid "" " /* all kinds of memory maps we could have allocated */\n" " if(sc->data_p) {\n" " bus_dmamap_unload(sc->data_tag, sc->data_map);\n" " sc->data_p = 0;\n" " }\n" " if(sc->data) { /* sc->data_map may be legitimately equal to 0 */\n" " /* the map will also be freed */\n" " bus_dmamem_free(sc->data_tag, sc->data, sc->data_map);\n" " sc->data = 0;\n" " }\n" " if(sc->data_tag) {\n" " bus_dma_tag_destroy(sc->data_tag);\n" " sc->data_tag = 0;\n" " }\n" msgstr "" " /* all kinds of memory maps we could have allocated */\n" " if(sc->data_p) {\n" " bus_dmamap_unload(sc->data_tag, sc->data_map);\n" " sc->data_p = 0;\n" " }\n" " if(sc->data) { /* sc->data_map may be legitimately equal to 0 " "*/\n" " /* the map will also be freed */\n" " bus_dmamem_free(sc->data_tag, sc->data, sc->data_map);\n" " sc->data = 0;\n" " }\n" " if(sc->data_tag) {\n" " bus_dma_tag_destroy(sc->data_tag);\n" " sc->data_tag = 0;\n" " }\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:872 #, no-wrap msgid " ... free other maps and tags if we have them ...\n" msgstr " ... free other maps and tags if we have them ...\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:877 #, no-wrap msgid "" " if(sc->parent_tag) {\n" " bus_dma_tag_destroy(sc->parent_tag);\n" " sc->parent_tag = 0;\n" " }\n" msgstr "" " if(sc->parent_tag) {\n" " bus_dma_tag_destroy(sc->parent_tag);\n" " sc->parent_tag = 0;\n" " }\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:891 #, no-wrap msgid "" " /* release all the bus resources */\n" " if(sc->mem0_r) {\n" " bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->mem0_rid,\n" " sc->mem0_r);\n" " sc->mem0_r = 0;\n" " }\n" " ...\n" " if(sc->port0_r) {\n" " bus_release_resource(sc->dev, SYS_RES_IOPORT, sc->port0_rid,\n" " sc->port0_r);\n" " sc->port0_r = 0;\n" " }\n" " }\n" msgstr "" " /* release all the bus resources */\n" " if(sc->mem0_r) {\n" " bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->mem0_rid," "\n" " sc->mem0_r);\n" " sc->mem0_r = 0;\n" " }\n" " ...\n" " if(sc->port0_r) {\n" " bus_release_resource(sc->dev, SYS_RES_IOPORT, " "sc->port0_rid,\n" " sc->port0_r);\n" " sc->port0_r = 0;\n" " }\n" " }\n" #. type: Title == #: documentation/content/en/books/arch-handbook/isa/_index.adoc:894 #, no-wrap msgid "xxx_isa_attach" msgstr "xxx_isa_attach" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:897 msgid "" "The attach routine actually connects the driver to the system if the probe " "routine returned success and the system had chosen to attach that driver. If " "the probe routine returned 0 then the attach routine may expect to receive " "the device structure softc intact, as it was set by the probe routine. Also " "if the probe routine returns 0 it may expect that the attach routine for " "this device shall be called at some point in the future. If the probe " "routine returns a negative value then the driver may make none of these " "assumptions." msgstr "" "Процедура присоединения фактически подключает драйвер к системе, если " "процедура обнаружения вернула успех, и система решила подключить этот " "драйвер. Если процедура обнаружения вернула 0, то процедура присоединения " "может ожидать, что получит структуру устройства `softc` в неизменном виде, " "как она была установлена процедурой обнаружения. Также, если обнаружение " "возвращает 0, она можно ожидать, что процедура присоединения для этого " "устройства будет вызвана в какой-то момент в будущем. Если процедура " "обнаружения возвращает отрицательное значение, то драйвер не может делать " "никаких из этих предположений." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:899 msgid "" "The attach routine returns 0 if it completed successfully or error code " "otherwise." msgstr "" "Процедура присоединение возвращает 0 при успешном завершении или код ошибки " "в противном случае." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:901 msgid "" "The attach routine starts just like the probe routine, with getting some " "frequently used data into more accessible variables." msgstr "" "Процедура присоединения начинается так же, как и процедура обнаружения, с " "помещения часто используемых данных в более доступные переменные." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:907 #, no-wrap msgid "" " struct xxx_softc *sc = device_get_softc(dev);\n" " int unit = device_get_unit(dev);\n" " int error = 0;\n" msgstr "" " struct xxx_softc *sc = device_get_softc(dev);\n" " int unit = device_get_unit(dev);\n" " int error = 0;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:910 msgid "" "Then allocate and activate all the necessary resources. As normally the port " "range will be released before returning from probe, it has to be allocated " "again. We expect that the probe routine had properly set all the resource " "ranges, as well as saved them in the structure softc. If the probe routine " "had left some resource allocated then it does not need to be allocated again " "(which would be considered an error)." msgstr "" "Затем выделите и активируйте все необходимые ресурсы. Обычно диапазон портов " "освобождается перед возвратом из обнаружения, поэтому его необходимо " "выделить снова. Мы предполагаем, что процедура обнаружения корректно " "установила все диапазоны ресурсов, а также сохранила их в структуре softc. " "Если процедура обнаружения оставила некоторые ресурсы выделенными, то их не " "нужно выделять снова (это будет считаться ошибкой)." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:916 #, no-wrap msgid "" " sc->port0_rid = 0;\n" " sc->port0_r = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port0_rid,\n" " /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE);\n" msgstr "" " sc->port0_rid = 0;\n" " sc->port0_r = bus_alloc_resource(dev, SYS_RES_IOPORT, " "&sc->port0_rid,\n" " /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE);\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:919 #, no-wrap msgid "" " if(sc->port0_r == NULL)\n" " return ENXIO;\n" msgstr "" " if(sc->port0_r == NULL)\n" " return ENXIO;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:924 #, no-wrap msgid "" " /* on-board memory */\n" " sc->mem0_rid = 0;\n" " sc->mem0_r = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem0_rid,\n" " /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE);\n" msgstr "" " /* on-board memory */\n" " sc->mem0_rid = 0;\n" " sc->mem0_r = bus_alloc_resource(dev, SYS_RES_MEMORY, " "&sc->mem0_rid,\n" " /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE);\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:927 #, no-wrap msgid "" " if(sc->mem0_r == NULL)\n" " goto bad;\n" msgstr "" " if(sc->mem0_r == NULL)\n" " goto bad;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:930 #, no-wrap msgid "" " /* get its virtual address */\n" " sc->mem0_v = rman_get_virtual(sc->mem0_r);\n" msgstr "" " /* get its virtual address */\n" " sc->mem0_v = rman_get_virtual(sc->mem0_r);\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:933 msgid "" "The DMA request channel (DRQ) is allocated likewise. To initialize it use " "functions of the `isa_dma*()` family. For example:" msgstr "" "Канал запроса DMA (DRQ) выделяется аналогично. Для его инициализации " "используйте функции семейства `isa_dma*()`. Например:" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:935 msgid "`isa_dmacascade(sc->drq0);`" msgstr "`isa_dmacascade(sc->drq0);`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:937 msgid "" "The interrupt request line (IRQ) is a bit special. Besides allocation the " "driver's interrupt handler should be associated with it. Historically in the " "old ISA drivers the argument passed by the system to the interrupt handler " "was the device unit number. But in modern drivers the convention suggests " "passing the pointer to structure softc. The important reason is that when " "the structures softc are allocated dynamically then getting the unit number " "from softc is easy while getting softc from the unit number is difficult. " "Also this convention makes the drivers for different buses look more uniform " "and allows them to share the code: each bus gets its own probe, attach, " "detach and other bus-specific routines while the bulk of the driver code may " "be shared among them." msgstr "" "Строка запроса прерывания (IRQ) является особенной. Помимо выделения, " "обработчик прерывания драйвера должен быть связан с ней. Исторически в " "старых драйверах ISA аргумент, передаваемый системой обработчику прерывания, " "был номером устройства. Однако в современных драйверах принято передавать " "указатель на структуру `softc`. Важная причина этого заключается в том, что " "когда структуры `softc` выделяются динамически, получение номера устройства " "из `softc` является простым, в то время как получение `softc` из номера " "устройства затруднительно. Кроме того, такое соглашение делает драйверы для " "различных шин более однородными и позволяет им совместно использовать код: " "каждая шина получает свои собственные процедуры обнаружения, присоединения, " "отсоединения и другие специфичные для шины функции, в то время как основная " "часть кода драйвера может быть общей для них." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:944 #, no-wrap msgid "" " sc->intr_rid = 0;\n" " sc->intr_r = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->intr_rid,\n" " /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE);\n" msgstr "" " sc->intr_rid = 0;\n" " sc->intr_r = bus_alloc_resource(dev, SYS_RES_MEMORY, " "&sc->intr_rid,\n" " /*start*/ 0, /*end*/ ~0, /*count*/ 0, RF_ACTIVE);\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:947 #, no-wrap msgid "" " if(sc->intr_r == NULL)\n" " goto bad;\n" msgstr "" " if(sc->intr_r == NULL)\n" " goto bad;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:956 #, no-wrap msgid "" " /*\n" " * XXX_INTR_TYPE is supposed to be defined depending on the type of\n" " * the driver, for example as INTR_TYPE_CAM for a CAM driver\n" " */\n" " error = bus_setup_intr(dev, sc->intr_r, XXX_INTR_TYPE,\n" " (driver_intr_t *) xxx_intr, (void *) sc, &sc->intr_cookie);\n" " if(error)\n" " goto bad;\n" msgstr "" " /*\n" " * XXX_INTR_TYPE is supposed to be defined depending on the type " "of\n" " * the driver, for example as INTR_TYPE_CAM for a CAM driver\n" " */\n" " error = bus_setup_intr(dev, sc->intr_r, XXX_INTR_TYPE,\n" " (driver_intr_t *) xxx_intr, (void *) sc, &sc->intr_cookie);\n" " if(error)\n" " goto bad;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:959 msgid "" "If the device needs to make DMA to the main memory then this memory should " "be allocated like described before:" msgstr "" "Если устройству необходимо выполнять DMA в основную память, то эта память " "должна быть выделена, как описано ранее:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:971 #, no-wrap msgid "" " error=bus_dma_tag_create(NULL, /*alignment*/ 4,\n" " /*boundary*/ 0, /*lowaddr*/ BUS_SPACE_MAXADDR_24BIT,\n" " /*highaddr*/ BUS_SPACE_MAXADDR, /*filter*/ NULL, /*filterarg*/ NULL,\n" " /*maxsize*/ BUS_SPACE_MAXSIZE_24BIT,\n" " /*nsegments*/ BUS_SPACE_UNRESTRICTED,\n" " /*maxsegsz*/ BUS_SPACE_MAXSIZE_24BIT, /*flags*/ 0,\n" " &sc->parent_tag);\n" " if(error)\n" " goto bad;\n" msgstr "" " error=bus_dma_tag_create(NULL, /*alignment*/ 4,\n" " /*boundary*/ 0, /*lowaddr*/ BUS_SPACE_MAXADDR_24BIT,\n" " /*highaddr*/ BUS_SPACE_MAXADDR, /*filter*/ NULL, /*filterarg*/ " "NULL,\n" " /*maxsize*/ BUS_SPACE_MAXSIZE_24BIT,\n" " /*nsegments*/ BUS_SPACE_UNRESTRICTED,\n" " /*maxsegsz*/ BUS_SPACE_MAXSIZE_24BIT, /*flags*/ 0,\n" " &sc->parent_tag);\n" " if(error)\n" " goto bad;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:988 #, no-wrap msgid "" " /* many things get inherited from the parent tag\n" " * sc->data is supposed to point to the structure with the shared data,\n" " * for example for a ring buffer it could be:\n" " * struct {\n" " * u_short rd_pos;\n" " * u_short wr_pos;\n" " * char bf[XXX_RING_BUFFER_SIZE]\n" " * } *data;\n" " */\n" " error=bus_dma_tag_create(sc->parent_tag, 1,\n" " 0, BUS_SPACE_MAXADDR, 0, /*filter*/ NULL, /*filterarg*/ NULL,\n" " /*maxsize*/ sizeof(* sc->data), /*nsegments*/ 1,\n" " /*maxsegsz*/ sizeof(* sc->data), /*flags*/ 0,\n" " &sc->data_tag);\n" " if(error)\n" " goto bad;\n" msgstr "" " /* many things get inherited from the parent tag\n" " * sc->data is supposed to point to the structure with the shared " "data,\n" " * for example for a ring buffer it could be:\n" " * struct {\n" " * u_short rd_pos;\n" " * u_short wr_pos;\n" " * char bf[XXX_RING_BUFFER_SIZE]\n" " * } *data;\n" " */\n" " error=bus_dma_tag_create(sc->parent_tag, 1,\n" " 0, BUS_SPACE_MAXADDR, 0, /*filter*/ NULL, /*filterarg*/ NULL,\n" " /*maxsize*/ sizeof(* sc->data), /*nsegments*/ 1,\n" " /*maxsegsz*/ sizeof(* sc->data), /*flags*/ 0,\n" " &sc->data_tag);\n" " if(error)\n" " goto bad;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:993 #, no-wrap msgid "" " error = bus_dmamem_alloc(sc->data_tag, &sc->data, /* flags*/ 0,\n" " &sc->data_map);\n" " if(error)\n" " goto bad;\n" msgstr "" " error = bus_dmamem_alloc(sc->data_tag, &sc->data, /* flags*/ 0,\n" " &sc->data_map);\n" " if(error)\n" " goto bad;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1009 #, no-wrap msgid "" " /* xxx_alloc_callback() just saves the physical address at\n" " * the pointer passed as its argument, in this case &sc->data_p.\n" " * See details in the section on bus memory mapping.\n" " * It can be implemented like:\n" " *\n" " * static void\n" " * xxx_alloc_callback(void *arg, bus_dma_segment_t *seg,\n" " * int nseg, int error)\n" " * {\n" " * *(bus_addr_t *)arg = seg[0].ds_addr;\n" " * }\n" " */\n" " bus_dmamap_load(sc->data_tag, sc->data_map, (void *)sc->data,\n" " sizeof (* sc->data), xxx_alloc_callback, (void *) &sc->data_p,\n" " /*flags*/0);\n" msgstr "" " /* xxx_alloc_callback() just saves the physical address at\n" " * the pointer passed as its argument, in this case &sc->data_p.\n" " * See details in the section on bus memory mapping.\n" " * It can be implemented like:\n" " *\n" " * static void\n" " * xxx_alloc_callback(void *arg, bus_dma_segment_t *seg,\n" " * int nseg, int error)\n" " * {\n" " * *(bus_addr_t *)arg = seg[0].ds_addr;\n" " * }\n" " */\n" " bus_dmamap_load(sc->data_tag, sc->data_map, (void *)sc->data,\n" " sizeof (* sc->data), xxx_alloc_callback, (void *) &sc->data_p," "\n" " /*flags*/0);\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1012 msgid "" "After all the necessary resources are allocated the device should be " "initialized. The initialization may include testing that all the expected " "features are functional." msgstr "" "После выделения всех необходимых ресурсов устройство должно быть " "инициализировано. Инициализация может включать проверку работоспособности " "всех ожидаемых функций." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1017 #, no-wrap msgid "" " if(xxx_initialize(sc) < 0)\n" " goto bad;\n" msgstr "" " if(xxx_initialize(sc) < 0)\n" " goto bad;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1020 msgid "" "The bus subsystem will automatically print on the console the device " "description set by probe. But if the driver wants to print some extra " "information about the device it may do so, for example:" msgstr "" "Подсистема шины автоматически выводит на консоль описание устройства, " "установленное при проверке. Однако, если драйвер хочет вывести " "дополнительную информацию об устройстве, он может это сделать, например:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1025 #, no-wrap msgid " device_printf(dev, \"has on-card FIFO buffer of %d bytes\\n\", sc->fifosize);\n" msgstr "" " device_printf(dev, \"has on-card FIFO buffer of %d bytes\\n" "\", sc->fifosize);\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1028 msgid "" "If the initialization routine experiences any problems then printing " "messages about them before returning error is also recommended." msgstr "" "Если в процессе выполнения инициализации возникают какие-либо проблемы, " "рекомендуется выводить сообщения об этих проблемах перед возвратом ошибки." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1030 msgid "" "The final step of the attach routine is attaching the device to its " "functional subsystem in the kernel. The exact way to do it depends on the " "type of the driver: a character device, a block device, a network device, a " "CAM SCSI bus device and so on." msgstr "" "Последним шагом процедуры присоединения является подключение устройства к " "его функциональной подсистеме в ядре. Конкретный способ зависит от типа " "драйвера: символьное устройство, блочное устройство, сетевое устройство, " "устройство шины CAM SCSI и так далее." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1032 msgid "If all went well then return success." msgstr "Если всё прошло успешно, вернуть успех." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1038 #, no-wrap msgid "" " error = xxx_attach_subsystem(sc);\n" " if(error)\n" " goto bad;\n" msgstr "" " error = xxx_attach_subsystem(sc);\n" " if(error)\n" " goto bad;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1040 #, no-wrap msgid " return 0;\n" msgstr " return 0;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1043 msgid "" "Finally, handle the troublesome situations. All the resources should be " "deallocated before returning an error. We make use of the fact that before " "the structure softc is passed to us it gets zeroed out, so we can find out " "if some resource was allocated: then its descriptor is non-zero." msgstr "" "Наконец, обработаем проблемные ситуации. Все ресурсы должны быть освобождены " "перед возвратом ошибки. Мы используем тот факт, что перед передачей " "структуры `softc` она обнуляется, поэтому мы можем определить, был ли " "выделен какой-либо ресурс: если его дескриптор ненулевой." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1053 #, no-wrap msgid "" " xxx_free_resources(sc);\n" " if(error)\n" " return error;\n" " else /* exact error is unknown */\n" " return ENXIO;\n" msgstr "" " xxx_free_resources(sc);\n" " if(error)\n" " return error;\n" " else /* exact error is unknown */\n" " return ENXIO;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1056 msgid "That would be all for the attach routine." msgstr "Вот и всё для процедуры присоединения." #. type: Title == #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1058 #, no-wrap msgid "xxx_isa_detach" msgstr "xxx_isa_detach" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1061 msgid "" "If this function is present in the driver and the driver is compiled as a " "loadable module then the driver gets the ability to be unloaded. This is an " "important feature if the hardware supports hot plug. But the ISA bus does " "not support hot plug, so this feature is not particularly important for the " "ISA devices. The ability to unload a driver may be useful when debugging it, " "but in many cases installation of the new version of the driver would be " "required only after the old version somehow wedges the system and a reboot " "will be needed anyway, so the efforts spent on writing the detach routine " "may not be worth it. Another argument that unloading would allow upgrading " "the drivers on a production machine seems to be mostly theoretical. " "Installing a new version of a driver is a dangerous operation which should " "never be performed on a production machine (and which is not permitted when " "the system is running in secure mode). Still, the detach routine may be " "provided for the sake of completeness." msgstr "" "Если эта функция присутствует в драйвере и драйвер скомпилирован как " "загружаемый модуль, то драйвер получает возможность быть выгруженным. Это " "важная функция, если оборудование поддерживает горячее подключение. Однако " "шина ISA не поддерживает горячее подключение, поэтому эта функция не " "особенно важна для устройств ISA. Возможность выгрузки драйвера может быть " "полезна при его отладке, но во многих случаях установка новой версии " "драйвера потребуется только после того, как старая версия каким-то образом " "заблокирует систему и перезагрузка все равно будет необходима, поэтому " "усилия, затраченные на написание процедуры отсоединения, могут не окупиться. " "Другой аргумент, что выгрузка позволит обновлять драйверы на рабочей машине, " "кажется в основном теоретическим. Установка новой версии драйвера — это " "опасная операция, которую никогда не следует выполнять на рабочей машине (и " "которая не разрешена, когда система работает в безопасном режиме). Тем не " "менее, процедура отсоединения может быть предоставлена для полноты." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1063 msgid "" "The detach routine returns 0 if the driver was successfully detached or the " "error code otherwise." msgstr "" "Процедура отсоединения возвращает 0, если драйвер был успешно отсоединён, " "или код ошибки в противном случае." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1065 msgid "" "The logic of detach is a mirror of the attach. The first thing to do is to " "detach the driver from its kernel subsystem. If the device is currently open " "then the driver has two choices: refuse to be detached or forcibly close and " "proceed with detach. The choice used depends on the ability of the " "particular kernel subsystem to do a forced close and on the preferences of " "the driver's author. Generally the forced close seems to be the preferred " "alternative." msgstr "" "Логика отсоединения является зеркальной по отношению к присоединению. " "Первое, что нужно сделать, — это отсоединить драйвер от его подсистемы ядра. " "Если устройство в настоящее время открыто, у драйвера есть два варианта: " "отказаться от отсоединения или принудительно закрыть устройство и продолжить " "отсоединение. Выбор зависит от возможности конкретной подсистемы ядра " "выполнить принудительное закрытие и от предпочтений автора драйвера. Как " "правило, принудительное закрытие кажется предпочтительным вариантом." #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1070 #, no-wrap msgid "" " struct xxx_softc *sc = device_get_softc(dev);\n" " int error;\n" msgstr "" " struct xxx_softc *sc = device_get_softc(dev);\n" " int error;\n" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1074 #, no-wrap msgid "" " error = xxx_detach_subsystem(sc);\n" " if(error)\n" " return error;\n" msgstr "" " error = xxx_detach_subsystem(sc);\n" " if(error)\n" " return error;\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1077 msgid "" "Next the driver may want to reset the hardware to some consistent state. " "That includes stopping any ongoing transfers, disabling the DMA channels and " "interrupts to avoid memory corruption by the device. For most of the drivers " "this is exactly what the shutdown routine does, so if it is included in the " "driver we can just call it." msgstr "" "Далее драйвер может сбросить аппаратное обеспечение в согласованное " "состояние. Это включает остановку любых текущих передач, отключение каналов " "DMA и прерываний, чтобы избежать повреждения памяти устройством. Для " "большинства драйверов это именно то, что делает процедура выключения, " "поэтому, если она присутствует в драйвере, мы можем просто вызвать её." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1079 msgid "`xxx_isa_shutdown(dev);`" msgstr "`xxx_isa_shutdown(dev);`" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1081 msgid "And finally release all the resources and return success." msgstr "И наконец освободить все ресурсы и вернуть успех." #. type: Title == #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1089 #, no-wrap msgid "xxx_isa_shutdown" msgstr "xxx_isa_shutdown" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1092 msgid "" "This routine is called when the system is about to be shut down. It is " "expected to bring the hardware to some consistent state. For most of the ISA " "devices no special action is required, so the function is not really " "necessary because the device will be re-initialized on reboot anyway. But " "some devices have to be shut down with a special procedure, to make sure " "that they will be properly detected after soft reboot (this is especially " "true for many devices with proprietary identification protocols). In any " "case disabling DMA and interrupts in the device registers and stopping any " "ongoing transfers is a good idea. The exact action depends on the hardware, " "so we do not consider it here in any detail." msgstr "" "Эта процедура вызывается, когда система собирается быть выключена. " "Ожидается, что она приведет оборудование в согласованное состояние. Для " "большинства устройств ISA не требуется никаких специальных действий, поэтому " "функция не является действительно необходимой, так как устройство будет " "переинициализировано при перезагрузке в любом случае. Однако некоторые " "устройства должны быть выключены с помощью специальной процедуры, чтобы " "убедиться, что они будут правильно обнаружены после мягкой перезагрузки (это " "особенно актуально для многих устройств с проприетарными протоколами " "идентификации). В любом случае отключение DMA и прерываний в регистрах " "устройства и остановка любых текущих передач — это хорошая идея. Точные " "действия зависят от оборудования, поэтому мы не рассматриваем их здесь " "подробно." #. type: Title == #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1094 #, no-wrap msgid "xxx_intr" msgstr "xxx_intr" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1097 msgid "" "The interrupt handler is called when an interrupt is received which may be " "from this particular device. The ISA bus does not support interrupt sharing " "(except in some special cases) so in practice if the interrupt handler is " "called then the interrupt almost for sure came from its device. Still, the " "interrupt handler must poll the device registers and make sure that the " "interrupt was generated by its device. If not it should just return." msgstr "" "Обработчик прерывания вызывается при получении прерывания, которое может " "быть от данного конкретного устройства. Шина ISA не поддерживает разделение " "прерываний (за исключением некоторых специальных случаев), поэтому на " "практике, если вызывается обработчик прерывания, то прерывание почти " "наверняка поступило от его устройства. Тем не менее, обработчик прерывания " "должен опросить регистры устройства и убедиться, что прерывание было " "сгенерировано его устройством. Если нет, он должен просто вернуть управление." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1099 msgid "" "The old convention for the ISA drivers was getting the device unit number as " "an argument. This is obsolete, and the new drivers receive whatever argument " "was specified for them in the attach routine when calling " "`bus_setup_intr()`. By the new convention it should be the pointer to the " "structure softc. So the interrupt handler commonly starts as:" msgstr "" "Старая практика для драйверов ISA заключалась в получении номера устройства " "в качестве аргумента. Это устарело, и новые драйверы получают любой " "аргумент, указанный для них в процедуре присоединения при вызове " "`bus_setup_intr()`. Согласно новой практике, это должен быть указатель на " "структуру softc. Таким образом, обработчик прерываний обычно начинается так:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1106 #, no-wrap msgid "" " static void\n" " xxx_intr(struct xxx_softc *sc)\n" " {\n" msgstr "" " static void\n" " xxx_intr(struct xxx_softc *sc)\n" " {\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1109 msgid "" "It runs at the interrupt priority level specified by the interrupt type " "parameter of `bus_setup_intr()`. That means that all the other interrupts of " "the same type as well as all the software interrupts are disabled." msgstr "" "Он выполняется на уровне приоритета прерывания, указанном параметром типа " "прерывания в `bus_setup_intr()`. Это означает, что все остальные прерывания " "того же типа, а также все программные прерывания, отключены." #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1111 msgid "To avoid races it is commonly written as a loop:" msgstr "Во избежание гонок это обычно записывается в виде цикла:" #. type: delimited block . 4 #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1119 #, no-wrap msgid "" " while(xxx_interrupt_pending(sc)) {\n" " xxx_process_interrupt(sc);\n" " xxx_acknowledge_interrupt(sc);\n" " }\n" msgstr "" " while(xxx_interrupt_pending(sc)) {\n" " xxx_process_interrupt(sc);\n" " xxx_acknowledge_interrupt(sc);\n" " }\n" #. type: Plain text #: documentation/content/en/books/arch-handbook/isa/_index.adoc:1121 msgid "" "The interrupt handler has to acknowledge interrupt to the device only but " "not to the interrupt controller, the system takes care of the latter." msgstr "" "Обработчик прерывания должен подтвердить прерывание только устройству, но не " "контроллеру прерываний, система позаботится о последнем."