
/*                                                 -*-mode:C;tab-width:8-*-
 * 
 * cxg_check.c -- a monitor for your hardware setup
 *
 * Copyright (C) 1995 Alessandro Rubini  -- rubini@ipvvis.unipv.it
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include "cxdrv.h"

#define RELEASE "0.09"

char *prgname;
#define PERROR(s) fprintf(stderr,"%s: %s: %s\n",prgname,s,strerror(errno))

int inforam(int fd)
{
  unsigned char pages[16]; int i,j;
  struct {int value; char *name;} status[] = {
    { CXG_MEM_FREE, "free"},
    { CXG_MEM_BUSY, "busy"},
    { CXG_MEM_RAM,  "ram"},
    { CXG_MEM_ROM,  "rom"},
    { 0,            NULL}
  };
  
  if(Cxg_GetRamInfo(fd,pages)<0)
    {
    PERROR("ioctl(CXG_GETRAMINFO)");
    return -1;
    }
  for (i=0;i<16;i++)
    {
    for (j=0;status[j].name; j++)
      if (pages[i]==status[j].value)
	break;
    printf("rampage 0x%x  %s\n",i,status[j].name);
    }
  return 0;
}


int infohw(int fd, char *N)
{
  Cxg_Board board;
  unsigned char ports[4];
      
  if (Cxg_GetHwInfo(fd,&board)<0)
    { PERROR("ioctl(CXG_GETHWINFO)"); return -1; }  
  printf("%s port_base  0x%03x\n",N,board.base);
  printf("%s may_overlay %i\n",N,!!board.may_overlay);
  printf("%s fpga_rev %i\n",N,board.fpga_rev);
  printf("%s micro_rev %i\n",N,board.micro_rev);
  printf("%s driver_rev %i.%02i\n",N,board.driver_rev1,board.driver_rev2);
  printf("%s irq %i\n",N,board.irq);
  printf("%s irq_received %li\n",N,board.irq_count);
  printf("%s current_rampage %i\n",N,board.ram);
  printf("%s has_video %i\n",N,board.has_video);
  printf("%s field_count %li\n",N,board.fields);
  printf("%s use_count %i\n",N,board.usecount);
  printf("%s lowres %i\n",N,board.lowres);
  printf("%s status %02x\n",N,board.status);

  if (Cxg_GetPorts(fd,ports))
    { PERROR("ioctl(CXG_GETPORTS)"); return -1; }
  printf("%s port0 %02x\n",N,ports[0]);
  printf("%s port1 %02x\n",N,ports[1]);
  printf("%s port2 %02x\n",N,ports[2]);
  printf("%s port6 %02x\n",N,ports[3]);
  return 0;
}

int main (int argc, char **argv)
{
int fds[8];
char nodename[8][16];
int i;
int got=0;
FILE *f;

  prgname=argv[0];

  if (argc==1)
    {
    /* first -- information about yourself */
    printf("%s version %s\n",prgname,RELEASE);
    printf("%s lib_version %s\n\n",prgname,Cxg_LibVersion());

    /* look for nodes */
    for (i=0; i<8; i++)
      {
      sprintf(nodename[i],"/dev/cxg%i",i);
      if ((fds[i]=open(nodename[i],O_RDWR))<0)
	PERROR(nodename[i]);
      else got++;
      }
        
    /* is there the module? */
    if (!got)
      {
      if (!(f=popen("grep cxdrv /proc/modules","r")))
	{ PERROR("/proc/modules"); exit(1); }
      if (!fgets(nodename[0],16,f))
	{
	fprintf(stderr,"cxdrv: no such module\n");
	exit(1);
	}
      pclose(f);
      fprintf(stderr,"cxdrv: no devices associated to the driver\n");
      exit(1);
      }

    /* ok, got some device. Look in them */

    /* first: look at the ram pages */
    for (i=0; fds[i]==-1; i++)
      ;
    inforam(fds[i]);

    for (i=0;i<8;i++)
      {
      if (fds[i]<0) continue;
      infohw(fds[i],nodename[i]);
      }

    exit(0);
    }

  /* else, cycle through argv */
  for (i=1; i<argc; i++)
    {
    int fd;

    if ((fd=open(argv[i],O_RDWR))<0)
      {
      PERROR(argv[i]);
      continue;
      }
    infohw(fd,argv[i]);
    close(fd);
    }
  exit(0); /* FIXME */
}
	
	  

