Commit e88c95c9 authored by Manohar Vanga's avatar Manohar Vanga

Fixed spec driver to work with new format

Signed-off-by: 's avatarManohar Vanga <manohar.vanga@gmail.com>
parent 306feab0
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "sdwb.h" #include "../../wishbone/sdwb.h"
#define PRIORITY(flag) ((flag >> 28) & 0xf) #define PRIORITY(flag) ((flag >> 28) & 0xf)
#define CLASS(flag) ((flag >> 16) & 0xfff) #define CLASS(flag) ((flag >> 16) & 0xfff)
...@@ -38,7 +38,7 @@ struct sdwb_head *sdwb_create_header(uint64_t wbid_addr, uint64_t wbd_addr) ...@@ -38,7 +38,7 @@ struct sdwb_head *sdwb_create_header(uint64_t wbid_addr, uint64_t wbd_addr)
head = malloc(sizeof(struct sdwb_head)); head = malloc(sizeof(struct sdwb_head));
if (!head) if (!head)
return NULL; return NULL;
memcpy(&head->magic, SDWB_HEAD_MAGIC, sizeof(head->magic)); head->magic = SDWB_HEAD_MAGIC;
head->wbid_address = wbid_addr; head->wbid_address = wbid_addr;
head->wbd_address = wbd_addr; head->wbd_address = wbd_addr;
return head; return head;
...@@ -65,7 +65,7 @@ struct sdwb_wbd *sdwb_create_device(uint8_t major, uint8_t minor, ...@@ -65,7 +65,7 @@ struct sdwb_wbd *sdwb_create_device(uint8_t major, uint8_t minor,
dev = malloc(sizeof(struct sdwb_wbd)); dev = malloc(sizeof(struct sdwb_wbd));
if (!dev) if (!dev)
return NULL; return NULL;
memcpy(&dev->wbd_magic, SDWB_WBD_MAGIC, sizeof(dev->wbd_magic)); dev->wbd_magic = SDWB_WBD_MAGIC;
dev->wbd_version = (((major & 0xFF) << 8) | ((minor) & 0xFF)); dev->wbd_version = (((major & 0xFF) << 8) | ((minor) & 0xFF));
dev->vendor = vendor; dev->vendor = vendor;
dev->device = device; dev->device = device;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include "../wishbone/wb.h" #include "../wishbone/wb.h"
#include "../wishbone/sdwb.h"
#define PFX "fakespec: " #define PFX "fakespec: "
...@@ -20,7 +21,7 @@ struct wb_header { ...@@ -20,7 +21,7 @@ struct wb_header {
__u32 flags; __u32 flags;
}; };
int ndev; static int ndev;
LIST_HEAD(spec_devices); LIST_HEAD(spec_devices);
static struct mutex list_lock; static struct mutex list_lock;
...@@ -30,11 +31,11 @@ static int n; ...@@ -30,11 +31,11 @@ static int n;
static int fake_spec_probe(struct pci_dev *pdev, static int fake_spec_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
int i = -1;
int j = 0;
int nblock;
char fwname[64]; char fwname[64];
struct wb_header *header; unsigned int header_addr = 0; /* We would normally read this from the BAR */
struct sdwb_head *header;
struct sdwb_wbid *id;
struct sdwb_wbd *wbd;
struct wb_device *wbdev, *next; struct wb_device *wbdev, *next;
const struct firmware *wb_fw; const struct firmware *wb_fw;
...@@ -45,8 +46,8 @@ static int fake_spec_probe(struct pci_dev *pdev, ...@@ -45,8 +46,8 @@ static int fake_spec_probe(struct pci_dev *pdev,
/* /*
* load firmware with wishbone address map. In the real driver, we would * load firmware with wishbone address map. In the real driver, we would
* first load the bitstream into the fpga and then walk through the * first load the bitstream into the fpga.
* address space. For loading the bitstream, we read the bitstream ID off * For loading the bitstream, we read the bitstream ID off
* the eeprom on the spec board. * the eeprom on the spec board.
*/ */
sprintf(fwname, "fakespec-%08x-%04x", spec_vendor, spec_device); sprintf(fwname, "fakespec-%08x-%04x", spec_vendor, spec_device);
...@@ -55,44 +56,33 @@ static int fake_spec_probe(struct pci_dev *pdev, ...@@ -55,44 +56,33 @@ static int fake_spec_probe(struct pci_dev *pdev,
return -1; return -1;
} }
/* print a warning if it is not aligned to 1KB blocks */ header = (struct sdwb_head *)&wb_fw->data[header_addr];
if (wb_fw->size % 1024) if (header->magic != SDWB_HEAD_MAGIC) {
printk(KERN_DEBUG PFX "not aligned to 1024 bytes. skipping extra\n"); printk(KERN_ERR PFX "invalid sdwb header\n");
goto head_fail;
/* find the number of block present */
nblock = wb_fw->size / 1024;
if (!nblock) {
printk(KERN_DEBUG PFX "no devices in memory map\n");
goto nodev;
} }
/* register wishbone devices */ id = (struct sdwb_wbid *)&wb_fw->data[header->wbid_address];
while (++i < nblock) { printk(KERN_INFO PFX "found sdwb wishbone ID: %d\n", id->dummy);
header = (struct wb_header *)&wb_fw->data[i * 1024];
if (!header->vendor) wbd = (struct sdwb_wbd *)&wb_fw->data[header->wbd_address];
continue; while (wbd->wbd_magic == SDWB_WBD_MAGIC) {
wbdev = kzalloc(sizeof(struct wb_device), GFP_KERNEL); wbdev = kzalloc(sizeof(struct wb_device), GFP_KERNEL);
if (!wbdev) if (!wbdev)
goto alloc_fail; goto alloc_fail;
wbdev->vendor = header->vendor; /* Assign stuff here */
wbdev->device = header->device; memcpy(&wbdev->wbd, wbd, sizeof(struct sdwb_wbd));
wbdev->subdevice = header->subdevice;
wbdev->flags = header->flags;
if (wb_register_device(wbdev) < 0) if (wb_register_device(wbdev) < 0)
goto register_fail; goto register_fail;
mutex_lock(&list_lock); mutex_lock(&list_lock);
list_add(&wbdev->list, &spec_devices); list_add(&wbdev->list, &spec_devices);
ndev++;
mutex_unlock(&list_lock); mutex_unlock(&list_lock);
j++; wbd++;
} }
ndev = j;
printk(KERN_INFO PFX "found %d wishbone devices\n", ndev); printk(KERN_INFO PFX "found %d wishbone devices\n", ndev);
return 0; return 0;
nodev:
release_firmware(wb_fw);
return 0;
register_fail: register_fail:
kfree(wbdev); kfree(wbdev);
alloc_fail: alloc_fail:
...@@ -103,6 +93,7 @@ alloc_fail: ...@@ -103,6 +93,7 @@ alloc_fail:
kfree(wbdev); kfree(wbdev);
} }
mutex_unlock(&list_lock); mutex_unlock(&list_lock);
head_fail:
release_firmware(wb_fw); release_firmware(wb_fw);
return -1; return -1;
} }
...@@ -135,6 +126,7 @@ static struct pci_driver fake_spec_pci_driver = { ...@@ -135,6 +126,7 @@ static struct pci_driver fake_spec_pci_driver = {
static int fake_spec_init(void) static int fake_spec_init(void)
{ {
n = 0; n = 0;
ndev = 0;
mutex_init(&list_lock); mutex_init(&list_lock);
return pci_register_driver(&fake_spec_pci_driver); return pci_register_driver(&fake_spec_pci_driver);
} }
......
#include <wb.h> #include <wb.h>
static struct wb_device_id wbtest_ids[] = { static struct wb_device_id wbtest_ids[] = {
{ WBONE_ANY_ID, WBONE_ANY_ID, WBONE_ANY_ID }, { WBONE_ANY_ID, WBONE_ANY_ID},
{ 0, }, { 0, },
}; };
......
#ifndef SDWB_H #ifndef SDWB_H
#define SDWB_H #define SDWB_H
#include <stdint.h> #define SDWB_HEAD_MAGIC (('s'<<7)|('d'<<6)|('w'<<5)|('b'<<4)|('h'<<3)|('e'<<2)|('a'<<1)|'d')
#define SDWB_WBD_MAGIC (('w'<<8)|'b')
#define SDWB_HEAD_MAGIC "SDWBHEAD"
#define SDWB_WBD_MAGIC "wb"
struct sdwb_head { struct sdwb_head {
uint64_t unused; uint64_t unused;
......
...@@ -15,7 +15,7 @@ static void wb_dev_release(struct device *dev) ...@@ -15,7 +15,7 @@ static void wb_dev_release(struct device *dev)
{ {
struct wb_device *wb_dev; struct wb_device *wb_dev;
wb_dev = to_wb_device(dev); wb_dev = to_wb_device(dev);
printk(KERN_DEBUG PFX "release %d\n", wb_dev->vendor); printk(KERN_DEBUG PFX "release %llx\n", wb_dev->wbd.vendor);
} }
/* /*
...@@ -77,13 +77,11 @@ static struct wb_device_id *wb_match_device(struct wb_driver *drv, ...@@ -77,13 +77,11 @@ static struct wb_device_id *wb_match_device(struct wb_driver *drv,
struct wb_device_id *ids; struct wb_device_id *ids;
ids = drv->id_table; ids = drv->id_table;
if (ids) { if (ids) {
while (ids->vendor || ids->device || ids->subdevice) { while (ids->vendor || ids->device) {
if ((ids->vendor == WBONE_ANY_ID if ((ids->vendor == WBONE_ANY_ID
|| ids->vendor == dev->vendor) && || ids->vendor == dev->wbd.vendor) &&
(ids->device == (__u16)WBONE_ANY_ID (ids->device == (__u16)WBONE_ANY_ID
|| ids->device == dev->device) && || ids->device == dev->wbd.device))
(ids->subdevice == (__u16)WBONE_ANY_ID
|| ids->subdevice == dev->subdevice))
return ids; return ids;
ids++; ids++;
} }
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/list.h> #include <linux/list.h>
#include "sdwb.h"
#define WBONE_ANY_ID (~0) #define WBONE_ANY_ID (~0)
struct wb_device; struct wb_device;
...@@ -13,7 +15,6 @@ struct wb_device; ...@@ -13,7 +15,6 @@ struct wb_device;
struct wb_device_id { struct wb_device_id {
__u32 vendor; /* Vendor or WBONE_ANY_ID */ __u32 vendor; /* Vendor or WBONE_ANY_ID */
__u16 device; /* Device ID or WBONE_ANY_ID */ __u16 device; /* Device ID or WBONE_ANY_ID */
__u16 subdevice; /* Device ID or WBONE_ANY_ID */
}; };
struct wb_driver { struct wb_driver {
...@@ -31,11 +32,14 @@ struct wb_driver { ...@@ -31,11 +32,14 @@ struct wb_driver {
struct wb_device { struct wb_device {
char *name; char *name;
#if 0
unsigned int vendor; unsigned int vendor;
unsigned short device; unsigned short device;
unsigned short subdevice; unsigned short subdevice;
unsigned int flags; /* MSB to LSB: 4 bits priority, 12 bits class, unsigned int flags; /* MSB to LSB: 4 bits priority, 12 bits class,
16 bits version */ 16 bits version */
#endif
struct sdwb_wbd wbd;
struct wb_driver *driver; struct wb_driver *driver;
struct list_head list; struct list_head list;
struct device dev; struct device dev;
......
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