
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.217.4] |
![]() |
|
Страницы: (51) « Первая ... 46 47 [48] 49 50 ... Последняя » ( Перейти к последнему сообщению ) |
Сообщ.
#706
,
|
|
|
Пара замечаний по взаимодействию с устройствами SuperSpeed.
Во-первых, в дескрипторе устройства поле bMaxPacketSize - байтовое. А значение maxPacketSize должно быть равно 512 (зафиксировано спецификацией USB3). Число 512 никак не помещается в один байт. Чтоб эту ситуацию разрешить, они стали писать в bMaxPacketSize показатель степени двойки. То есть реально в это поле пишется 9. А искомое число в байтах вычисляется как 1<<(bMaxPacketSize). Во-вторых, появились новые дескрипторы, в частности, дескрипторы с кодом bDescriptorType = 48 (30h) - SuperSpeed Endpoint Companion Descriptor, так что при поиске обычных дескрипторов EP надо быть аккуратным.. |
Сообщ.
#707
,
|
|
|
zakharo, очень интересно почитать про xhci. Спасибо, что не побоялся копнуть неизведанное и рассказываешь нам всем. Очень интересно почитать. Пока я не могу присоединиться (железа соответствующего нет и времени), но в скором времени тоже планирую заняться его поддержкой.
|
Сообщ.
#708
,
|
|
|
Мне самому было страсть как интересно разобраться во всем этом.
Сегодня удалось померять скорости. Я читал информацию с mass-storage устройств (флешки, USB-винчестер) из последовательных секторов, начиная с 0. Чтобы не заморачиваться с границами физических страниц, читал по 8 секторов в одну страницу (4 Кб) одной командой READ. Всего читал по 40 Мб, время засекал по BIOS'овскому таймеру (0:046ch). Получилось - при подключении флешек USB 2.0 самая быстрая дала около 8 Мб/сек. Винчестер USB 3.0 дал 24 Мб/с. Винда при работе с этим винчестером показывала около 80 Мб/с. Ну, понятно, у меня тут сильно упрощенный вариант, без длинных очередей, без обработки прерываний. И, в общем, скорость для меня - не самое главное. Главное - возможность в принципе работать с этим контроллером. Тот факт, что мне удалось выдать довольно много команд и получить много ответов на них (напомню - все это делается через кольца), говорит о том, что я правильно сделал работу с этими кольцами. И это радует. Теперь осталось привести все сделанное к уже имеющемуся у меня интерфейсу модулей контроллеров и почивать на лаврах.. :-) |
Сообщ.
#709
,
|
|
|
Цитата zakharo @ Винда при работе с этим винчестером показывала около 80 Мб/с. Скорость там достигается за счет использования больших блоков. Если читать по мегабайту сразу, то скорость была бы такой же, а то еще и больше. |
Сообщ.
#710
,
|
|
|
Чтобы читать по мегабайту, нужно делать цепочки TRB и еще долго разбираться с адресами физических страниц.. Ну их на фиг..
Еще я предполагаю, что Винда все эти очереди поддерживает динамически из разных потоков. А у меня же как - дал запрос, дождался выполнения, дал следующий, опять дождался.. На этом и теряем. Кстати, когда я в USB 2.0 перешел на 32-битный расширитель ДОС и с памятью стало гораздо легче, я сделал обмен с устройством по 4096 байт за одну операцию READ или WRITE. Ну, то есть, смотрю, что меньше - размер кластера или размер физической страницы памяти, и с этой меньшей величиной работаю. Для FAT32 8 секторов на кластер используются в большинстве случаев. Получается удобно - за одно обращение сразу кластер читается или пишется. Скорость получилась примерно вдвое меньше, чем в Винде. |
Сообщ.
#711
,
|
|
|
Цитата zakharo @ Получается удобно - за одно обращение сразу кластер читается или пишется У меня уровень ФС и уровень железа разделены. Драйвер ФС передает запрос на чтение блока секторов максимально возможной длины (как правило подавляющее большинство кластеров - смежные), а уже драйвер железки режет на оптимальные блоки. На самом деле с выравниванием особых проблем нет. Разбить все это хозяйство на страницы - нск. строк кода. |
Сообщ.
#712
,
|
|
|
Еще уточнение по поводу xHCI. Как отбирать его у BIOS. В спецификации написано не очень четко, поэтому надо пояснить.
В регистре HCCPARAMS биты 16:31 содержат смещение к блоку регистров "расширенных возможностей" - extended capabilities, xECP. Одним из этих регистров является интересующий нас, он называется USBLEGSUP (leqacy support). Смещение в HCCPARAMS задано в 32-битных словах относительно BAR1, т.е., если мы работаем на ассемблере, его надо умножать на 4. Если на Си с данными типа uint32_t, то надо просто брать его как индекс. Тут все понятно. А вот дальше идут не очень понятные изложения. С одной стороны, написано, что USBLEGSUP расположен по адресу xECP+0. С другой - оказывается, есть много этих самых capabilities. В общем, там надо искать то, что нужно нам - USB Legacy Support. Код "capability" записан в младшем байте регистра, а в байте 1 (биты 8:15) записано смещение к следующему блоку capabilities (опять-таки в 32-битных словах). Действуем так: читаем регистр по адресу base+xECP, смотрим его младший байт. Если он равен 1 (код USB Legacy Support), то мы нашли то, что нужно. Если нет - то к к значению xECP прибавляем байт 1 из считанного регистра (сдвинутый на 8 бит вправо, конечно), получаем новое значение xECP и возвращаемся в начало цикла. Заканчиваем цикл либо когда нашли USB Legacy Support, либо когда байт 1 очередного регистра capabilities окажется равным 0 (значит, мы не нашли USB Legacy Support, и беспокоиться не о чем). Дальше все просто - смотрим на 16-й бит USBLEGSUP, если он равен 1, то контроллером владеет BIOS. Пишем 1 в 24-й бит и ждем, когда 16-й бит обнулится, а 24-й останется - значит, BIOS отдала нам управление. Следующий регистр в блоке (USBLEGSUP+4) разрешает всякие SMI. Чтобы не было проблем, я весь его обнуляю. И только после этого можно стартовать контроллер - иначе неминуемо мертвое зависание. ![]() |
Сообщ.
#713
,
|
|
|
Есть еще существенное отличие xHCI от тех контроллеров, с которыми мы работали раньше. Оно заключается в обработке состояния STALL. Всем предыдущим контроллерам было наплевать на то, что EP выдала STALL - нам просто передавался этот код, и все.
Теперь же контроллер реагирует на состояние STALL. Помимо того, что он нам передает код STALL в Event Ring, он еще контекст соответствующей EP ставит в состояние HALTED и деактивирует TRB Ring для этой EP, то есть последующие "звонки в дверь" не сработают. Для сброса мы должны через Command Ring послать контроллеру команду Reset Endpoint с номером нужной нам EP. Это относится как к EP0, так и ко всем остальным. По этой команде контекст EP переводится из состояния Halted в состояние Stopped (TRB Ring снова активизируется и отреагирует на следующий "звонок"), после чего наш софт должен при необходимости снять состояние STALL в устройстве. |
Сообщ.
#714
,
|
|
|
Цитата zakharo @ Помимо того, что он нам передает код STALL в Event Ring, он еще контекст соответствующей EP ставит в состояние HALTED и деактивирует TRB Ring для этой EP, то есть последующие "звонки в дверь" не сработают На мой взгляд это правильно. |
Сообщ.
#715
,
|
|
|
Есть материнка GA-C807N мост Intel NM70 с 8-ю разьемами USB. Программно из USB вижу только два хаба. Logi прилагаю. Может кто подскажет как решить проблемму ? Может есть какая документация или ссылки на спецификацию по хабам.
Прикреплённый файл ![]() |
Сообщ.
#716
,
|
|
|
Цитата nwg @ Может кто подскажет как решить проблемму ? А в чем, собственно, проблема? Добавлено Цитата nwg @ Может есть какая документация или ссылки на спецификацию по хабам. Отдельной спецификации по хабам не видел. ЕМНИП они описываются в отдельной главе общей спецификации usb2. Вольный перевод есть в книге Кулакова. Также посмотри книгу Агурова о USB. Инфы много - ты просто не искал. |
Сообщ.
#717
,
|
|
|
Вкратце надо сделать так: инициализировать хаб, опросить по очереди его порты, инициализировать найденные устройства, а дальше - работать как обычно. Для работы с хабом есть набор соответствующих реквестов, все они описаны в общей документации по USB, как сказал shm.
|
Сообщ.
#718
,
|
|
|
Добрый день. Ребят подскажите по работе с UHCI.
Задача. Под DOS написать вывод файла на принтер, подключенный у USB. По идее ничего сложного, так как есть пример Кулакова работы с принтером (LIST8_03.ASM). Но при запуске файлов (как скомпилированных мною, так и из примеров) выдает превышение интервала ожидания. Путем отладки выяснено, что порт с принтером определяется корректно, но на функции Enumeration. А именно при попытке выполнить функцию Setup_Transaction c командой SetAddrDesc. В отладчике видно, что происходит зацикливание на этом участке кода: LIST8_01.INC ; Ожидать завершения операции @@Wait_OpComplete: ; Проверить номер кадра in AX,DX sub AX,[StartFrame] and AX,7FFh ;выделить младшие 11 разрядов cmp AX,500 ;ожидать не более 500 кадров ja @@TimeOut ;превышен интервал ожидания ; Проверить слово состояния cmp [dword ptr GS:ESI],1b jne @@Wait_OpComplete popad ret Регистр ax после чтения из порта постоянно 0. Зацикливание на cmp [dword ptr GS:ESI],1b jne @@Wait_OpComplete Посему. Подскажите в чем может быть проблема? При этом программа выложенная на форуме UHCI.EXE корректно выводит данные по подключенному устройству (принтеру). Попутно несколько вопросов: Пытаясь решить предыдущую проблему избавлялся от регистра GS. Подскажите корректно ли будет таким образом сделать замену: Исходный кусок кода: ; Загрузить в ESI указатель на массив дескрипторов mov ESI,[Addr_TD_Array] ; Сформировать дескриптор команды mov EAX,ESI add EAX,32 mov [GS:ESI],EAX мой mov ESI,[Addr_TD_Array] mov EAX, ESI add EAX,32 push USB_DESCR pop es mov si, offset TD_array mov [es:si],EAX Корректно ли так работать. Т.е. провожу запись не по линейному адресу, содержащемуся в ESI, а через смещение массива дескрипторов(TD_array) в сегменте дескрипторов(USB_DESCR). И еще один вопрос. По FrameListBaseAddr. В примере он установлен сразу конкретным значением. ; Физический адрес области памяти для списка кадров USB FrameListBaseAddr equ 200000h Почему так? Могу ли я определять его след образом: DATASEG …. FrameListBaseAddr dd 0 ENDS Segment FrameAddrr mampage //выравнивание в 4 КБ BaseAddr dd 1024 DUP (0) Ends CODESEG mov AX,DGROUP mov DS,AX mov [CS:MainDataSeg],AX xor eax,eax xor ebx,ebx mov ax, FrameAddrr ahl eax,4 mov bc, offset BaseAddr add eax,ebx mov FrameListBaseAddr, eax …. Ends Проблема в том, что при дальнейшем выполнении кода в примере на куске кода: ; Загрузить указатель на список кадров в регистр ; адреса списка кадров mov DX,[USB_BaseAddr] add DX,6 mov AX,0 out DX,AX add DX,2 mov EAX,FrameListBaseAddr out DX,EAX ; Активизировать хост-контроллер mov DX,[USB_BaseAddr] mov AX,1 out DX,AX На последней команде все повисает. По сему, можете ли подсказать в чем состоит ошибка или что имеет смысл попробовать? |
Сообщ.
#719
,
|
|
|
Krom, у Кулакова в примерах огромное количество ошибок, по памяти сейчас все и не вспомню. Однозначно ошибка в размере 0й КТ у него он всегда считается равным 8. На практике это как правило не так.
Добавлено Цитата Krom @ Пытаясь решить предыдущую проблему избавлялся от регистра GS У него, ЕМНИП, у GS перенастроен предел для доступа к 4Гб физ. памяти. Делается это хитро и через обычный (не перенастроенный) сегментный доступ к расширенной памяти не получить. Вся эта технология называется нереальный режим. Добавлено Цитата Krom @ Могу ли я определять его след образом: Некоторые контроллеры отказываются работать со структурами данных в базовой памяти. |
Сообщ.
#720
,
|
|
|
Понял, спасибо.
Цитата shm @ Однозначно ошибка в размере 0й КТ у него он всегда считается равным 8. На практике это как правило не так. 0й КТ - это что имеется ввиду? И каким образом можно определить истинный размер? |