Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-doc
Path: blob/main/documentation/content/ru/books/arch-handbook/isa/_index.po
18099 views
# SOME DESCRIPTIVE TITLE
# Copyright (C) YEAR The FreeBSD Project
# This file is distributed under the same license as the FreeBSD Documentation package.
# Vladlen Popolitov <[email protected]>, 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-04-05 04:45+0000\n"
"Last-Translator: Vladlen Popolitov <[email protected]>\n"
"Language-Team: Russian <https://translate-dev.freebsd.org/projects/"
"documentation/booksarch-handbookisa_index/ru/>\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 <sys/module.h>\n"
"#include <sys/bus.h>\n"
"#include <machine/bus.h>\n"
"#include <machine/resource.h>\n"
"#include <sys/rman.h>\n"
msgstr ""
"#include <sys/module.h>\n"
"#include <sys/bus.h>\n"
"#include <machine/bus.h>\n"
"#include <machine/resource.h>\n"
"#include <sys/rman.h>\n"

#. type: delimited block . 4
#: documentation/content/en/books/arch-handbook/isa/_index.adoc:71
#, no-wrap
msgid ""
"#include <isa/isavar.h>\n"
"#include <isa/pnpvar.h>\n"
msgstr ""
"#include <isa/isavar.h>\n"
"#include <isa/pnpvar.h>\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 ""
"Обработчик прерывания должен подтвердить прерывание только устройству, но не "
"контроллеру прерываний, система позаботится о последнем."