Дано: Простенький PCI-девайс с небольшой внутренней памятью. Нужно: Прочесть значение памяти (32-х битное слово) по адресу, например, 0х10 от начала памяти. Что получается: В Win2k значение возвращается нормально. В XP почему-то вместо значения ячейки памяти упорно возвращается адрес этой ячейки. Например, если адрес 0хE0000010 (BAR = 0xE0000000, смещение = 0х10), то и возвращается 0xE0000010. Вопрос: Что это, Бэрримор? Дополнительные данные: Драйвер для девайса написан на VC++ 6.0 с использованием DDK2000 и DriverStudio 2.0. Могу кинуть кусок кода, но там ничего особенного - только запись и чтение KMemoryRegister...
Внесу кое-какие уточнения. В XP значение адреса возвращается, похоже, тогда, когда драйвер не успевает читать значение из памяти девайса. В Win2K такое "неуспевание" тоже бывало, только возвращалось значение 0xFFFFFFFF (т.е. как будто на эту область памяти не отображено ничего). Значение я читаю в цикле (сначала запись, потом чтение - это весь цикл), и на некоторых итерациях цикла такое и происходит. Компы такие: Celeron 1700 с WinXP и P4-2600 с Win2K. На обоих заметен этот глюк. Зато на старом P-90 (c Win2K) всё нормально, все итерации цикла проходят без ошибок. Такое впечатление, что девайс не успевает за слишком быстрым процессором... :-D Приведу куски кода из драйвера: Код (Text): ...кусок из заголовочного файла: // внутренняя память девайса KMemoryRange InfRegs; // регистр RSO KMemoryRegister regRSO; ...кусок из обработчика OnStartDevice: PCM_RESOURCE_LIST pResListRaw = I.AllocatedResources(); PCM_RESOURCE_LIST pResListTranslated = I.TranslatedResources(); KPciConfiguration PciConfig(m_Lower.TopOfStack()); status = InfRegs.Initialize( pResListTranslated, pResListRaw, PciConfig.BaseAddressIndexToOrdinal(0) ); // регистр regRSO - одно 32-битное слово по смещению 0x20 от начала памяти девайса regRSO = InfRegs[0x20]; ...кусок из обработчика IOCTL-функции, которая пишет и сразу читает память девайса: NTSTATUS Device406::TEST_STATUS_REGISTER_Handler(KIrp I) { ULONG *bufData; // получаем указатель на юзерский буфер bufData = (ULONG *) I.IoctlBuffer(); // тестируем (пишем/читаем) регистр RSO regRSO = *bufData; *bufData = regRSO; // количество записанных байт I.Information() = 4; return STATUS_SUCCESS; } Вот эту функцию я как раз и вызываю в цикле из проги. Подозреваю, что между записью и чтением нужно поставить проверку на готовность девайса к чтению. Как это сделать, если, конечно, проблема именно в этом?