Kernel driver reading HW regs, weird results

Ok, I believe I’m doing something wrong but I’m not sure what.

In my KMDF PrepareHardware callback, I get a nice translated address for the device, which I then map into my process space with MmMapIoSpace(). At this point I get confused…

I can dereference the pointer returned, and I look at the proper offset into that for the hardware version number, but I see bogus results.

Now, I’ve seen in the docs where it was mentioned that register programming should be done with the raw resources, yet I see in the examples that the translated resoures are used. Which is proper? I’m using the translated ones right now.

Second, I’m iffy on whether I need to go through the whole MDL-building exercise as I just need to read/write a linear sequence of registers on the hardware. If I have to build a MDL to do so, that would explain the bogus read results I’m seeing.

Sorry to ask questions on a Friday afternoon! But this is bugging me and I’d like to figure it out before I go home or I’ll obsess about it all weekend.

…ed…

Found the problem - I was stupid and didn’t use the HAL macros to read the registers. Color me embarassed! :blush:

Now getting the right major/minor version numbers and will be able to relax over the weekend.

…ed… (off for more coffee)

xxxxx@woolyloach.com wrote:

Ok, I believe I’m doing something wrong but I’m not sure what.

In my KMDF PrepareHardware callback, I get a nice translated address for the device, which I then map into my process space with MmMapIoSpace(). At this point I get confused…

I can dereference the pointer returned, and I look at the proper offset into that for the hardware version number, but I see bogus results.

I see you have solved your problem, but I’d like to understand what you
were doing that didn’t work. Although you should be using them for
future-proofing, the macros (like READ_REGISTER_ULONG) don’t do anything
other than dereference the pointer you give. That is, if this works:
unsigned long xxx = READ_REGISTER_ULONG(myaddr+0x28);
then this should also work:
unsigned long xxx *(unsigned long *)(myaddr + 0x28);

What was your code doing? Were you dereferencing bit fields, or a byte
at a time?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi! I was going in a byte at a time, since major/minor versions are byte-wide registers.

I was doing:

unsigned char foo = *(unsigned char *)(base + 0x02);

…but I also made changes to the way buffering was set and altered the caching to non-cached so it’s very likely wrongness in other places contributed to the issue.

…ed…

What’s the type of ‘base?’

mm
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@woolyloach.com
Sent: Friday, September 24, 2010 4:07 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Kernel driver reading HW regs, weird results

Hi! I was going in a byte at a time, since major/minor versions are
byte-wide registers.

I was doing:

unsigned char foo = *(unsigned char *)(base + 0x02);

…but I also made changes to the way buffering was set and altered the
caching to non-cached so it’s very likely wrongness in other places
contributed to the issue.

…ed…


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

xxxxx@woolyloach.com wrote:

Hi! I was going in a byte at a time, since major/minor versions are byte-wide registers.

I was doing:

unsigned char foo = *(unsigned char *)(base + 0x02);

…but I also made changes to the way buffering was set and altered the caching to non-cached so it’s very likely wrongness in other places contributed to the issue.

Could be. Some devices handle byte-wide reads. Some insist on dword at
a time. Depends on your hardware.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.