Linux-Development-Sys Digest #761, Volume #8     Wed, 30 May 01 18:13:12 EDT

Contents:
  Prob. w/ mem mapped ISA card ( more info ) ("Jason M. LaPenta")
  Re: /usr/local/include is a file not directory ("Paul D. Smith")
  Re: accessing memory and IO space ("Ken Whaley")

----------------------------------------------------------------------------

From: "Jason M. LaPenta" <[EMAIL PROTECTED]>
Subject: Prob. w/ mem mapped ISA card ( more info )
Date: Wed, 30 May 2001 16:59:58 -0400

This is a multi-part message in MIME format.
==============CB4DEE2B728091385EF73DFF
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi, 
        There was a typo in the previous post (sorry), so I'm posting 
again and attaching the source code. 
Also, the isa_read() and isa_write() functions are explained in the 
document /usr/src/linux/Documentation/IO-mapping.txt
The kernel I'm using is linux-2.4.2 (released by Mandrake). I'm running
on a Pentium II with an ISA/PCI backplane.

Hello.

I'm trying to figure out why I can't access my custom built ISA card on
my linux box. It supposedly works fine with some ISA tester under WinNT
that someone else checked the board out with.

As a fundamental test I searched through the ISA memory 0xA0000 -
0xFFFFF to see what was there with both the board in the machine and the
board out of the machine. In both cases I got the same result. Here's
the code I ran via IOCTRL. My custom card is a 16bit isa card. 
Am I doing something wrong or is my card not working?

Thx in advance
Jason


    case SCAN_IOC_DEBUG :
      {
        printk( "scan : debug information %d\n", sizeof( savew ) );
                  
                  switch( DEBUG_SW )
                         {

                         case 1:
                                printk( "scan : searching for memory by byte\n" );

                                for( index = 0xA0000; index < 0xFFFFF; index++ )
                                  {
                                         saveb = isa_readb( index );
                                         isa_writeb( 0x55 , index );
                                         testb = isa_readb( index ); 
                                         if( testb == 0x55 && good == 0 )
                                                {
                                                  printk("0x%x", index);
                                                  good = index;
                                                }
                                         else if( testb != 0x55 && good != 0 && index 
!= (good + 1) )
                                                {
                                                  printk(" - 0x%x \n", (index - 1));
                                                  good = 0;
                                                }
                                         else if( testb != 0x55 && good != 0 )
                                                {
                                                  printk(", ");
                                                  good = 0;
                                                }

                                         isa_writeb( savew, index );
                                  }
                                break;

                         case 2:
                                printk( "scan : searching for memory by word\n" );

                                for( index = 0xA0000; index < 0xFFFFF; index++ )
                                  {
                                         savew = isa_readw( index );
                                         isa_writew( 0x5555, index );
                                         testw = isa_readw( index ); 
                                         if( testw == 0x5555 && good == 0 )
                                                {
                                                  printk("0x%x", index);
                                                  good = index;
                                                }
                                         else if( testw != 0x5555 && good != 0 && 
index != (good + 1) )
                                                {
                                                  printk(" - 0x%x \n", (index - 1));
                                                  good = 0;
                                                }
                                         else if( testw != 0x5555 && good != 0 )
                                                {
                                                  printk(", ");
                                                  good = 0;
                                                }

                                         isa_writew( savew, index );
                                  }
                                break;

                         }

                  printk( "\n g_num_interrupts = %d \n", g_num_interrupts );
                  break;
      }
==============CB4DEE2B728091385EF73DFF
Content-Type: text/plain; charset=us-ascii;
 name="scan_module.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="scan_module.c"

/**************************************************************************

    Scan Controller ISA Test Module

    Date Started : 5/2001
    Last Updated : 5/15/2001    
    
    Author : Jason LaPenta 5/2001 (adapted from ptg_module)
    
    Abstract : Tests the interface to the scan controller card
               for this test the irq will be 5 and the data
               io will be memory mapped to 0xE0500 - 0x57E

               only the first 32 double words are used for 
               access. 

               the isa bus writes to the lower 16 dwords, 
               and reads from upper 16 dwords

***************************************************/


#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
 
#define DEBUG_SW 2

#include <linux/module.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/uaccess.h>

#include "scan_module.h"

/*************************** 
 * MACROS
 ***************************/


/*************************** 
 * GLOBALS
 ***************************/
int scan_major     = 0;       /* setting to zero request a free major number */
int scan_base_addr = 0xE0500; /* memory mapped base addr for scan controller */
int scan_range     = 0x7E;    /* length of memory region from base_addr */
int scan_irq       = 5;       /* software configured */

 /* debugging var */ 
int g_temp = 0;
int g_num_interrupts = 0;

unsigned int scan_out_buf[16] = {0};
unsigned int scan_in_buf[16]  = {0};

/*************************** 
 * open
 *
 * called when user code 
 * opens the device
 ***************************/
int scan_open (struct inode *inode, struct file *filp)
{
  /*MOD_INC_USE_COUNT; removed for development */
  printk( KERN_INFO "scan : opened 0.04 \n"); 
  return 0;
}
 
/*************************** 
 * release
 * 
 * called when user code 
 * closes the device
 ***************************/
int scan_release (struct inode *inode, struct file *filp)
{ 
  /* MOD_DEC_USE_COUNT;  removed for development */ 
  printk( KERN_INFO "scan : released \n"); 
  return 0;
}

/********************************************************
 * Interrupt Handler
 * 
 *******************************************************/
static inline void scan_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
  int index = 0;

  g_num_interrupts++;

  printk( KERN_INFO "scan : interrupt %d\n", g_num_interrupts ); 

  for( index = 0; index < sizeof( scan_out_buf ) / 2; index++ )
         {
                ((short *)(scan_in_buf))[ index ]  = readw( scan_base_addr + index );
         }
        
}
 
/*************************************** 
 * IO Control
 * 
 * communication link to user code
 *
 * note : may want to add in a setdefault
 *        to change default settings
 ***************************************/
static int scan_ioctl( struct inode *inode, struct file *file, unsigned int cmd, 
                                                          unsigned long arg ) 
{   
  unsigned long flags;         /* for disabling interrupts */
  int ret   = 0;
  int index = 0;
  unsigned short int testw = 0;
  unsigned short int savew = 0;
  unsigned char testb = 0;
  unsigned char saveb = 0;
  int good = 0;
 
  /* extract the type and number bitfields, and don't decode */
  /* wrong cmds: return EINVAL before verify_area()          */
  if ( _IOC_TYPE(cmd) != SCAN_IOC_MAGIC ) 
    return -EINVAL;
  if ( _IOC_NR(cmd) > SCAN_IOC_MAXNR ) 
    return -EINVAL;

  /* process the command. interrupts are disabled if the */
  /* pulseArray needs to be modified */
  switch(cmd) 
    {             
      /* resets timings to default values */
    case SCAN_IOC_RESET :
      {
        save_flags( flags );
        cli();

        restore_flags( flags );
        break;
      }

      /* sets the requested channel to the desired value */      
    case SCAN_IOC_WRITE :
      {
        ret = copy_from_user( &scan_out_buf, (void *)arg, sizeof( scan_out_buf ) );
                  if( ret > 0 )
                         {
                                printk( KERN_INFO "scan : copy_from_user() error in 
SCAN_IOC_WRITE \n" ); 
                                return -EFAULT;
                         }

                  printk( KERN_INFO "scan : SCAN_IOC_WRITE 0x%x\n", scan_out_buf[ 0 ] 
); 
        /* write buffer to scan_controller */
        save_flags( flags );
        cli();
                  isa_writew( scan_out_buf[ 0 ], scan_base_addr );         

/*                for( index = 0; index < sizeof( scan_out_buf ) / 2; index++ ) */
/*                       { */
/*                              isa_writew( ((short *)(scan_out_buf))[ index ], 
scan_base_addr + index ); */
/*                       } */
        
        restore_flags( flags );      
        break;
      }

      /* returns the requested channel */
    case SCAN_IOC_READ :
      {

                  scan_in_buf[ 0 ]  = isa_readw( scan_base_addr ); 

                  ret = copy_to_user( (void *)arg, &scan_in_buf, sizeof( scan_in_buf ) 
);
                  if( ret > 0 )
                         {
                                printk( KERN_INFO "scan : copy_from_user() error in 
SCAN_IOC_READ \n" ); 
                                return -EFAULT;
                         }

                  printk( KERN_INFO "scan : SCAN_IOC_READ 0x%x \n",  isa_readw( 
scan_base_addr ) ); 
        break;
      }
      
      /* print out debug information */
    case SCAN_IOC_DEBUG :
      {
        printk( "scan : debug information %d\n", sizeof( savew ) );
                  
                  switch( DEBUG_SW )
                         {

                         case 1:
                                printk( "scan : searching for memory by byte\n" );

                                for( index = 0xA0000; index < 0xFFFFF; index++ )
                                  {
                                         saveb = isa_readb( index );
                                         isa_writeb( 0x55 , index );
                                         testb = isa_readb( index ); 
                                         if( testb == 0x55 && good == 0 )
                                                {
                                                  printk("0x%x", index);
                                                  good = index;
                                                }
                                         else if( testb != 0x55 && good != 0 && index 
!= (good + 1) )
                                                {
                                                  printk(" - 0x%x \n", (index - 1));
                                                  good = 0;
                                                }
                                         else if( testb != 0x55 && good != 0 )
                                                {
                                                  printk(", ");
                                                  good = 0;
                                                }

                                         isa_writeb( savew, index );
                                  }
                                break;

                         case 2:
                                printk( "scan : searching for memory by word\n" );

                                for( index = 0xA0000; index < 0xFFFFF; index++ )
                                  {
                                         savew = isa_readw( index );
                                         isa_writew( 0x5555, index );
                                         testw = isa_readw( index ); 
                                         if( testw == 0x5555 && good == 0 )
                                                {
                                                  printk("0x%x", index);
                                                  good = index;
                                                }
                                         else if( testw != 0x5555 && good != 0 && 
index != (good + 1) )
                                                {
                                                  printk(" - 0x%x \n", (index - 1));
                                                  good = 0;
                                                }
                                         else if( testw != 0x5555 && good != 0 )
                                                {
                                                  printk(", ");
                                                  good = 0;
                                                }

                                         isa_writew( savew, index );
                                  }
                                break;

                         }

                  printk( "\n g_num_interrupts = %d \n", g_num_interrupts );
                  break;
      }

      /* redundant, as cmd was checked against MAXNR */                  
    default:  
                printk( KERN_INFO "scan : Command Not Found \n" ); 
      return -EINVAL;    
    }
    
  return 0;
}
 
/***************************
 * file operations
 *  needed by init_module
 *  register_chrdev
 ***************************/ 
static struct file_operations scan_fops = {
  ioctl:   scan_ioctl,
  open:    scan_open,
  release: scan_release,
};

/******************************************************* 
 * init_module
 * 
 * called when the module is installed. It requested the
 * IO port and the required IRQ and starts the signals
 * out the timer card.
 *******************************************************/

int init_module(void)
{  
  int  result = 0;

  printk( KERN_INFO "scan : Starting Module\n");
  printk( KERN_INFO "scan : memory base addr = 0x%X\n", scan_base_addr );
  printk( KERN_INFO "scan : irq = %d\n", scan_irq );

  /* request isa board memory location */
  /*  result = request_mem_region( scan_base_addr, 0x1000, "aic7xxx" )
  if ( result <= 0 )
         {
                printf("scan : Cannot Memory Map Device");
                return result;
         }

  base_page = scan_base_addr & PAGE_MASK;
  maddr = ioremap_nocache( base_page, base_offset + 256 );*/


  /* register the module under /dev */
  result = register_chrdev( scan_major, "scan", &scan_fops );
  if( result < 0 )
    {
      printk( KERN_INFO "scan : Failed to register_chrdev\n" );
                /*      release_region( scan_base_addr, scan_range ); */
      return result;
    }

  if( scan_major == 0 ) 
    scan_major = result; /* dynamic */

  /***************************************
   * interrupt setup
   ***************************************/ 
  if( scan_irq >= 0 )
    {
      result = request_irq(scan_irq, scan_interrupt, SA_INTERRUPT, "scan", NULL);

      if( result )
        {
                         printk( KERN_INFO "scan: failed to assigned irq %i\n", 
scan_irq );
                         scan_irq = -1;                 
                         unregister_chrdev(scan_major, "scan");            
                         /*                      release_region( scan_base_addr, 
scan_range );*/
                         return -EINTR; 
        }
    }
    

  return 0;
} 
 
/*********************************
 * cleanup_module
 * 
 * called when modules if removed
 *********************************/
void cleanup_module(void)
{

  if( scan_irq >= 0 )
    {
      free_irq( scan_irq, NULL );
    }
        
  unregister_chrdev( scan_major, "scan" );
  /*  release_region( scan_base_addr, scan_range ); */
}

==============CB4DEE2B728091385EF73DFF==


------------------------------

From: "Paul D. Smith" <[EMAIL PROTECTED]>
Subject: Re: /usr/local/include is a file not directory
Date: 30 May 2001 17:04:07 -0400
Reply-To: [EMAIL PROTECTED]

%% [EMAIL PROTECTED] (Bob Glauser) writes:

  >> > When I try to compile any files, I get the error that
  >> > /usr/local/include is not a directory.  I have checked for the
  >> > directory, and in the /usr/local directory, is a file named
  >> > include. I do not know what this file is or why I have it in
  >> > place of the directory.

  bg> The file contains code, I'm pretty sure it is c.

This file is cdda_interface.h; CDDA is (usually) a part of the xmcd tool
that lets you play audio CDs in your computer's CDROM drive.

Did you try to install this by hand, rather than via your package
manager, perhaps?

  bg> I have put the file here:
  bg> http://www.angelfire.com/goth/rwg1226/include.txt , if anyone can
  bg> help me figure out what it is, how it got there, and what I need
  bg> to do with it to make my apps work, I would be very grateful.

Almost certainly what happened was that you did not have a
/usr/local/include directory and the install process expected it to
already exist.  Then during the install process, something similar to
this command was invoked:

  cp cdda_interface.h /usr/local/include

If the directory /usr/local/include exists, that will DTRT and create
/usr/local/include/cdda_interface.h.  If /usr/local/include _doesn't_
exist, then it copies cdda_interface.h to the file /usr/local/include.

Not what you want.

But, this is easily fixed:

  # mv /usr/local/include /usr/local/cdda_interface.h
  # mkdir /usr/local/include
  # mv /usr/local/cdda_interface.h /usr/local/include

-- 
===============================================================================
 Paul D. Smith <[EMAIL PROTECTED]>    HASMAT--HA Software Methods & Tools
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist
===============================================================================
   These are my opinions---Nortel Networks takes no responsibility for them.

------------------------------

From: "Ken Whaley" <[EMAIL PROTECTED]>
Subject: Re: accessing memory and IO space
Date: Wed, 30 May 2001 14:22:22 -0700


This won't work on linux, because ptrace explicitly prevents access to
non-RAM addresses.   I wanted to use gdb to do some h/w bringup too, and
ran into this.  So we hacked ptrace in the kernel to allow this.

A quicker/dirtier approach is to write a peek/poke program that mmaps
/dev/mem.  Has to run as root, but will do just what you want (for
memory mapped ranges of a PCI device).

"Arne Driescher" <[EMAIL PROTECTED]> wrote in message
news:[EMAIL PROTECTED]...
> [EMAIL PROTECTED] wrote:
> >
> > The need has arisen to be able to access arbritary memory and IO space
while
> > working on driver development for an embedded project. I am hoping that
> > someone can tell me a way to either use gdb to read/write memory or IO
space
> > or barring that, a debug program that will read/write any memory
address. I
> > have read 'man gdb' and tried the 'x' command to no avail. Maybe it is
as
> > simple as giving gdb a command line argument that I don't know yet. I
would
> > have to believe that such a thing is easy, its just that I don't know
how to
> > do it in this operating system. In developing drivers on other
architectures
> > (such as vxWorks for instance), it is easy to read memory and IO space
in
> > order to check and possibly re-configure driver hardware while
developing.
>
> Hmm, I usually try patching memory with gdb
> like
> set *0x123456=0x9876
> Is this what you want?
>
> -Arne
>




------------------------------


** FOR YOUR REFERENCE **

The service address, to which questions about the list itself and requests
to be added to or deleted from it should be directed, is:

    Internet: [EMAIL PROTECTED]

You can send mail to the entire list by posting to the
comp.os.linux.development.system newsgroup.

Linux may be obtained via one of these FTP sites:
    ftp.funet.fi                                pub/Linux
    tsx-11.mit.edu                              pub/linux
    sunsite.unc.edu                             pub/Linux

End of Linux-Development-System Digest
******************************

Reply via email to