/* proc.c: PnP config tool proc i/f module */
/*
 * $Header: /root/pnp/tools/RCS/proc.c,v 1.1 1996/06/24 23:31:22 root Exp $
 *
 * $Log: proc.c,v $
 * Revision 1.1  1996/06/24  23:31:22  root
 * Initial revision
 *
 *
 */

/*
 * (c) Copyright 1996  D.W.Howells <dwh@nexor.co.uk>,
 */

#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include "tools.h"

struct pnp_dev *dev_list = NULL;
struct pnp_index *index_list[1024];
int index_count = 0;

/*****************************************************************************/
/* read the index that resides in /proc/pnp */
int pnp_read_index()
{
    struct pnp_index ix;
    struct pnp_dev *pdev;
    char buffer[100];
    FILE *file;
    int rt;

    file = fopen("/proc/pnp","r");
    if (!file)
	return -1;

    /* skip the header */
    fgets(buffer,100,file);
    fgets(buffer,100,file);

    while (1) {
	memset(&ix,0,sizeof(ix));
	if (fscanf(file,"%6s %5s %7s %8s %50[^\n]",
		   ix.pi_interface,
		   buffer,
		   ix.pi_ident,
		   ix.pi_driver,
		   ix.pi_data
		   )==EOF)
	    break;
	sscanf(buffer,"%02x-%02x",&ix.pi_csn,&ix.pi_dev);

	/* search for a match from the pnpdevices file */
	for (pdev=dev_list; pdev; pdev=pdev->pd_next)
	    if (strcasecmp(pdev->pd_ident,ix.pi_ident)==0)
		break;
	if (pdev)
	    ix.pi_device = pdev;

	/* read the configuration if not a card */
	if (strcmp("CARD",ix.pi_interface)!=0) {
	    ix.pi_ioc.pioc_req = PNPREQ_READ;
	    ix.pi_ioc.pioc_csn = ix.pi_csn;
	    ix.pi_ioc.pioc_dev = ix.pi_dev;
	    rt = ioctl(pnpconf,PNPIOC_REQUEST,&ix.pi_ioc);
	    if (rt<0)
		return rt;
	}

	/* add into the device list */
	index_list[index_count] =
	    (struct pnp_index*) malloc(sizeof(struct pnp_index));
	memcpy(index_list[index_count],&ix,sizeof(ix));
	index_count++;
    }
    fclose(file);

    return 0;
} /* end pnp_read_index() */

/*****************************************************************************/
#if 0
/* read the list of known pnp devices from /usr/local/lib/pnpdevices */
int read_devicelist()
{
    struct pnp_dev dev, *pdev;
    FILE *file;

    file = fopen("/usr/local/lib/pnpdevices","r");
    if (!file)
	return -1;

    while (memset(&dev,0,sizeof(dev)),
	   fscanf(file,"%7s:%80[^\n]",
		  dev.pd_ident,dev.pd_desc
		  )!=EOF
	   ) {
	pdev = (struct pnp_dev*) malloc(sizeof(dev));
	memcpy(pdev,&dev,sizeof(dev));
	pdev->pd_next = dev_list;
	dev_list = pdev;
    }

    fclose(file);

    return 0;
} /* end read_devicelist() */
#endif

/*****************************************************************************/
/* read the list of known pnp devices from /usr/local/lib/pnpdevices */
int read_devicelist()
{
    struct pnp_dev *pdev;
    FILE *file;
    char buffer[1024], *pchr, **ppchr;
    int loop;

    file = fopen("/usr/local/lib/pnpdevices","r");
    if (!file)
	return -1;

    while (1) {
	if (!fgets(buffer,1024,file))
	    break;

	pdev = (struct pnp_dev*) malloc(sizeof(*pdev));
	if (!pdev)
	    break;
	memset(pdev,0,sizeof(*pdev));
	pdev->pd_next = dev_list;
	dev_list = pdev;

	pchr = buffer + strlen(buffer);
	if (pchr[-1]=='\n')
	    pchr[-1] = '\0';

	pchr = strdup(buffer);
	ppchr = &pdev->pd_ident;
	for (loop=0; loop<18; loop++) {
	    *ppchr = pchr;
	    pchr = strchr(pchr,':');
	    if (!pchr)
		break;
	    *(pchr++) = '\0';
	    ppchr++;
	}
	if (!pdev->pd_ident)
	    pdev->pd_ident = "???????";
	if (!pdev->pd_desc)
	    pdev->pd_desc = "";
    }

    fclose(file);

    return 0;
} /* end read_devicelist() */
