Команда SC_EXEC_SCSI_CMD

Вот мы и подошли к рассмотрению самой используемой команды интерфейса ASPI. Именно с помощью команды SC_EXEC_SCSI_CMD происходит обмен данными между программой и устройством. Для ее использования применяется соответствующая структура, определяемая как SRB_ExecSCSICmd. Первые пять полей у нее такие же, как и у рассмотренных выше, а также добавлены и новые.

Структура имеет самый сложный вид, но не стоит этого пугаться. В реальной программе используются немногие из приведенных полей. Это зависит в первую очередь от того, какие цели ставит перед собой программист. Можно безболезненно исключить обработку состояний оборудования и контроллера, а можно упростить обработку ошибок до самых общих. Хорошим решением будет создание своего класса с поддержкой всех возможностей интерфейса ASPI и последующее повторное использование его в различных проектах и с различными допустимыми типами оборудования. Ну а теперь вернемся к нашей структуре и попробуем более подробно разобраться в ее параметрах.

  • SRB_Cmd

    Это поле должно содержать код команды SC_EXEC_SCSI_CMD.

  • SRB_Status

    После выполнения команды здесь будет храниться результат вызова функции SendASPI32Command. Ниже приведены возможные значения:

    • SS_PENDING — происходит попытка выполнить команду.
    • SSJCOMP — операция успешно завершена.
    • SS_ABORTED — команда SCSI была грубо прервана.
    • SS_ABORT_FAIL — не удалось фубо завершить команду.
    • SS_ERR — команда SCSI была завершена с ошибкой.
    • SS_INVALID_SRB — одно или большее число полей в структуре SRB_ExecSCSICmd были установлены неправильно.
    • SS_INVALID_PATH_ID — недопустимые значения идентификатора и логического номера устройства.
    • SS_BUFFER_TO_BIG — драйвер ASPI не может обработать пакет данных из-за большого размера.
    • SS_BUFFER_ALING — драйвер ASPI не может произвести выравнивание буфера данных. Используйте команду SC_HA_INQUIRY для установки правильного значения.
    • SS_SECURITY_VIOLATION — программа не требует установки привилегий защиты для выполнения команды.
  • SRB_HaId

    Сюда нужно поместить номер выбранного контроллера. Нумерация начинается с 0. Максимально возможное значение номера контроллера равно 7.

  • SRB_Flags

    В данное поле помещается флаг выполняемой операции. На данный момент определены пять возможных операций.

    • SRB_DIR_IN — передача данных от устройства в программу. Не может использоваться совместно с флагом SRB_DIR_OUT.
    • SRB_DIR_OUT — передача данных из программы на устройство. Не может использоваться совместно с флагом SRB_DIR_IN.
    • SRB_EVENT_NOTIFY — установка этого флажка разрешает получать уведомления о происходящих событиях интерфейса ASPI для синхронного режима. Не может использоваться совместно с флагом SRB_POSTING.
    • SRB_POSTING — установка этого флажка разрешает получать уведомления о происходящих событиях интерфейса ASPI для асинхронного режима. Не может использоваться вместе с флагом SRB_EVENT_NOTIFY.
    • SRB_ENABLE_RESIDUAL_COUNT — допускает использование остаточного индекса при передаче данных. Этот флаг имеет силу только в случае, если контроллер поддерживает передачу данных с учетом остаточного индекса. Используйте описанную ранее команду SC_HA_INQUIRY для определения этого. Если контроллер работает в таком режиме, при каждой передаче пакета данных поле SRB_BufLen будет модифицировано таким образом, чтобы показать остаток от переданных данных.
  • SRB_Hdr_Rsvd

    Зарезервированное поле должно равняться 0.

  • SRB_Target

    Сюда помещается идентификатор устройства. Получить это значение можно, используя команду SC_HA_INQUIRY. Нумерация начинается с 0.

  • SRB_Lun

    Логический адрес устройства.

  • SRB_BufLen

    В это поле заносится количество байтов, которое будет передано. Если используются команды тестирования, перемотки и им подобные, это поле должно быть установлено в 0. Если присутствует поддержка остаточного индекса и установлен соответствующий флаг в поле SRB_Flags, то тогда данное поле после выполнения команды возвратит остаточное число байтов (обычно 0).

  • SRB_BufPointer

    В это поле заносится указатель на буфер данных. Если передача данных не планируется, следует записать сюда нулевое значение.

  • SRB_SenseLen

    Сюда следует занести количество байтов, используемых для отчета о выполнении команды. В Windows NT (Windows 2000/XP) не удается использовать более чем 18 байтов. Для Windows 98/МЕ офаничение максимального размера отсутствует.

  • SRB_CDBLen

    В это поле заносится размер команды SCSI в байтах. Типичными значениями являются 6-, 10-, 12-байтовые команды. Следует следить за тем, чтобы заносимое сюда значение всегда было больше или равно размеру команды. Иначе будет возвращена ошибка.

  • SRB_HaStat

    После удачного завершения команды в это поле будет помешено определенное значение о состоянии контроллера. Вот эти значения.

    • HASTAT_OK — контроллер ошибок не обнаружил.
    • HASTAT_TIMEOUT — время, отпущенное модулю на выполнение операции, закончилось.
    • HASTAT_COMMAND_TIMEOUT — время ожидания обработки команды истекло.
    • HASTAT_SEL_TO — время обслуживания выбранного устройства вышло.
    • HASTAT_MESSAGE_REJECT — при обработке команды контроллером прошло неверное сообщение.
    • HASTAT_BUS_RESET — был обнаружен общий сброс шины.
    • HASTAT_PARITY_ERROR — была обнаружена ошибка четности.
    • HASTAT_REQUEST_SENSE_FAILED — контроллер не сумел правильно обработать данные отчета, полученные от целевого устройства.
    • HASTAT_DO_DU — произошло переполнение данных.
    • HASTAT_BUS_FREE — неожидаемая очистка шины.
    • HASTAT_PHASE_ERR — отказ механизма последовательного распределения идентификаторов на шине.

    Как видите, многие ошибки, возвращаемые контроллером, настолько специфичны, что не имеет смысла в каждой программе учитывать их все.

  • SRB_TargetStat

    После успешного завершения команды SCSI в это поле будет занесено значение состояния, возвращаемого текущим устройством. Не следует обрабатывать это значение, если поле SRB_status возвратит SS_COMP. Ниже приведены общие случаи возвращаемого значения.

    • STATUS_GOOD — данные о состоянии устройства отсутствуют.
    • STATUS_CHKCOND — данные о состоянии находятся в поле SenseArea (не обязательно).
    • STATUS_BUSY — указанный идентификатор (логический адрес) устройства занят.
    • STATUS_RESCONF — возник конфликт резервирования адресов.
  • SRB_PostProc

    Если установлен флажок SRB_POSTING, в это поле необходимо занести функцию обратного вызова для обработки уведомляющих сообщений интерфейса ASPI. Если установлен флаг SRB_EVENT_NOTIFY, сюда помещается дескриптор пользовательского события для обработки сообщений ASPI. Подробнее обо всех способах обработки событий интерфейса ASPI для корректной работы с оборудованием будет рассказано далее, а сейчас продолжим описание оставшихся полей структуры SRB_EXEC_SCSI_SMD.

  • CDBByte

    В это поле нужно записать код команды SCSI в соответствии с битовой таблицей выбранной команды. В поле SRB_CDBLen указывается размер команды в байтах.

  • SenseArea

    После успешного завершения команды в это поле будет занесена отчетная информация по выполненной команде. Каждая команда имеет набор значений, помещаемых в это поле. По мере изучения команд будем приводить отчетные данные для каждой команды. Максимальная длина поля указывается в значении SRB_SenseLen. Обратите внимание, что может быть возвра¬щено меньшее количество байтов отчета по сравнению с ожидаемым. Кон¬станта SENSE_LEN определена в файле Wnaspi32.h и по умолчанию равна 14 (байт).

Возвращаемым значением функции SendASPI32Command при выполнении команды SC_EXEC_SCSI_SMD является SS_PENDING. Приведем пример использования команды SC_EXEC_SCSI_CMD.

Листинг 2.6. Реализация структуры SRB_ExecSCSICmd на Visual С++

На данном примере показаны общие принципы обработки команды передачи данных между программой и устройством посредством интерфейса ASPI. Теперь приведем пример использования команды SC_EXEC_SCSI_CMD ДЛЯ Visual Basic.

Листинг 2.7.Реализация структуры SRB_ExecSCSICmd на Visual Basic

На этом небольшом примере показан способ обработки команды SCSI посредством Visual Basic. Однако этот пример не является единственным решением задачи. Для обработки возвращаемого значения функции SendASPI32Command можно применить еще более простой код, не используя функции Windows CreateEvent, ResetEvent, CloseHandle И waitForsingieObject. На этом описание команды SC_EXEC_SCSI_CMD можно считать завершенным и переходим к следующей.

 

 

2021-04-01

Google сообщил о запуске проекта Dunant

Проект Dunant, начатый в 2018 году, был запущен в эксплуатацию. Трансатлантический интернет-кабель соединяет США и континентальную Европу. Общая протяженность...

подробнее
2020-04-06

Новшества в обновленной Windows 10

Корпорация Microsoft завершила разработку обновления, в котором добавлено множество функций. Обновление содержит как доработку уже имеющихся систем, так...

подробнее

 

Все новости...

 

Научно-Техническое Объединение

Тел.: +7(4752) 55-95-86

E-mail:e-mail