[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Question about installing a PCI parallel card



I have two EPP parallel port devices that I want to run from one
debian box. I could not find any purely EPP parallel cards, so
I got one that claimed ECP/EPP, an I/O Future Single Parallel PCI
Card (which uses NetMos Technology's 9805 chip). The docs for
that card claimed that a couple of simple I/Os is all it takes
to put it into EPP mode (attached is to_epp.c, which does those
I/Os). I hoped to be able to run to_epp and then run my app
that talks to the parallel device. No go :-(

My debian system seemed to find the new parallel port fine, here
is a section of /proc/pci and /proc/ioports.

/proc/pci (partial):
  Bus  0, device   8, function  0:
Communication controller: PCI device 9710:9805 (NetMos Technology) (rev 1).
      IRQ 10.
      Master Capable.  Latency=32.
      I/O at 0xc000 [0xc007].
      I/O at 0xc400 [0xc407].
      I/O at 0xc800 [0xc807].
      I/O at 0xcc00 [0xcc07].
      I/O at 0xd000 [0xd007].
      I/O at 0xd400 [0xd40f].


/proc/ioports (partial):
  c000-c007 : PCI device 9710:9805 (NetMos Technology)
    c000-c002 : parport1
    c003-c007 : parport1


The output from to_epp is:
  ~/docs/parallel_pci %to_epp c000
  ECR: 95
  DSR: c8
  DCR: 04
  DSR: c8
  DCR: 04

A trace of the application I/Os when using the std parallel port:
  from port 0x0379 -> 0xce
  to port 0x0379 -> 0xce
  to port 0x037a -> 0x00
  from port 0x037a -> 0xc0
  to port 0x037a -> 0x04
  to port 0x037b -> 0x18
  to port 0x037b -> 0x08
  to port 0x037b -> 0x0d
  from port 0x037c -> 0x54
  ... (more I/Os)

A trace of the application I/Os when using the PCI parallel port:
  from port 0xc001 -> 0xc8
  to port 0xc001 -> 0xc8
  to port 0xc002 -> 0x00
  from port 0xc002 -> 0x00
  to port 0xc002 -> 0x04
  to port 0xc003 -> 0x18
  to port 0xc003 -> 0x08
  to port 0xc003 -> 0x0d
  from port 0xc004 -> 0x04
  Board failure

The app quits there because it expects 0x54 from the last I/O,
which indicates that the device is initialized. The two differences
that I see in the traces are that the std port reports INT and
a reserved bit in its DSR (bits 1 and 2) whereas the PCI port
does not, and the std port reports two reserved bits (bits 6 & 7)
in its DCR whereas the PCI port does not... Interestingly the
card's docs say those reserved bits should be 0, but in the
std port (on the motherboard) on my system they are 1.

I have tried playing with timing (giving more time) but no change.

Any suggestions would be appreciated.

TIA,

Jim Kleck
/*
 * build with: gcc -O2 to_epp.c -o to_epp
 * run from root or use root to set the s bit
 */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/io.h>

#define FAIL -1
#define OK 0
static int GetParms(int, char **);
static void ShowSyntax(void);

unsigned long ulBase = 0x378;
unsigned long ulEcr;
unsigned long ulEppDsr;
unsigned long ulEppDcr;
unsigned long ulEppAddr;
unsigned long ulEppData;

int main (int argc, char *argv[])
{

  /* get parms */
  if (FAIL == GetParms(argc, argv)) {
    ShowSyntax();
    return -1;
  }

  ulEcr = ulBase + 0x402;
  ulEppDsr = ulBase + 0x001;
  ulEppDcr = ulBase + 0x002;
  ulEppAddr = ulBase + 0x003;
  ulEppData = ulBase + 0x004;
  iopl (3);
  
  /* Switch to EPP mode: 100 */
  outb (0x94, ulEcr);
  printf ("ECR: %02x\n", inb (ulEcr));

  /* init the EPP */
  printf ("DSR: %02x\n", inb (ulEppDsr));
  printf ("DCR: %02x\n", inb (ulEppDcr));
  outb (0x4, ulEppDcr);
  printf ("DSR: %02x\n", inb (ulEppDsr));
  printf ("DCR: %02x\n", inb (ulEppDcr));


  return 0;
}



/*
** GetParms
**
** Get the command line parms
**
** returns:	OK	if parms OK
**		FAIL	if parms bad
*/
static int
GetParms(int argc, char *argv[])
{
  char * pchEnd;

  /* if no parms then return and show syntax */
  if (argc != 2) {
    fprintf(stderr, "missing or extra args!\n");
    return FAIL;
  }

  /* get # of bytes to trim */
  ulBase = strtol(argv[1], &pchEnd, (int) 16);
  if (pchEnd == argv[1]) {
    fprintf(stderr, "arg not a number!\n");
    return FAIL;
  }
  if ((*pchEnd != '\0') && (*pchEnd != '\n') && (*pchEnd != '\r')) {
    fprintf(stderr, "arg not all a number or too big!\n");
    return FAIL;
  }
      
  return OK;
}



/*
** ShowSyntax
**
** Show the Command Line Syntax
**
*/
static void
ShowSyntax(void)
{
  printf("\n");
  printf("This program set a ECP Parallel port into EPP mode.\n");
  printf("Note: must be run from root or have the s bit set.\n");
  printf("\n");
  printf("Syntax:  to_epp _hex_base_addr\n");
  printf("\n");
}





Reply to: