4.3. Запросы к драйверам устройств

 

      Каждый  запрос  к  драйверу  устройства  представляет собой

 определенную последовательность байтов,  содержащую информацию о

 команде,  которую   драйвер  должен  выполнить.   Адрес  запроса

 передается  программе  стратегии  драйвера  в  регистрах  ES:BX.

 Запрос  состоит  из  заголовка  (постоянной  части) и переменной

 части,  содержащей данные,  относяиеся к  данному типу запросов.

 Заголовок имеет следующее строение.

 

 Смещение  Длина  Содержание         Комментарий

 ─────────────────┬────┬──────────────────────────────────────────

  +0         1    │Len │ Длина запроса (включая заголовок)

                  ├────┤

  +1         1    │Unit│ Номер устройства (только для блочных

                  ├────┤ устройств)

  +2         1    │Cmd │ Код команды (00h-18h)

                  ├────┴───┐

  +3         2    │ Status │ Слово состояния устройства

                  ├────────┴─────────┐ (заполняется драйвером)

  +5         8    │(зарезервировано) │

                  └──────────────────┘

  +0Dh       Длина заголовка. Здесь начинается переменная часть

             запроса.

 

      Слово  состояния  устройства  заполняется  драйвером  перед

 возвратом  управления  ДОС.  При  нормальном  завершении драйвер

 должен установить  бит "выполнено" и выдать  команду RETF. Слово

 состояния имеет следующую структуру.

 

  1 1 1 1 1 1

  5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0

 ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐

 │ │  резерв │ │ │  код ошибки  

 └┬┴─┴─┴─┴─┴─┴┬┴┬┴─┴─┴─┴┬┴─┴─┴─┴─┘ Биты:                  Маска:

             │ │      

             │ │       └─────────>0-7:код ошибки       S & 00FFh

             │ │                      устройства

             │ └─────────────────>8:1=выполнено        S & 0100h

                                   (устанавливается всегда)

             └───────────────────>9:1=занято (только   S & 0200h

                                    запросы 6 и 0Fh)

  └──────────────────────────────>15:1=произошла ошибка S & 8000h

 

      Бит  "занято" устанавливается  драйвером, если  он не может

 выполнить  требуемую  операцию  из-за  того,  что устройство еще

 выполняет предыдущую  команду. Кроме того,  в некоторых запросах

 он содержит различную информацию, такую как "буфер клавиатуры не

 пуст" или "носитель является сменным".

 

      Бит "ошибка" устанавливается драйвером, если при выполнении

 заданной операции произошла ошибка. В этом случае в младший байт

 слова  состояния следует  занести код  ошибки согласно следующей

 таблице.

 

 Код  Описание                  Код  Описание

 ────────────────────────────────────────────────────────────────

 

  0   Диск защищен от записи     8   Сектор диска не найден

  1   Неизвестное устройство     9   Нет бумаги в принтере

  2   Устройство не готово      Ah   Ошибка записи

  3   Неизвестная команда       Bh   Ошибка чтения

  4   Сбой контрольной суммы    Ch   Общий сбой

      (CRC)                     Dh   (резерв)

  5   Неверная длина запроса    Eh   (резерв)

  6   Ошибка поиска             Fh   Недопустимая смена диска

  7   Неизвестный формат             (ДОС 3.x)

      носителя

 

      Код команды задает тип запроса согласно следующей таблице.

 

 Код Название команды Применим к│ Код Название команды Пpименим к

 ───────────────────────────────┼────────────────────────────────

                                

  0  Инициализация       C/B      Ah Состояние вывода      C

     устройства                   Bh Сброс буфера вывода   C

  1  Проверка носителя    B       Ch Вывод управляющей   C/B, I

                                     инфоpмации

  2  Создать BPB          B       Dh Открыть устройство  C/B, R

  3  Ввод управляющей   C/B, I       (3.x)

     информации                   Eh Закрыть устройство  C/B, R

  4  Ввод                C/B         (3.x)

  5  Неразрушающий        C       Fh Проверить сменный     B,R

     ввод без ожидания               носитель (3.x)

  6  Состояние ввода      C     │ 13h Общее управление      I

  7  Сброс буфера ввода   C          устройством (3.2)

  8  Вывод               C/B    │ 17h Получить логическое C/B, L

  9  Вывод с проверкой   C/B         устройство (3.2)

                                │ 18h Задать логическое   C/B, L

                                     устройство (3.2)

  ──────────────────────────────┴────────────────────────────────

 

      Примечание: C = последовательные устройства

                  B = блочные устройства

                  I = должно поддерживать IOCTL

                  R = должно поддерживать буферизацию

                  L = должно поддерживать логические устройства.

 

 См. атрибуты устройств.

 

      Инициализация устройства (код 0)

     ──────────────────────────────────

 

 Смещение Длина Содержимое          Комментарий

 ───────────────┬──────────────────────┬────────────────────────────

  +0       0Dh     Заголовок запроса 

                ├───┬──────────────────┘

  +0Dh      1      │ Выход: число устройств, определемых этим

                ├───┼───┬───┬───┐ драйвером (для блочных устройств)

  +0Eh      4                 │ Выход: конечный адрес

                ├───┼───┼───┼───┤ резидентного кода

  +12h      4                 │ Вход: адрес ASCIIZ-строки из

                └───┴───┴───┴───┘ CONFIG.SYS. Выход: указатель на

                        таблицу адресов BPB устройств (только для

                ┌───┐   блочного драйвера)

  +16h      1      │ Вход: номер дисковода (0=A, 1=B, ...) для

                └───┘ блочного устройства

   17h          Длина запроса (в ДОС 3.x)

 

      По этой команде  драйвер должен инициализировать устройство

 и вернуть  последний  адрес  памяти,  которую  он хочет оставить

 резидентной.  Блочное  устройство  должно  также сообщить  число

 физических   устройств,   которое   он   обслуживает.  Во  время

 инициализации можно использовать фн 01h-0Ch.

 

      Начиная  с ДОС  3.0, структура  запроса расширена.  Двойное

 слово  по  смещению  12h  содержит  адрес  текстовой  строки  из

 CONFIG.SYS, которой драйвер был  загружен (без слова "DEVICE=").

 Драйвер может проанализировать эту строку и обработать указанные

 в ней  параметры.  Кроме  того,  байт  по  смещению 16h содержит

 номер, присвоенный  ДОС этому устройству;  это позволяет вывести

 на  экран сообщение,  извещающее пользователя  о том,  какое имя

 присвоено данному дисководу.

 

      Проверка носителя (код 1)

     ──────────────────────────

 

 Смещение Длина Содержимое          Комментарий

 ───────────────┬──────────────────────┬────────────────────────────

  +0       0Dh     Заголовок запроса 

                ├───┬──────────────────┘

  +0Dh      1      │ Вход: описатель носителя

                ├───┤

  +0Eh      1      │ Выход: ответ драйвера

                ├───┼───┬───┬───┐

  +1Fh      4                 │ Выход: адрес ASCIIZ-строки,

                └───┴───┴───┴───┘ содержащей метку предыдущего

                                  тома

   12h      Длина запроса

 

      ДОС запрашивает, был ли  сменен диск в дисководе, передавая

 драйверу  баит  описания   носителя.  Драйвер  отвечает  байтом,

 который может иметь следующие значения:

 

      FFh = диск сменен

       1  = тот же самый диск

       0  = не знаю

 

      Если диск был сменен и драйвер поддерживает буферизацию, то

 по  смещению  12h  он   должен  занести  длинный  адрес  строки,

 содержащей метку предыдущего диска.

 

      Ввод и вывод (коды 3,4,8,9 и 0Ch)

     ───────────────────────────────────

 

 Смещение Длина Содержимое          Комментарий

 ───────────────┬──────────────────────┬─────────────────────────

  +0       0Dh     Заголовок запроса 

                ├───┬──────────────────┘

  +0Dh      1            Вход: описатель носителя

                ├───┼───┬───┬───┐

  +0Eh      4               │ Вход: адрес буфера обмена

                ├───┼───┼───┴───┘

  +12h      2   │ Count │  Вход: счетчик (байтов или секторов)

                ├───┼───┤

  +14h      2   │ Sector│  Вход: начальный сектор (для блочных

                ├───┼───┼───┬───┐ устройств)

  +16h      4               │ Выход: адрес ASCIIZ-строки,

                └───┴───┴───┴───┘ содержащей метку тома (при

                                  ошибке устройства с кодом 0Fh).

  1Ah       Длина запроса

 

      Команды ввода требуют чтения с устройства Count байтов (для

 последовательных) или  секторов (для блочных  устройств) в буфер

 обмена.

 

      Команды  вывода требуют  записи на  устройство Count байтов

 или секторов из буфера обмена.

 

      Краткое описание команд:

 

 Ввод  (4)                         Чтение данных с устройства

 Вывод (8)                         Запись данных на устройство

 Вывод с проверкой (9)             Запись данных и проверка записи

 Вывод управляющей информации (3)  Вывод данных в управляющий

                                   канал устройства

 Вывод управляющей информации (Ch) Чтение данных из управляющего

                                   канала устройства

 

      Неразрушающий ввод без ожидания (код 5)

      ───────────────────────────────────────

 

 Смещение Длина Содержимое          Комментарий

 ───────────────┬──────────────────────┬─────────────────────────

  +0       0Dh     Заголовок запроса 

                ├───┬──────────────────┘

  +0Dh      1      │ Выход: первый байт в буфере опережающего

                └───┘ ввода

  0Eh       Длина запроса

 

      Применим только к последовательным устройствам (например, к

 клавиатуре).  Драйвер  возвращает  первый  байт,  который  будет

 считан следующим запросом на ввод.

 

      Состояние ввода/вывода (коды 6, 0Ah)

     ─────────────────────────────────────

 

      Запрос  применим  только  к  последовательным устройствам и

 состоит  из   заголовка  запроса.  Драйвер   сообщает  состояние

 устройства через бит "занято"  в слове состояния устройства (бит

 9).

 

      Состояние ввода: бит 9=1, если буфер ввода пуст

                             0, если в буфере ввода есть символы.

 

      Состояние вывода: бит 9=1, если предыдущая операция вывода

                                 еще не завершена

                              0, если устройство готово к выводу.

 

      Сброс буфера ввода/вывода (коды 7, 0Bh)

     ────────────────────────────────────────

 

      Запрос  применим  только  к  последовательным устройствам и

 состоит из заголовка запроса. Драйвер должен очистить свой буфер

 ввода или  вывода. Этот запрос  применяется обычно для  удаления

 введенных клавиш из буфера клавиатуры.

 

      Открыть/закрыть устройство (коды 0Dh, 0Eh)

     ───────────────────────────────────────────

 

      Эти   запросы   применимы   к   устройствам,  подерживающим

 буферизацию, и состоят из заголовка запроса (впервые появились в

 ДОС 3.0). Блочные устройства  обычно используют их для локальной

 буферизации.  Команда "открыть  устройство" подается  при каждом

 открытии  файла, а  "закрыть устройство"  - при  каждом закрытии

 файла. Это  позволяет драйверу отслеживать  моменты, когда смена

 диска  в дисководе  допустима и  организовать собственные буфера

 ввода-вывода файлов для повышения производительности.

 

      Последовательные устройства могут  использовать эти команды

 для приведения  устройства в исходное состояние  или для посылки

 инициализирующих команд на устройство (например, на принтер).

 

      Проверить сменный носитель (код 0Fh)

     ─────────────────────────────────────

 

      Этот   запрос  применим   только  к   блочным  устройствам,

 поддерживающим  буферизацию,  и  состоит  из  заголовка  запроса

 (впервые введен в ДОС 3.0). Драйвер должен сообщить, является ли

 носитель  устройства сменным,  в бите  "занято" слова  состояния

 устройства:

 

     бит 9 = 0 - сменный носитель (например, НГМД)

             1 - несменный носитель (например, жесткий диск).


 

      Общее управление устройством (код 13h)

     ───────────────────────────────────────

 

 Смещение Длина Содержимое          Комментарий

 ───────────────┬──────────────────────┬─────────────────────────

  +0       0Dh     Заголовок запроса 

                ├───┬──────────────────┘

  +0Dh      1      │ Вход: номер функции (всегда равен 8)

                ├───┤

  +0Eh      1      │ Вход: номер подфункции

                ├───┼───┐

  +0Fh      2         │ Вход: значение в регистре SI (см.фн 44h)

                ├───┼───┤

  +11h      2         │ Вход: значение в регистре DI (см.фн 44h)

                ├───┼───┼───┬───┐

  +1Fh      4               │ Вход: длинный адрес пакета

                └───┴───┴───┴───┘ данных IOCTL

  +17h      Длина запроса

 

      Драйверы ДОС 3.2 и ДОС 3.3, обеспечивающие поддержку IOCTL,

 должны   обрабатывать   этот   запрос.   Он   используется   для

 многочисленных  действий, включая  форматирование дисков,  и был

 разработан для стандартизации интерфейса  с дисками разных типов

 с помощью  драйвера  DRIVER.SYS.  Полное  описание  параметров и

 пакетов данных для этого запроса см. фн 44h, подфн 0Dh.

 

      Получить/задать логическое устройство (коды 17h, 18h)

     ──────────────────────────────────────────────────────

 

 Смещение Длина Содержимое          Комментарий

 ───────────────┬──────────────────────┬────────────────────────────

  +0       0Dh     Заголовок запроса 

                ├───┬──────────────────┘

  +0Dh      1      │ Вход: код устройства;

                ├───┤ Выход: номер последнего диска

  +0Eh      1      │ Вход: код команды

                ├───┼───┐

  +0Fh      2         │ Статус (никто не знает, что это такое!)

                ├───┼───┼───┬───┐

  +11h      4               │ (резерв)

                └───┴───┴───┴───┘

  +15h

 

      Драйверы ДОС 3.2 и  ДОС 3.3, обеспечивающие поддержку IOCTL

 и логических  устройств,  должны  обрабатывать  эти запросы. Они

 предназначены  для  поддержания   "фантомных"  или  "логических"

 дисководов,   которые  устанавливаются   при  загрузке  драйвера

 DRIVER.SYS.

 

      Запрос  с  кодом  18h  ("Получить  логическое  устройство")

 требует, чтобы драйвер  поместил  в  байт  по смещению 0Dh номер

 логического диска, который использовался последним (например, A:

 или  B: в  ПЭВМ с одним НГМД);  при этом  1=A, 2=B  и т. д. Если

 драйвер  обслуживает только  одно логическое  устройство, то  он

 должен вернуть нуль.


 

      Запрос  с   кодом  19h  ("Задать   логическое  устройство")

 сообщает   драйверу,  на   какой  логический   диск  он   должен

 переключиться.  Драйвер  должен  вернуть  номер  этого  диска по

 описанным выше правилам (0, 1, 2, ...).

 

      См. также: фн 44h, подфн 0Dh-0Fh.

 

 

 

Вы находитесь в разделе: 
Также вам будет интересно:

Добавить коментарий