Как я могу ограничить количество блоков, записываемых командой Write_10?

У меня есть продукт, который представляет собой флэш-накопитель USB на базе микроконтроллера NXP LPC18xx. Я использую библиотеку, предоставленную производителем (LPCOpen), которая обрабатывает USB MSC и SD-карту (где я храню данные).

Вот проблема: Внутренне LPC18xx имеет 64-килобайтный (ограниченный аппаратно) буфер, используемый для кэширования операций чтения/записи, что означает, что он может кэшировать только до 128 блоков (512 Б) памяти. Команда SCSI Write-10 имеет поле total-blocks, которое может содержать до 256 блоков (128 КБ). При первоначальном тестировании продукта в Windows 7 он никогда не записывает более 128 блоков за раз, но при тестировании в Linux он иногда записывает более 128 блоков, что приводит к сбою микроконтроллера.

Есть ли способ сказать хост-ОС не запрашивать более 128 блоков? Я вижу ссылки [1] на команду Read-Block-Limit (05h), но, похоже, она широко не поддерживается. Кроме того, какую смысловую клавишу я должен вернуть в команду Write-10, чтобы сообщить Linux, что запись слишком велика? Я также вижу ссылки на страницу ограничения блока VPD в некоторых спецификациях устройств, но не могу найти много документации о том, как это реализовано.

[1]https://en.wikipedia.org/wiki/SCSI_command


person Jotux    schedule 26.10.2015    source источник


Ответы (1)


Позвольте мне заранее предупредить, что это то, что вы ДОЛЖНЫ делать, но ничего из этого может не сработать. Беглый поиск драйвера SCSI для Linux не дал мне того, что я хотел увидеть. Так что я совсем не уверен, что «правильные действия» принесут вам желаемые результаты.

Следуя правилам, вы должны сделать две вещи: внедрить VPD с ограничениями на блокировку и обрабатывать слишком большие объемы передаваемых данных в режимах ЗАПИСЬ И ЧТЕНИЕ.

Во-первых, внедрите страницу Block Limits VPD, которую вы можете найти в последних версиях SBC-3, гуляющих по Интернету (например, эта: http://www.13thmonkey.org/documentation/SCSI/sbc3r25)..pdf). Наверное, стоит зайти на сайт t10.org, зарегистрироваться, а потом скачать последнюю ревизию (http://www.t10.org/cgi-bin/ac.pl?t=f&f=sbc3r36.pdf).

На странице Block Limits VPD есть поле максимальной длины передачи, которое определяет максимальное количество блоков, которые могут быть переданы всеми командами READ и WRITE, а также любыми другими операциями чтения или записи данных. Конечно, недостатком реализации этой страницы является то, что вы должны убедиться, что все остальные поля, которые вы возвращаете, верны!

Во-вторых, при обработке READ и WRITE, если длина передачи команды превышает ваш максимум, ответьте клавишей ILLEGAL REQUEST и установите дополнительный смысловой код в INVALID FIELD IN CDB. На это поведение указывает таблица в разделе, описывающем Block Limits VPD, но только в поздних версиях SBC-3 (я смотрю на 35h).

Вы можете просто начать с возврата INVALID FIELD IN CDB, так как это самый простой способ действий. Посмотрите, достаточно ли этого?

person Mike Andrews    schedule 27.10.2015
comment
Поэтому я некоторое время копался в Linux и нашел функцию sd_read_block_limits, которая похоже вызывается при монтировании устройств scsi. Я добавил расширенный запрос, страницу поддерживаемой диагностики и страницу ограничения блокировки vpd, но когда я монтирую/читаю/пишу на свой диск, я не могу заставить свою Linux-машину выполнить расширенный запрос и попытаться прочитать vpd страница. Возврат INVALID FIELD IN CDB при чтении/записи сверх лимита кеша приводит к тому, что выводится множество ошибок неверной команды, а данные CDB выталкиваются на консоль. - person Jotux; 28.10.2015
comment
А, вот что меня волновало. В коде ядра, который, кажется, смотрит на страницу ограничений блоков, я не вижу, чтобы он обращал внимание на максимальный размер передачи. Вздох... Проверьте этот вопрос на сайте unix/linux: unix.stackexchange.com/questions/67719/ . Кажется, что на стороне клиента вы можете вывести меньшее значение в /sys/block/sdX/queue/max_sectors (кажется, max_sectors_kb в более новых ядрах?). Однако я не уверен, что цель может каким-либо образом повлиять на это. - person Mike Andrews; 28.10.2015