
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.3] |
![]() |
|
Страницы: (14) « Первая ... 3 4 [5] 6 7 ... 13 14 все ( Перейти к последнему сообщению ) |
Сообщ.
#61
,
|
|
|
Я так понял с EHCI мне тоже ещё предстоит разбираться...
Пока тоже просто в BIOS отключу. А насчёт завершения транзакции - я точно также делаю, слово в слово ![]() Просто этот метод я из UHCI взял, там по другому практически нельзя, прерывания то есть, но от какого дескриптора оно пришло определить нельзя. В OHCI хоть DoneQueue есть. Хотя в общем мне UHCI проще в программировании показался, хотя пишут, что он большие требования к софту выдвигает. Типа в OHCI многие вещи аппаратно реализованы, а в UHCI программно приходится делать. Но единственное с чем я столкнулся, так это с тем, что в OHCI есть прерывание по подключению/отключению устройства, а в UHCI нет - я на таймер вешал процедуру и проверял биты состояния порта. А в общем с UHCI вроди проще - может потому что тестировать мне легче (дома он у меня), да и примеры из Кулакова помогают. И ещё такой вопрос - ты при транзакции (например control_read) данные на какие блоки разбиваешь?? Ну тоесть в одном дескрипторе какой размер данных указываешь?? Я wMaxPacketSize для Endpoint0, а пока неизвестно - во время инициализации - 8б. Может в этом трабла?? |
Сообщ.
#62
,
|
|
|
Цитата cppasm @ ты при транзакции (например control_read) данные на какие блоки разбиваешь?? Напиример для запроса дескриптора устройства я делал так: потом повторяем процедуру, но в дескрипторе приема указываем полный размер дескриптора устройства (если конечно конечная точка 0 устройства поддерживает такой объем). А вообще для OHC в том вся прелесть, что в дескрипторе передачи можно указывать длину больше, чем конечная точка может воспринять, он сам разберется, как ему осуществить такую транзакцию ![]() Я, например, при чтении/записи на флешку создаю один дескриптор с объемом данных 512 байт и контроллер сам спокойно это съедает ![]() |
Сообщ.
#63
,
|
|
|
Спасибо! По исходникам Linux и FreeBSD я так и понял.
Но вроди размер блока (кроме последнего) должен быть кратен wMaxPacketSize и не должен больше раза пересекать границу 4Кб. На счёт кратности не уверен. Т.е. блоки размером больше 4Кб в одном дескрипторе описывать не желательно. При 4Кб блоке пересечений границы больше 1 не будет 100% |
Сообщ.
#64
,
|
|
|
Я проверил твою прогу и вот результат:
![]() ![]() Detcting OHCI USB Controllers... 1 OHCI USB Controller(s) detected OHCI USB Controller 0: VENDOR ID = 1039h, DEVICE ID = 7001h PCI BUS = 0, PCI DEV = 1, PCI FN = 2 MM BASE = DFFFB000h, IRQ = 5 Detecting USB Devices... Ctrl ND: ED[0]=00080000h; ED[1]=00120030h; ED[2]=00120021h; ED[3]=00000000h; TD00[0]=5EE40000h; TD00[1]=0002D67Eh; TD00[2]=00000000h; TD00[3]=0002D685h; TD01[0]=1A2B01A0h; TD01[1]=007006F4h; TD01[2]=08110016h; TD01[3]=007006F4h; TD02[0]=FFFFFFFFh; TD02[1]=FFFFFFFFh; TD02[2]=FFFFFFFFh; TD02[3]=FFFFFFFFh; После всего этого машина повисла, но не совсем (NUM LOCK работет)... Такое ощущение, что она в бесконечный цикл ушла... Небольшой разбор полученых данных: Из ED[2] - ошибка при обработке TВ00 В TD00[0] стоит код, что устройство не отвеает. В TD00[2] должен, по идее, быть адрес TD01. TD01[0]=1A2B01A0h - странное значение... я бы даже сказал, не правильное TD01[1] если идет передача без данных, то указатель на буфер должен быть равен 0 TD01[2]=08110016h - странное значение... Цитата cppasm @ Но вроди размер блока (кроме последнего) должен быть кратен wMaxPacketSize... Кратность совершенно не обязательна... пакеты с длиной 1, 31 или 13 байт, ухотят и приходят ![]() |
Сообщ.
#65
,
|
|
|
Обнаружил в коде ДУРАЦКУЮ ошибку...
Проги надо на свежую голову писать ![]() Насчёт кратности - мы друг друга не поняли. Например такое возможно: SETUP, read 13b, write 0b (ACK) Но если блок данных большой - больше 1 пересечения границы в 4Кб - его нужно разбивать на разные TD. И такое уже не возможно: SETUP,read 65b, read 63b, write 0b (ACK) при wMaxPacketSize=64b. Т.е. граница TD не должна попадать внутрь пакета. Отсюда требование чтобы размер блоков данных кроме последнего был кратен размеру пакета (wMaxPacketSize). Если найду в спецификации - зацитирую. Значится другие траблы появились. Отрубаю в BIOS USB2.0. Поиск устройства - нет его и всё (флэшка вставлена). Гружу Win - она находит. Завтра ещё дрова под DOS попробую - может и со сбросом у меня какие-то нелады. Но с другой стороны у тебя ж детектит... Прикреплённый файл ![]() |
Сообщ.
#66
,
|
|
|
Цитата cppasm @ Насчёт кратности - мы друг друга не поняли Да, действительно ![]() Результат остальзя тотже, что и в прошлый раз... машина виснет! Проверь условие выхода из цикла ожидания завершения транзакции. И еще в TD00 запиши адрес следующего TD, а то не понятно, что контроллер должен обрабатывать после первого. А ресет порта делается перед транзакцией? Извени, что указываю на такие очевидные вещи ![]() ![]() P.S. Сделай прогу, чтобы она не ждала завершения транзакции! Пусть она запускает транзакцию и вываливается в ДОС, я помторю, что там в памяти творится. P.P.S В приложении есть файлик с функциями для осуществления SETUP транзакций и два файла со структурами (на асме). Это кусок моего драйвера, посмотри, должно помоч ![]() Добавлено Цитата Gerret @ Отрубаю в BIOS USB2.0. Поиск устройства - нет его и всё (флэшка вставлена). Когда я начинал разбираться с OHC, написал прогу, которая в цикле считывала и показывала мне значения в регистрах контроллера. Попробуй и посмотри, что происходит внутри контроллера при подключении и отключении флешки. Прикреплённый файл ![]() |
Сообщ.
#67
,
|
|
|
Такой вопрос - что указывать в MPS в ED.
wMaxPacketSize или максимальный передаваемый блок данных, описанный в одном TD? Я к первому склоняюсь, но всё-же. Ресет делаю, по поводу TD не понял - вроди там всё Ок должно быть (откуда 0???), сейчас буду смотреть. |
Сообщ.
#68
,
|
|
|
Цитата cppasm @ Такой вопрос - что указывать в MPS в ED. wMaxPacketSize! |
Сообщ.
#69
,
|
|
|
Значит так.
Сделал я прогу - запускает одну транзакцию, ждёт нажатия на кнопку и выходит. Команда - SET_ADDRESS, т.е. Control Nodata. ED_ADDR=0x120000, TD_ADDR=0x120010 TD идут друг за другом. Если что выяснишь - сообщи ![]() Прикреплённый файл ![]() |
Сообщ.
#70
,
|
|
|
Нуууу... ничего, ровным счетом не изменилось...
В памяти по этим адресам я вижу только то, что раньше выводила твоя программа: ![]() ![]() 00120000: 00 00 08 00 30 00 12 00 21 00 12 00 00 00 00 00 00120010: 00 00 E4 5E C0 BA 02 00 00 00 00 00 C7 BA 02 00 00120020: 00 00 F4 F3 00 00 00 00 30 00 12 00 00 00 00 00 По адресу, (02BAC0h) где должен лежать USB Request какая-то лабуда находится: ![]() ![]() 0002BAC0: 13 19 46 72 12 0E 00 00 5E 05 F4 FF 25 0E 00 00 В общем вот! Давай попробуем так: подготавлизай все дескрипторы и запрос, но транзакцию не запускай. Помотрим что там изначально. P.S. Перемести, плиз, дескрипторы куда-нибудь по дальше, к примеру в 500000h, а то твоя прога затирает кусок swap'a от DosNavigator'a и он работать после этого отказывается. Приходится из под голого доса ее грузить. Добавлено Во блин! после последнего эксперимента у меня с диска С пропал io.sys ![]() |
Сообщ.
#71
,
|
|
|
Вот - переместил всё на адреса 600000h, 600010h, транзакцию не запускаю.
Я проверил - список TD нормально создаётся. Насчёт USB Request - он в стеке создаётся, и когда ты смотришь уже возможно затёрт. И тут до меня дошло! А ведь дескрипторы те которые ты написал ПРАВИЛЬНЫЕ. ![]() Просто контроллер обработал первый TD, изменил HeadP. Обработанный TD поместил в DoneQueue - а там своя очередь, и этот TD в ней последний, поэтому NextTD=0. Но остаётся вопрос с тем, почему устройство не отвечает... Посмотри состояние порта - может я его разрешаю неправильно. В общем, что можешь сказать по поводу: Reset HC: ![]() ![]() void ohci_init(HC *hc,int hcn) { int i,k; dword HCCA=0x500000; for(i=0;i<hcn;i++) { // Initialize HCCA. Setup interrupt ED. for(k=0x00;k<0x080;k++) writed(HCCA+k,ED); for(k=0x80;k<0x100;k++) writed(HCCA+k,0); // If SMM active - request ownership change. if(readd(hc[i].base+0x04) & 0x100) { writed(hc[i].base+0x08,0x08); for(k=0;k<10 && (readd(hc[i].base+0x04) & 0x100);k++) delay(1); } // Reset HC, enter UsbReset state. writed(hc[i].base+0x04,0x00); delay(10); // Reset HC, HC enters UsbSuspend state. writed(hc[i].base+0x04,0x00); delay(10); // Reset HC, HC enters UsbSuspend state. writed(hc[i].base+0x08,0x01); // Wait for reset completition. for(k=0;k<10 && (readd(hc[i].base+0x08) & 0x01);k++) delay(1); // Set HCCA physical address. writed(hc[i].base+0x18,HCCA); HCCA+=0x100; // Set Control head ED. writed(hc[i].base+0x20,ED); // Set Bulk head ED. writed(hc[i].base+0x28,ED); // Disable all HC interrupts. writed(hc[i].base+0x14,0xFFFFFFFF); // Enable interrupt (SMI) on ownership change. writed(hc[i].base+0x14,0xC0000000); // Start Host Controller. // Set UsbOperational state. // Disable Periodic List, Isochronous List, // Control List and Bulk List processing. writed(hc[i].base+0x04,0x80); // Set Frame Interval. writed(hc[i].base+0x34,0x27792EDF); // Set Periodic Start (90%). writed(hc[i].base+0x40,0x00002A2F); // Root Hub ports are power switched. // All ports are powered at the same time. writed(hc[i].base+0x48,readd(hc[i].base+0x48) & 0xFFFFFCFF); // Turn on power to all ports. writed(hc[i].base+0x50,0x10000); // Wait Power On to Power Good time. delay((readd(hc[i].base+0x48)>>23) & 0x1FE); } } PortEnable: ![]() ![]() // Enable Port of USB Controller. writed(hc[i].base+port,0x001F0002); Может тут что не правильно, или лишнее, или порт обязательно ресетить надо (я не ресечу, только HC). Я транзакцию не запускаю - посмотри какие дескрипторы будут. Прикреплённый файл ![]() |
Сообщ.
#72
,
|
|
|
Reset HC отличный! даже немного есть того, чего я не делал, например "Turn on power to all ports" и прочее связанное с питанием портов
![]() Цитата cppasm @ или порт обязательно ресетить надо Да, обязательно, а то устройство, которое подключено, может иметь любой адрес. Когда ты делаешь ресет, оно выставляет свой адрес в 0 и сбрасывает все свои внутренние регистры. А PortEnable выставлять не надо, когда ты ресет сделаешь, контроллер сам включит порт (ПРОВЕРЕНО!!!). Надо так: ![]() ![]() writed(hc[i].base+port,0x001F0010); delay(20); //можно 10, но я 20 делаю :) А с дескрипторами действительно все ОК! Это я, что-то туплю мольца ![]() Делай обратно транзакцию (без ожидания завершения), но вставь ресет порта, должно заработать. |
Сообщ.
#73
,
|
|
|
Вот.
Сегодня сходил к другу в гости в общагу. У него OHCI, ну я попрограммил немного ![]() Убил пол дня, но сейчас всё работает. Кстати после записи в HCFS UsbReset ресетится вся шина USB, включая подключённые устройства. Так что с этим всё Ок. PortEnable оставил как было. Попробуй. Если вдруг чего - ED=0x520000, TD=0x520010. Прикреплённый файл ![]() |
Сообщ.
#74
,
|
|
|
У меня не работает... она виснет! Я запустил ее через debuger и действительно, она зацикливается в одном месте и никуда не идет больше (крутится в адресах от cs:1027 - cs:1043). В памяти все как и раньше (уст-во не отвечает и т.д.) за исключением того, что теперь в TD00, в ячейке адреса следующего дескриптора, записан его собственный адрес!
Судя по тому, что я в отладчике видел, твоя прога не выходит из цикла ожидания завершения транзакции по флагу Halted в ED. Цитата cppasm @ Кстати после записи в HCFS UsbReset ресетится вся шина USB, включая подключённые устройства. Так что с этим всё Ок. Если тебе не нужен hot-swap то тогда такой вариант работать наверное будет... но если ты хочешь менять флешки налету, то без ресета портов не обойтись. Не будешь же ты весь контроллер переинициализировать, когда новое устройство подключается... |
Сообщ.
#75
,
|
|
|
Такс, буду щас разбираться.
Насчёт горячено подключения - тогда конечно порт ресетить надо. Насчёт того что виснет - там цикл глухой есть. Т.е. если устройство не отвечает - запустить транзакцию ещё раз. А устройство видно жёстко не отвечает. Попробуй вот это - а я счас с ресетом портов забацаю. С отладчиком можешь сильно не усердствовать - не работает и фиг с ним. ![]() Я кажись знаю в чём проблемма... Прикреплённый файл ![]() |