Commit 5dd63391 authored by garcialasheras's avatar garcialasheras

Tools detached from kernel: no modules required

parent 46ea2e4d
......@@ -6,8 +6,9 @@
#define __LOADER_LL_C__ /* Callers won't define this symbol */
#ifdef __KERNEL__
#include "spec.h"
#ifdef __KERNEL__
#include "loader-ll.h"
#else
#include "loader-userspace.h"
......
......@@ -9,17 +9,20 @@
*/
#ifndef __SPEC_H__
#define __SPEC_H__
#include <linux/pci.h>
#include <linux/firmware.h>
#include <linux/completion.h>
#include <linux/fmc.h>
#include <linux/gpio.h>
#define PCI_VENDOR_ID_CERN 0x10dc
#define PCI_DEVICE_ID_SPEC 0x018d
#define PCI_VENDOR_ID_GENNUM 0x1a39
#define PCI_DEVICE_ID_GN4124 0x0004
#ifdef __KERNEL__
#include <linux/pci.h>
#include <linux/firmware.h>
#include <linux/completion.h>
#include <linux/fmc.h>
#include <linux/gpio.h>
#define SPEC_DEFAULT_LM32_ADDR 0x80000 /* used if "1" is passed */
/* Our device structure */
......@@ -141,5 +144,6 @@ extern int spec_eeprom_write(struct fmc_device *fmc, uint32_t offset,
extern int spec_gpio_init(struct fmc_device *fmc);
extern void spec_gpio_exit(struct fmc_device *fmc);
#endif /* __KERNEL__ */
#endif /* __SPEC_H__ */
......@@ -17,6 +17,7 @@
#include "speclib.h"
#include "loader-ll.h"
#include "spec.h"
#include "wb_uart.h"
struct spec_private {
......@@ -25,6 +26,54 @@ struct spec_private {
uint32_t vuart_base;
};
/*
* Check if the PCI device at bus/def_fn is a SPEC board.
* Return 1 if the device is a SPEC and 0 if it is not.
* If there is an error accessing the files, return -1
*/
static int spec_check_id(int bus, int dev)
{
unsigned int vendor, device;
char buf[128];
FILE *f;
// check device
snprintf(buf, sizeof buf,
"/sys/bus/pci/devices/0000:%02x:%02x.0/device",
bus, dev);
f=fopen(buf,"r");
if (f==NULL){
fprintf(stderr,"error accessing to file\n");
return -1;
}
fscanf(f, "%x", &device);
fclose(f);
// check vendor
snprintf(buf, sizeof buf,
"/sys/bus/pci/devices/0000:%02x:%02x.0/vendor",
bus, dev);
f=fopen(buf,"r");
if (f==NULL){
fprintf(stderr,"error accessing to file\n");
return -1;
}
fscanf(f, "%x", &vendor);
fclose(f);
if (device== PCI_DEVICE_ID_SPEC && vendor== PCI_VENDOR_ID_CERN)
return 1;
if (device== PCI_DEVICE_ID_GN4124 && vendor== PCI_VENDOR_ID_GENNUM)
return 1;
return 0;
}
/*
* Checks if there's a SPEC card at bus/def_fn.
* If one (or both) parameters are < 0, takes first available card
......@@ -36,26 +85,38 @@ static int spec_scan(int *bus, int *devfn)
int n, found = 0;
int my_bus, my_devfn;
n = scandir("/sys/bus/pci/drivers/spec", &namelist, 0, 0);
if (n < 0)
if (*bus < 0 || *devfn < 0)
{
perror("scandir");
exit(-1);
} else {
while (n--)
// Automatic search for the first availabe card
n = scandir("/sys/bus/pci/devices/", &namelist, 0, 0);
if (n < 0)
{
if(!found && sscanf(namelist[n]->d_name,
"0000:%02x:%02x.0",
&my_bus, &my_devfn) == 2)
perror("scandir");
exit(-1);
} else {
while (n--)
{
if(*bus < 0) *bus = my_bus;
if(*devfn < 0) *devfn = my_devfn;
if(*bus == my_bus && *devfn == my_devfn)
found = 1;
if(!found && sscanf(namelist[n]->d_name,
"0000:%02x:%02x.0",
&my_bus, &my_devfn) == 2)
{
if (spec_check_id(my_bus, my_devfn))
{
*bus = my_bus;
*devfn = my_devfn;
found = 1;
}
}
free(namelist[n]);
}
free(namelist[n]);
free(namelist);
}
free(namelist);
} else {
// Check if the requested card is available
if (spec_check_id(*bus, *devfn))
found = 1;
}
if(!found)
......@@ -77,7 +138,7 @@ static void *spec_map_area(int bus, int dev, int bar, size_t size)
int fd;
void *ptr;
snprintf(path, sizeof(path), "/sys/bus/pci/drivers/spec"
snprintf(path, sizeof(path), "/sys/bus/pci/devices/"
"/0000:%02x:%02x.0/resource%d", bus, dev, bar);
fd = open(path, O_RDWR | O_SYNC);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment