LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-10-2008, 04:34 AM   #1
webquinty
Member
 
Registered: Apr 2008
Location: Espaņa
Distribution: Suse
Posts: 227

Rep: Reputation: 32
Problem with access I/O ports.......


Hello,

I have a bit problem with I/O port access.
In user space I have this program:


Quote:
#include <stdio.h>
#include <unistd.h>
#include <sys/io.h>
#include <stdlib.h>
#include <sys/io.h>
#define BASEPORT 0x168

int main()
{
int i;
unsigned char valor;
if (ioperm(BASEPORT, 8, 1)!=0) {
printf("Error ioperm\n");
return -1;
}
for (i=0; i<7 ; i++)
{
valor = inb(BASEPORT+i);
/* Sleep for a while (100 ms) */
usleep(500000);
printf("Valor: %x\n", valor);
}
for (i=0; i<7 ; i++)
{
outb(0x00,BASEPORT+i);
/* Sleep for a while (100 ms) */
usleep(500000);
}
if (ioperm(BASEPORT, 8, 0)!=0) {
printf("Error ioperm\n");
return -1;
}
exit(0);
}
I have compiled with this order:

Quote:
gcc -O3 -Wall -m32 -I/usr/include -o example example.c
Well, IO ports are in 0x168 - 0x16F and 0x168-0x169 are Read only and othres are R/W.

outb command works fine when I tried to write a register, but if I read this register, always return me 0xFF.

Can I forget something??? any advice???

Best regards.
 
Old 12-10-2008, 10:19 AM   #2
webquinty
Member
 
Registered: Apr 2008
Location: Espaņa
Distribution: Suse
Posts: 227

Original Poster
Rep: Reputation: 32
This is the output of /proc/ioports

Quote:
0000-001f : dma1
0020-0021 : pic1
0040-0043 : timer0
0050-0053 : timer1
0060-006f : keyboard
0070-0077 : rtc
0080-008f : dma page reg
00a0-00a1 : pic2
00c0-00df : dma2
00f0-00ff : fpu
0168-016f : TSCAN1 Board
0170-0177 : 0000:00:0f.2
01f0-01f7 : 0000:00:0f.2
01f0-01f7 : ide0
02f8-02ff : serial
0376-0376 : 0000:00:0f.2
0378-037a : parport0
03c0-03df : vesafb
03f6-03f6 : 0000:00:0f.2
03f6-03f6 : ide0
03f8-03ff : serial
0cf8-0cff : PCI conf1
1000-101f : 0000:00:0f.0
6000-6007 : 0000:00:0f.0
6100-61ff : 0000:00:0f.0
6100-61ff : cs5535_gpio
6200-623f : 0000:00:0f.0
9c00-9c3f : 0000:00:0f.0
9d00-9d7f : 0000:00:0f.0
ac1c-ac1f : 0000:00:01.0
fa00-faff : 0000:00:10.0
fa00-faff : 8139too
fc00-fcff : 0000:00:09.0
fe00-fe7f : 0000:00:0f.3
ff00-ff0f : 0000:00:0f.2
ff00-ff07 : ide0
But, the output of cat /devport:
Quote:
00000b0 ffff ffff ffff ffff ffff ffff ffff ffff
00000c0 ffff ff7f ffff ffff efbc ebee ffff ffff
00000d0 ff00 ffb2 ffb2 ffb2 ffb2 ffb2 ffb2 ffb2
00000e0 ffff ffff ffff ffff ffff ffff ffff ffff
00000f0 2400 ffff ffff ffff ffff ffff ffff ffff
0000100 ffff ffff ffff ffff ffff ffff ffff ffff
*
00001f0 0000 ee00 1004 50e0 ffff ffff ffff ffff
0000200 ffff ffff ffff ffff ffff ffff ffff ffff
*
0000290 ffff ffff 20ff ff4f ffff ffff ffff ffff
00002a0 ffff ffff ffff ffff ffff ffff ffff ffff
is it normal, in /proc/ioport appear my hardware, but /dev/port does not show me values from port 0x168.
 
Old 12-10-2008, 02:59 PM   #3
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Perhaps the behavior of the device (is this is a CANbus board? Technologics Systems?) is such that writing a byte does not leave the board with the same values in those registers. How about trying some other registers such as a standard parallel port at 0x378? You must run your program with root privileges for ioperm() to work, but it seems that you are already doing this.
--- rod.
 
Old 12-10-2008, 04:33 PM   #4
webquinty
Member
 
Registered: Apr 2008
Location: Espaņa
Distribution: Suse
Posts: 227

Original Poster
Rep: Reputation: 32
Quote:
Originally Posted by theNbomr View Post
Perhaps the behavior of the device (is this is a CANbus board? Technologics Systems?) is such that writing a byte does not leave the board with the same values in those registers. How about trying some other registers such as a standard parallel port at 0x378? You must run your program with root privileges for ioperm() to work, but it seems that you are already doing this.
--- rod.

Hello,

Yes, is a Canbus card, is a TSCAN1 (pc/104)
And yes, I have tried to do it with a different port, for example, baseio=0x1f2 or 0x378, and my program works fine, inb return me correct value.

Now I have a doubt, why output >cat /dev/port | hexdump does not show me ports between 0x110 and 0x1e0???
Can I access as root this ports???

Best regards
 
Old 12-11-2008, 11:03 AM   #5
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
You should have access to all IO ports. If the specified port has no logic to decode a read, it will usually return 0xFF, as the bus floats to a logic high state. It may be courting failure to access all IO ports as you have done, as devices may interpret a read as a signal to do something, and that something may require the cooperation of some code to ensure correct behavior.
My interpretation of the output of hexdump is that whenever it finds a series of ports that return all '00's or all 'FF's, it simply uses the '*' notation to denote 'more of the same...'
It is not necessarily the case that all write registers will return the value written to them by reading from them. Some may have no logic to decode a read, and others may read back entirely different values, with different meanings. It is entirely a matter up to the designer of the part.
Have you tried to access the CANbus with a vendor-supplied driver? What happened?
--- rod.
 
Old 12-11-2008, 02:51 PM   #6
webquinty
Member
 
Registered: Apr 2008
Location: Espaņa
Distribution: Suse
Posts: 227

Original Poster
Rep: Reputation: 32
Hello,

Well, How can I explain you about vendor driver????
I bought this card in web page vendor because board description say "Driver Linux".
When I read manual of board later, I read "TSCAN1 is support by LinCan ( Ocera )", and problem is that this driver is for 2.4 kernel and not for 2.6. I am using 2.6.24.7-rt20.

Then I said that is a good moment to learn how to develop a driver and I begin to understand LinCan driver.
The first step of this driver is detect the board in four I/O port ranges 0x150, 0x158, 0x160 and 0x168.

Quote:
PHP Code:
    if(io_addr && (io_addr != (unsigned long)-1)) {
        
remap_io_addr io_addr tsxxx_base;

        if(
tscan1_check_presence(remap_io_addr, &jmp)){
            
CANMSG("No TSCAN1 card found at address 0xlx\n");
            return -
ENODEV;
        }
    } else {
        
DEBUGMSG("Scanning bus for TS-CAN1 boards...\n");

        for (
i=01;i++)
        {
            if(
>= 4) {
                
CANMSG("No TS-CAN1 boards found for slot %d\n"candev->candev_idx);
                return -
ENODEV;
            }

            
io_addr TSCAN1_BASE_IO i*TSXXX_IO_RANGE; [B]--> Here scanning I/O ports to find card.[/B]
            
remap_io_addr io_addr tsxxx_base;

            for (
0MAX_HW_CARDSj++) {
                if(
io[j] == io_addr){
                    
= -1;
                    break;
                }
            }
            if(
j<0)
                continue;

            if(!
tscan1_check_presence(remap_io_addr, &jmp))
                break;

        }
        
DEBUGMSG("TS-CAN1 board was found at 0x%lx for driver slot %d\n",
                    
io_addrcandev->candev_idx);

        
io[candev->candev_idx] = io_addr;
    } 
Quote:
PHP Code:
int tscan1_check_presence(unsigned long remap_io_addrint *pjmp)
{
    
int result = -ENODEV;

    if (!
can_request_io_region(remap_io_addrTSXXX_IO_RANGE"tscan1-probe"))
        return -
ENODEV;

    do {
        if (
inb(remap_io_addr+TSXXX_ID0_REG)!=TSCAN1_ID0 ||
            
inb(remap_io_addr+TSXXX_ID1_REG)!=TSCAN1_ID1)
            break;

        
outb(0x00remap_io_addr+TSCAN1_WIN_REG);
        
outb(0x20remap_io_addr+TSCAN1_MOD_REG);

        if(
pjmp)
            *
pjmp inb(remap_io_addr+TSCAN1_JMP_REG);

        
result 0;
    } while (
0);

    
can_release_io_region(remap_io_addrTSXXX_IO_RANGE);

    return 
result;

In my driver I only implement the last function, check if hardware is present, but always return me 0xFF.

I am going to make more test, but next step is to test this driver in 2.4 kernel to see what is the difference.

Thanks a lot for your help and I am sorry about my english, is bad.

Best regards
 
  


Reply



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 Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem opening ports - ports appear open, but do not work. computer_freak_8 Linux - Software 10 09-20-2008 09:39 PM
RHEL AS 4 No Remote Access on Certain Ports jharri3470 Linux - Security 8 01-24-2007 01:03 PM
How can I access web server ports? arupsarkar Linux - Security 2 04-16-2006 12:07 AM
trying to access usb ports SkiZzy Linux - Hardware 3 06-01-2004 01:51 PM
No access to any ports on my linux machine Danno13 Linux - Networking 5 05-03-2004 06:49 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:32 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration