b4d5 ISA Device Driver and bus_alloc_resource_any(9) - The FreeBSD Forums
The FreeBSD Forums  

Go Back   The FreeBSD Forums > Development > FreeBSD Development

FreeBSD Development Kernel development, writing drivers, coding, and questions regarding FreeBSD internals.

Reply
 
Thread Tools Display Modes
  #1  
Old February 24th, 2011, 23:11
phs phs is offline
Junior Member
 
Join Date: Nov 2008
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default ISA Device Driver and bus_alloc_resource_any(9)

Hi,

I have an Alix 1.C for which I'm trying to write an I2C device driver. The system is AMD Geode LX based and as such has an AMD CS5536 South Bridge that contains the I2C/SMBus hardware. Judging by the datasheet available at http://support.amd.com/us/Embedded_T..._cs5536_db.pdf, the registers of the I2C controller are mapped into I/O space via a BAR.

The BAR can be read via a fixed-address MSR and I determined that the eight registers are mapped at I/O addresses 0x6000-0x6007. I have successfully used the io(4) device to access the registers from userland.

Apparently, the south bridge also announces itself as a PCI-ISA bridge and the kernel correctly recognizes it as such. The five I/O port ranges the kernel prints seem to correspond to the five "legacy devices" the south bridge contains. Here's the relevant part of the dmesg output:

Code:
alix# dmesg | grep isa
isab0: <PCI-ISA bridge> port 0x6000-0x6007,0x6100-0x61ff,0x6200-0x623f,0x9d00-0x9d7f,0x9c00-0x9c3f at device 15.0 on pci0
isa0: <ISA bus> on isab0
pmtimer0 on isa0
atrtc0: <AT realtime clock> at port 0x70-0x71 irq 8 pnpid PNP0b00 on isa0
atkbdc0: <Keyboard controller (i8042)> at port 0x60,0x64 irq 1 pnpid PNP0303 on isa0
uart0: <16550 or compatible> at port 0x3f8-0x3ff irq 4 flags 0x10 pnpid PNP0501 on isa0
ppc0: <Standard parallel printer port> at port 0x378-0x37f,0x778-0x77b irq 7 pnpid PNP0400 on isa0
uart1: <16550 or compatible> at port 0x2f8-0x2ff irq 3 pnpid PNP0501 on isa0
orm0: <ISA Option ROMs> at iomem 0xc0000-0xc7fff,0xc8000-0xd27ff,0xef000-0xeffff pnpid ORM0000 on isa0
sc0: <System console> at flags 0x100 on isa0
vga0: <Generic ISA VGA> at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa0
This is all fine, but I'd like to add a kernel device driver that uses the I/O port range 0x6000-0x6007. So my approach is to add a child to the ISA bus, and have the driver use bus_alloc_resource_any(9) to get a hold off the port range. Unfortunately, bus_alloc_resource_any(9) fails :-(

Code:
alix# kldload /tmp/glxiic.ko 
glxiic0: <AMD CS5536 SMBus/I2C controller> at port 0x6000-0x6007 on isa0
glxiic0: bus_alloc_resource_any(9) failed!
device_attach: glxiic0 attach returned 6
I read the developer's handbook and it seems the ISA bus driver needs to be told what I/O port range resource ID 0 corresponds to. So I added an identify routine to my driver that uses bus_set_resource(9) to set up the resource ID (I couldn't get the device.hints mechanism to work):

Code:
uint64_t    lbar;
u_long      ioport, port_start, port_count;
int         rc;

lbar = rdmsr(MSR_LBAR_SMB);
if (!(lbar & (1LL << 32))) {
    if (bootverbose) {
        device_printf(dev, "I/O memory mapping is not enabled by platform "
          "firmware!\n");
    }

    goto out;
}

ioport = (lbar & 0xFFF8);

rc = bus_get_resource(dev, SYS_RES_IOPORT, 0, &port_start, &port_count);
if ((port_start == ioport) && (port_count == RES_SIZE)) {
    goto out;
}

rc = bus_set_resource(dev, SYS_RES_IOPORT, 0, ioport, RES_SIZE);
if (bootverbose && rc) {
    device_printf(dev, "bus_set_resource(9) failed with rc=%i\n", rc);
}
Here's the code in the attach routine that fails:

Code:
sc->res_id = 0;
sc->res_io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->res_id,
  RF_ACTIVE);
if (sc->res_io == NULL) {
    device_printf(dev, "bus_alloc_resource_any(9) failed!\n");
    goto out;
}
What am I doing wrong? Has the isab code already allocated the port range? If so, how do I get it to give me a hold off the resource?

Last edited by DutchDaemon; February 25th, 2011 at 02:13. Reason: [man] tags are fun.
Reply With Quote
  #2  
Old March 6th, 2011, 23:16
phs phs is offline
Junior Member
 
Join Date: Nov 2008
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

So after digging through the bus and PCI code, it seems the generic PCI-ISA driver (isab) has allocated the resources. It does that because the device announces itself as a PCI-ISA bridge and claims certain memory and I/O resources in its BARs. Further, the PCI code will only assign resources to its direct children, so a device that sits below isab or isa in the device tree will not be able to claim resources that have been allocated by the PCI code.

My solution is to replace the generic isab driver with one that attaches specifically to the vendor and device IDs of the relevant CS5536 function. I can then grab the resources from the PCI code and assign it to my children.

I don't know if this is the "right" solution, but it seems to work so far. It has a down-side, however, because now I need to run a custom kernel and can't just build modules.
Reply With Quote
  #3  
Old November 18th, 2011, 00:47
Caffeinomane Caffeinomane is offline
Junior Member
 
Join Date: Nov 2011
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hi!
How is your work on the I2C driver going? I have an ALIX too and I would like to use the I2C that is built-in. Have you succeeded?
Reply With Quote
Reply

Tags
bus_alloc_resource, device driver, isa

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
8.1 and ISA Modem ertyu System Hardware 1 January 15th, 2011 05:27
network device driver queries email2akashjain FreeBSD Development 0 July 28th, 2010 08:56
FTDI FT232R device driver mlhuang FreeBSD Development 0 January 14th, 2010 16:48
sigprocmask within a device driver PaoloRoberti Userland Programming & Scripting 1 December 1st, 2009 10:47
[Solved] ISA card - nothing in dmesg kldload System Hardware 7 April 20th, 2009 20:19


All times are GMT +1. The time now is 05:43.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2013, vBulletin Solutions, Inc.
The mark FreeBSD is a registered trademark of The FreeBSD Foundation and is used by The FreeBSD Project with the permission of The FreeBSD Foundation.
Web protection and acceleration provided by CloudFlare
0