Alter.Org.UA
 << Back Home EN en   Donate Donate

NT SCSI Pass Through Interface (SPTI) behavior

SPTI - замечательная технология для непосредственного обращения к SCSI-совместимым устройствам для NT-подобный систем. SPTI обеспечивает единообразный интерфейс для работы со следующими типами устройств (в действительности список может оказаться более широким)

  • SCSI устройства, подключенные через SCSI-контроллер
  • устройства, использующие SCSI'шный набор команд, подключенные не-SCSI-контроллеры
    • все современные IDE/ATAPI CD/DVD-приводы и большинство старых.
    • LPT, USB и FireWire HDD и CD/DVD-приводы.
  • устройства, для которых эмулируется SCSI-интерфейс на уровне драйверов - IDE/ATA HDD

Через SPTI можно передать любую SCSI команду с любыми параметрами и получить полную информацию об ошибке (SenseInfo) от устройства. Вот краткий список преимуществ:

  • Работает во всей линейке NT-подобных систем.
  • Не требует никаких дополнительных драйверов (таких как многочисленные реализации ASPI с их не менее многочисленными глюками).
  • Доступно в Win32 через DeviceIoControl() с handle'ом физического устройства (см. MSDN, CreateFileEx(), \\.\<DriveLetter>: и т.п.)

Всем хорош SPTI, но есть ряд недокументированых граблей, на которые я имел честь наступить. Именно о них дальнейший рассказ.

Подробно о SCSI командах для CD/DVD приводов можно найти в спецификациях MMC.

Transfer length limitations

Проблема: IOCTL_SCSI_PASS_THROUGH_DIRECT возвращает ошибку при попытке передать 64k данных устройству из Win32 через DeviceIoControl(). Вскрытие показало, что Port driver возвращает STATUS_INVALID_PARAMETER. MS DDK Help говорит, что такая ошибка возникает при неправильном размере буфера. В Knowledge base (PSS ID Number: Q126369) сказано, что нужно использовать IOCTL_SCSI_GET_CAPABILITIES для того, чтобы узнать MaximumTransferLength и MaximumPhysicalPages. Согласно докам пользовательский буфер копируется во временный system-allocated буфер (METHOD_BUFFERED) а после завершения операции данные копируются обратно из временного буфера в пользовательский.

Я проверил.. MaximumTransferLength = 64k, так что никаких проблем быть не должно. MaximumPhysicalPages = 16, типа тоже no problem. Так где же, спрашивается, грабли ?

Ответ: пользовательский буфер передался вниз как был. Port driver сравнил его размер с MaximumTransferLength. Пока все хорошо. Подсчитал, сколько страниц (полных и неполных) перекрывает пользовательский буфер. Т.к. Win32 выделяет память блоками, выровнеными на 8 байт, 64k буфер как правило будет перекрывать 17 страниц (1ю и последнюю - частично). Вот и грабельки.

Solution: Выровнять буфер на размер страницы (PAGE_SIZE). В kernel-mode это делает memory maneger. А в Win32 придется делать самостоятельно. Либо выделять бОльший буфер и использовать из него выровненый блок, либо делать собственный heap manager специально для таких случаев.

Auto-sense (device error reporting) issues

Мелкие грабли: при использовании SenseInfoOffset нельзя устанавливать SenseInfoLength больше чем sizeof(SENSE_DATA) - 24 байта. Иначе SenseInfo не будет возвращено. Это связано с тем, что при возникновении ошибки Port-driver самостоятельно посылает устройству команду REQUEST_SENSE и передает ей как раз SenseInfoLength. Поскольку устройство не может отдать в ответ больше 24 байт, возникает ошибка.

VMWare compatibility

Проблемка: при отображении физического ATAPI CD-recorder'а на IDE шину виртуальной машины не работает CD-пишущий софт, работающий через SPTI. Оказалось, что VMWare блокирует команды установки режима записи (MODE_SELECT, MODE_PAGE_WRITE_PARAMS - 0x05), а также сами команды записи. Дальнейшее исследование показало, что проблема касается не только SPTI, и писать на устройство нельзя вообще.

Solution: настроить VMWare так, чтобы физический ATAPI CD-recorder отображался в виртуальную машину как SCSI устройство.

<< Back Автор: Alter (Александр А. Телятников) Сервер: Apache+PHP под FBSD © 2002-2024