URL
https://opencores.org/ocsvn/pci/pci/trunk
Subversion Repositories pci
Compare Revisions
- This comparison shows the changes necessary to convert path
/pci/tags/rel_11/apps/sw
- from Rev 127 to Rev 154
- ↔ Reverse comparison
Rev 127 → Rev 154
/driver/pci_bridge32_test.h
0,0 → 1,82
// definition of maximum test application command length |
#define MAX_COMMAND_LEN 100 |
#define MAX_DESCRIPTION_LEN 1000 |
#define NUM_OF_COMMANDS 15 |
|
char GSA_COMMANDS [NUM_OF_COMMANDS][MAX_COMMAND_LEN] = { |
"help", |
"quit", |
"set_pci_region", |
"write", |
"read", |
"target_write", |
"dump", |
"master_read", |
"master_buf_fill", |
"master_write", |
"master_chk_write", |
"target_chk_write", |
"target_programmed_tests", |
"set_wb_region", |
"master_programmed_tests" |
} ; |
|
char GSA_COMMAND_DESCRIPTIONS [NUM_OF_COMMANDS][MAX_DESCRIPTION_LEN] = { |
"Displays basic command and parameter reference.", |
"Exits the program.", |
"Selects one of 6 bridge pci address regions <region> for subsequent accesses.", |
"Writes 32 bit word <value> to specified offset <offset> and performs read-back.", |
"Reads data from the specified offset <offset>.", |
"Initiates <number of transactions> write transactions with <transaction size> size. It starts from specified offset<offset>. <pattern> selects the pattern to write to on-board buffer.", |
"Reads 32 words from specified offset<offset>.", |
"Configures master to read data from the system memory buffer. Reads start at specified offset <offset>, using <number of transactions> read operations of size <transaction size>.", |
"Fills system buffer with the specified pattern <pattern>.", |
"Writes contents of device's RAM on specified offset to system memory. Writes start at specified offset <offset>, using <number of transactions> write operations of size <transaction size>.", |
"Checks <size> words of data in system memory from offset <offset> against a specified pattern <pattern>.", |
"Checks data in onboard buffer from offset <offset> against a specified pattern. Buffer is read with <number of transactions> transactions of size <transaction size>.", |
"Performs arround 2M read/write transactions through target. Writes write pseudo random data, reads check the data.", |
"Enables WISHBONE image <image[1:5]> for subsequent PCI Master accesses. The command doesn't check for implemented WB images!", |
"Executes the master test program code written in the function in the pci_bridge32_test.c file!" |
} ; |
|
char GSA_PARAMETERS [NUM_OF_COMMANDS][MAX_COMMAND_LEN] = { |
"", |
"", |
"<region[0:5]>", |
"<offset> <value>", |
"<offset>", |
"<starting offset> <number of transactions> <transaction size> <pattern>", |
"<offset>", |
"<offset> <number of transactions> <transaction size>", |
"<pattern>", |
"<offset> <number of transactions> <transaction size>", |
"<offset> <size> <pattern>", |
"<offset> <number of transactions> <transaction size> <pattern>", |
"", |
"<image[1:5]>", |
"" |
} ; |
|
#define GET_CMD(i) (GSA_COMMANDS[i]) |
#define GET_CMD_DES(i) (GSA_COMMAND_DESCRIPTIONS[i]) |
#define GET_CMD_PARMS(i) (GSA_PARAMETERS[i]) |
|
#define SYS_BUFFER_SIZE (4096) |
#define SPARTAN_BOARD_BUFFER_SIZE (1024) |
|
#define TARGET_BUFFER_SIZE (1024) |
|
#define MASTER_TRANS_SIZE_OFFSET (0x1000) |
#define MASTER_TRANS_COUNT_OFFSET (0x1004) |
#define MASTER_OP_CODE_OFFSET (0x1008) |
#define MASTER_ADDR_REG_OFFSET (0x100c) |
#define TARGET_BURST_TRANS_CNT_OFFSET (0x1010) |
#define TARGET_TEST_SIZE_OFFSET (0x1014) |
#define TARGET_TEST_START_ADR_OFFSET (0x1018) |
#define TARGET_TEST_START_DATA_OFFSET (0x101C) |
#define TARGET_TEST_ERR_REP_OFFSET (0x1020) |
#define MASTER_NUM_OF_WB_OFFSET (0x1024) |
#define MASTER_NUM_OF_PCI_OFFSET (0x1028) |
#define MASTER_TEST_SIZE_OFFSET (0x102C) |
#define MASTER_TEST_START_DATA_OFFSET (0x1030) |
#define MASTER_TEST_DATA_ERROR_OFFSET (0x1034) |
/driver/spartan_kint.h
0,0 → 1,32
#include <linux/ioctl.h> |
|
#define SPARTAN_IOC_NUM 'S' |
#define SPARTAN_IOC_MAX_NUM 11 |
|
#define SPARTAN_IOC_CURRESGET _IO(SPARTAN_IOC_NUM, 1) // read current resource - (0 = none) |
#define SPARTAN_IOC_CURRESSET _IO(SPARTAN_IOC_NUM, 2) // set current resource |
#define SPARTAN_IOC_CURBASE _IOR(SPARTAN_IOC_NUM, 3, base) // read current resource base address |
#define SPARTAN_IOC_CURBASEMAP _IOR(SPARTAN_IOC_NUM, 4, base) // read current resource remaped base address ( 0 - not remaped) |
#define SPARTAN_IOC_CURBASESIZE _IOR(SPARTAN_IOC_NUM, 5, base_size)// read current resource size |
#define SPARTAN_IOC_NUMOFRES _IO(SPARTAN_IOC_NUM, 6) // read number of found resources |
#define SPARTAN_IOC_VIDEO_BASE _IOR(SPARTAN_IOC_NUM, 7, base) // read video buffer phyisical base address |
#define SPARTAN_IOC_VIDEO_VBASE _IOR(SPARTAN_IOC_NUM, 8, base) // read video buffer virtual base address |
#define SPARTAN_IOC_VIDEO_SIZE _IOR(SPARTAN_IOC_NUM, 9, base_size) // read video buffer size |
#define SPARTAN_IOC_SET_VIDEO_BUFF _IO(SPARTAN_IOC_NUM, 10) // fill video buffer |
#define SPARTAN_IOC_GET_VIDEO_BUFF _IO(SPARTAN_IOC_NUM, 11) // copy video buffer to user space |
|
|
#define SPARTAN_P_IMG_CTRL1_ADDR 0x110 |
#define SPARTAN_P_BA1_ADDR 0x114 |
#define SPARTAN_P_AM1_ADDR 0x118 |
#define SPARTAN_P_TA1_ADDR 0x11c |
|
|
#define SPARTAN_W_IMG_CTRL1_ADDR 0x184 |
#define SPARTAN_W_BA1_ADDR 0x188 |
#define SPARTAN_W_AM1_ADDR 0x18C |
#define SPARTAN_W_TA1_ADDR 0x190 |
|
#define SPARTAN_CRT_CTRL 0x000 |
#define SPARTAN_CRT_ADD 0x004 |
#define SPARTAN_CRT_PALETTE_BASE 0x400 |
/driver/spartan_drv.c
0,0 → 1,636
#include <linux/module.h> |
#include <linux/errno.h> |
#include <linux/kernel.h> |
#include <linux/pci.h> |
#include <linux/wrapper.h> |
|
#include <asm/uaccess.h> |
#include <spartan_kint.h> //IOCTL definitions |
|
// define vendor and device ID here - currently this definitions specify reference designs from insight electronic |
#ifdef __SDRAM__ |
#define OC_PCI_VENDOR 0x1597 |
#define OC_PCI_DEVICE 0x0300 |
#endif |
#ifdef __VGA__ |
#define OC_PCI_VENDOR 0x1895 |
#define OC_PCI_DEVICE 0x0001 |
#endif |
#ifdef __OC_TEST__ |
#define OC_PCI_VENDOR 0x1895 |
#define OC_PCI_DEVICE 0x0001 |
#define __VGA__ |
#endif |
|
// if someone wants specific major number assigned to spartan board - specify it here |
// if 0 is used, kernel assigns it automaticaly |
#ifdef __SDRAM__ |
#define REQUESTED_MAJOR 0 |
#endif |
|
#ifdef __VGA__ |
#define REQUESTED_MAJOR 0 |
#endif |
|
// if compiling module for kernel 2.4 - leave this defined |
// for kernel 2.2 - comment this out |
#define KERNEL_VER_24 |
|
#ifndef SEEK_SET |
#define SEEK_SET 0 |
#define SEEK_CUR 1 |
#define SEEK_END 2 |
#endif |
|
// io.h needed just for kernel 2.2 |
#ifndef KERNEL_VER_24 |
#include <asm/io.h> |
#endif |
|
// memory mapped or IO mapped region definitions |
#define SPARTAN_MEM_MAPPED 0 |
#define SPARTAN_IO_MAPPED 1 |
|
#ifdef __VGA__ |
#ifdef __OC_TEST__ |
#define VIDEO_SZ (16384) |
#else |
#define VIDEO_SZ (640*480) |
#endif |
#endif |
|
// structure for holding board information |
// (6 base addresses, mapping, page etc. |
static struct our_dev |
{ |
int major ; |
u32 bases[6] ; |
u8 num_of_bases ; |
u32 base_size[6] ; |
u32 offset ; |
u32 page_addr ; |
u32 base_page_offset ; |
int current_resource ; |
int base_map[6] ; |
u32 video_base ; |
u32 video_vbase ; |
u32 video_size ; |
struct pci_dev *ppci_spartan_dev ; |
} pspartan_dev ; |
|
// function prototypes |
int spartan_open(struct inode *inode, struct file *filp); |
|
int spartan_release(struct inode *inode, struct file *filp); |
|
ssize_t spartan_read(struct file *filp, char *buf, size_t count, loff_t *offset ) ; |
ssize_t spartan_write(struct file *filp, const char *buf, size_t count, loff_t *offset) ; |
int spartan_ioctl(struct inode *pnode, struct file *filp, unsigned int cmd, unsigned long arg) ; |
loff_t spartan_seek(struct file *filp, loff_t offset, int what) ; |
|
// file operations structure - different for kernels 2.2 and 2.4 |
static struct file_operations *pspartan_fops ; |
static struct file_operations spartan_fops = { |
#ifdef KERNEL_VER_24 |
NULL, |
#endif |
spartan_seek, |
spartan_read, |
spartan_write, |
NULL, |
NULL, |
spartan_ioctl, |
NULL, |
spartan_open, |
NULL, |
spartan_release, |
} ; |
|
int open_mem_mapped(void) ; |
|
// seek file operation function |
loff_t spartan_seek(struct file *filp, loff_t offset, int origin) |
{ |
loff_t requested_offset ; |
int resource_num = pspartan_dev.current_resource ; |
|
switch (origin) |
{ |
case SEEK_CUR:requested_offset = pspartan_dev.offset + offset ; break ; |
case SEEK_END:requested_offset = pspartan_dev.base_size[resource_num] + offset ; break ; |
default:requested_offset = offset ; break ; |
} |
|
if ((requested_offset < 0) || (requested_offset > pspartan_dev.base_size[resource_num])) |
return -EFAULT ; |
|
pspartan_dev.offset = requested_offset ; |
|
return requested_offset ; |
} |
|
// ioctl for device |
// currently just a few operations are supported here - defined in spartan_kint.h header |
int spartan_ioctl(struct inode *pnode, struct file *filp, unsigned int cmd, unsigned long arg) |
{ |
int error = 0; |
int size = _IOC_SIZE(cmd) ; |
unsigned long base ; |
unsigned long base_size ; |
int i; |
|
if (_IOC_TYPE(cmd) != SPARTAN_IOC_NUM) return -EINVAL ; |
if (_IOC_NR(cmd) > SPARTAN_IOC_MAX_NUM) return -EINVAL ; |
|
// Writes through pointers not allowed - writes only through argument |
if (_IOC_DIR(cmd) & _IOC_WRITE) return -EINVAL ; |
else if (_IOC_DIR(cmd) & _IOC_READ) |
error = verify_area(VERIFY_WRITE, (void *) arg, size) ; |
|
if (error) |
return error ; |
|
switch (cmd){ |
case SPARTAN_IOC_CURRESGET: |
// current resource - they start at 1 |
return (pspartan_dev.current_resource + 1) ; |
case SPARTAN_IOC_CURRESSET: |
// check if resource is in a range of implemented resources |
if (arg < 0 ) |
return -EINVAL ; |
|
// unmap previous resource if it was mapped |
if (pspartan_dev.current_resource >= 0) |
{ |
iounmap((void *)pspartan_dev.page_addr) ; |
} |
|
if (arg == 0) |
{ |
// previous resource unmaped - that's all |
pspartan_dev.current_resource = -1 ; |
return 0 ; |
} |
|
if (pspartan_dev.num_of_bases < arg) |
return -ENODEV ; |
|
// IO mapped not supported yet |
if (pspartan_dev.base_map[arg] == SPARTAN_IO_MAPPED) |
{ |
// set current resource to none, since it was unmapped |
pspartan_dev.current_resource = -1 ; |
return -ENODEV ; |
} |
pspartan_dev.current_resource= (int)(arg-1) ; |
// remap new resource |
if ( (error = open_mem_mapped()) ) |
{ |
pspartan_dev.current_resource = -1 ; |
return error ; |
} |
return 0 ; |
case SPARTAN_IOC_CURBASE: |
// check if any resource is currently activated |
if (pspartan_dev.current_resource>=0) |
base = pspartan_dev.bases[pspartan_dev.current_resource] ; |
else |
base = 0x00000000 ; |
|
*(unsigned long *)arg = base ; |
return 0 ; |
case SPARTAN_IOC_CURBASEMAP: |
// check if any resource is currently activated |
if (pspartan_dev.current_resource>=0) |
base = pspartan_dev.page_addr ; |
else |
base = 0x00000000 ; |
|
*(unsigned long *)arg = base ; |
|
return 0 ; |
case SPARTAN_IOC_CURBASESIZE: |
// check if any resource is currently activated |
if (pspartan_dev.current_resource>=0) |
base_size = pspartan_dev.base_size[pspartan_dev.current_resource] ; |
else |
base_size = 0x00000000 ; |
|
*(unsigned long *)arg = base_size ; |
return 0 ; |
case SPARTAN_IOC_NUMOFRES: |
return (pspartan_dev.num_of_bases) ; |
#ifdef __VGA__ |
case SPARTAN_IOC_VIDEO_BASE: |
*((unsigned long *)arg) = pspartan_dev.video_base; |
put_user(pspartan_dev.video_base, ((unsigned long *)arg)); |
return 0 ; |
|
case SPARTAN_IOC_VIDEO_VBASE: |
*(unsigned long *)arg = pspartan_dev.video_vbase; |
put_user(pspartan_dev.video_vbase, ((unsigned long *)arg)); |
return 0 ; |
|
case SPARTAN_IOC_VIDEO_SIZE: |
*(unsigned long *)arg = pspartan_dev.video_size; |
put_user(pspartan_dev.video_size, ((unsigned long *)arg)); |
return 0; |
|
case SPARTAN_IOC_SET_VIDEO_BUFF: |
for(i = 0; i < VIDEO_SZ; i++) { |
get_user(*((char *)(pspartan_dev.video_vbase + i)), ((char *)(arg + i))); |
} |
|
return 0; |
case SPARTAN_IOC_GET_VIDEO_BUFF: |
for(i = 0; i < VIDEO_SZ; i++) { |
put_user(*((char *)(pspartan_dev.video_vbase + i)), ((char *)(arg + i))) ; |
} |
|
return 0 ; |
#endif |
default: |
return -EINVAL ; |
} |
} |
|
// helper function for memory remaping |
int open_mem_mapped(void) |
{ |
int resource_num = pspartan_dev.current_resource ; |
unsigned long num_of_pages = 0 ; |
unsigned long base = pspartan_dev.bases[resource_num] ; |
unsigned long size = pspartan_dev.base_size[resource_num] ; |
|
if (!(num_of_pages = (unsigned long)(size/PAGE_SIZE))) ; |
num_of_pages++ ; |
|
pspartan_dev.base_page_offset = base & ~PAGE_MASK ; |
|
if ((pspartan_dev.base_page_offset + size) < (num_of_pages*PAGE_SIZE)) |
num_of_pages++ ; |
|
// remap memory mapped space |
pspartan_dev.page_addr = (unsigned long)ioremap(base & PAGE_MASK, num_of_pages * PAGE_SIZE) ; |
|
if (pspartan_dev.page_addr == 0x00000000) |
return -ENOMEM ; |
|
return 0 ; |
} |
|
// add io mapped resource handler here |
int open_io_mapped( void ) |
{ |
return 0 ; |
} |
|
// open file operation function |
int spartan_open(struct inode *inode, struct file *filp) |
{ |
if (MOD_IN_USE) |
return -EBUSY ; |
|
pspartan_fops = &spartan_fops ; |
filp->f_op = pspartan_fops ; |
pspartan_dev.offset = 0 ; |
pspartan_dev.current_resource = -1 ; |
MOD_INC_USE_COUNT ; |
return 0 ; |
} |
|
// release - called by close on file descriptor |
int spartan_release(struct inode *inode, struct file *filp) |
{ |
// unmap any remaped pages |
if (pspartan_dev.current_resource >= 0) |
iounmap((void *)pspartan_dev.page_addr) ; |
|
pspartan_dev.current_resource = -1 ; |
|
MOD_DEC_USE_COUNT ; |
return 0 ; |
} |
|
// memory mapped resource read function |
ssize_t spartan_read(struct file *filp, char *buf, size_t count, loff_t *offset_out ) |
{ |
|
unsigned long current_address = pspartan_dev.page_addr + pspartan_dev.base_page_offset + pspartan_dev.offset ; |
unsigned long actual_count ; |
unsigned long offset = pspartan_dev.offset ; |
int resource_num = pspartan_dev.current_resource ; |
int i; |
unsigned int value; |
unsigned int *kern_buf ; |
unsigned int *kern_buf_tmp ; |
|
unsigned long size = pspartan_dev.base_size[resource_num] ; |
int result ; |
|
if (pspartan_dev.current_resource < 0) |
return -ENODEV ; |
|
if (offset == size) |
return 0 ; |
|
if ( (offset + count) > size ) |
actual_count = size - offset ; |
else |
actual_count = count ; |
|
// verify range if it is OK to copy from |
if ((result = verify_area(VERIFY_WRITE, buf, actual_count))) |
return result ; |
|
kern_buf = kmalloc(actual_count, GFP_KERNEL | GFP_DMA) ; |
kern_buf_tmp = kern_buf ; |
if (kern_buf <= 0) |
return 0 ; |
|
memcpy_fromio(kern_buf, current_address, actual_count) ; |
i = actual_count/4; |
while(i--) { |
|
// value = readl(current_address); |
value = *(kern_buf) ; |
put_user(value, ((unsigned int *)buf)); |
buf += 4; |
++kern_buf ; |
// current_address += 4; |
} |
|
kfree(kern_buf_tmp); |
pspartan_dev.offset = pspartan_dev.offset + actual_count ; |
|
*(offset_out) = pspartan_dev.offset ; |
|
return actual_count ; |
} |
|
// memory mapped resource write function |
ssize_t spartan_write(struct file *filp, const char *buf, size_t count, loff_t *offset_out) |
{ |
unsigned long current_address = pspartan_dev.page_addr + pspartan_dev.base_page_offset + pspartan_dev.offset ; |
unsigned long actual_count ; |
unsigned long offset = pspartan_dev.offset ; |
int resource_num = pspartan_dev.current_resource ; |
int i; |
int value; |
unsigned long size = pspartan_dev.base_size[resource_num] ; |
int result ; |
int *kern_buf ; |
int *kern_buf_tmp ; |
|
if (pspartan_dev.current_resource < 0) |
return -ENODEV ; |
|
if (offset == size) |
return 0 ; |
|
if ( (offset + count) > size ) |
actual_count = size - offset ; |
else |
actual_count = count ; |
|
// verify range if it is OK to copy from |
if ((result = verify_area(VERIFY_READ, buf, actual_count))) |
return result ; |
|
kern_buf = kmalloc(actual_count, GFP_KERNEL | GFP_DMA) ; |
kern_buf_tmp = kern_buf ; |
if (kern_buf <= 0) |
return 0 ; |
|
i = actual_count/4; |
while(i--) { |
get_user(value, ((int *)buf)); |
//writel(value, current_address); |
*kern_buf = value ; |
buf += 4; |
//current_address += 4; |
++kern_buf ; |
} |
|
memcpy_toio(current_address, kern_buf_tmp, actual_count) ; |
kfree(kern_buf_tmp) ; |
|
pspartan_dev.offset = pspartan_dev.offset + actual_count ; |
|
*(offset_out) = pspartan_dev.offset ; |
|
return actual_count ; |
} |
|
// initialization function - different for 2.2 and 2.4 kernel because of different pci_dev structure |
int init_module(void) |
{ |
int result ; |
u32 base_address ; |
unsigned long size ; |
unsigned short num_of_bases ; |
u16 wvalue ; |
struct pci_dev *ppci_spartan_dev = NULL ; |
struct resource spartan_resource ; |
struct page *page; |
int sz ; |
|
if(!pci_present()) |
{ |
printk("<1> Kernel reports no PCI bus support!\n " ); |
return -ENODEV; |
} |
|
if((ppci_spartan_dev = pci_find_device(OC_PCI_VENDOR, OC_PCI_DEVICE, ppci_spartan_dev))==NULL ) |
{ |
printk("<1> Device not found!\n " ); |
return -ENODEV ; |
} |
|
pspartan_dev.ppci_spartan_dev = ppci_spartan_dev ; |
|
#ifdef KERNEL_VER_24 |
//printk("<1> Board found at address 0x%08X\n", ppci_spartan_dev->resource[0].start) ; |
// copy implemented base addresses to private structure |
|
spartan_resource = ppci_spartan_dev->resource[0] ; |
base_address = spartan_resource.start ; |
printk("<1> First base address register found at %08X \n ", base_address ); |
num_of_bases = 0 ; |
while ((base_address != 0x00000000) && (num_of_bases < 6)) |
{ |
pspartan_dev.bases[num_of_bases] = spartan_resource.start ; |
pspartan_dev.base_size[num_of_bases] = spartan_resource.end - spartan_resource.start + 1 ; |
// check if resource is IO mapped |
if (spartan_resource.flags & IORESOURCE_IO) |
pspartan_dev.base_map[num_of_bases] = SPARTAN_IO_MAPPED ; |
else |
pspartan_dev.base_map[num_of_bases] = SPARTAN_MEM_MAPPED ; |
|
num_of_bases++ ; |
spartan_resource = ppci_spartan_dev->resource[num_of_bases] ; |
base_address = spartan_resource.start ; |
} |
|
result = pci_read_config_word(ppci_spartan_dev, PCI_COMMAND, &wvalue) ; |
if (result < 0) |
{ |
printk("<1> Read from command register failed! \n " ); |
return result ; |
} |
|
result = pci_write_config_word(ppci_spartan_dev, PCI_COMMAND, wvalue | PCI_COMMAND_MEMORY | PCI_COMMAND_IO) ; |
|
if (result < 0) |
{ |
printk("<1>Write to command register failed! \n " ); |
return result ; |
} |
|
#else |
|
printk("<1> Board found at address 0x%08X\n", ppci_spartan_dev->base_address[0]); |
|
// now go through base addresses of development board |
// and see what size they are - first disable devices response |
result = pci_read_config_word(ppci_spartan_dev, PCI_COMMAND, &wvalue) ; |
if (result < 0) |
{ |
printk("<1> Read from command register failed! \n " ); |
return result ; |
} |
|
// write masked config value back to command register to |
// disable devices response! mask value |
result = pci_write_config_word(ppci_spartan_dev, PCI_COMMAND, wvalue & ~PCI_COMMAND_IO & ~PCI_COMMAND_MEMORY) ; |
|
if (result < 0) |
{ |
printk("<1>Write to command register failed! \n " ); |
return result ; |
} |
|
// write to base address registers and read back until all 0s are read |
base_address = ppci_spartan_dev->base_address[0] ; |
num_of_bases = 0 ; |
while ((base_address != 0x00000000) && (num_of_bases < 6)) |
{ |
// copy non-zero base address to private structure |
pspartan_dev.bases[num_of_bases] = ppci_spartan_dev->base_address[num_of_bases] ; |
|
// write to current register |
result = pci_write_config_dword(ppci_spartan_dev, PCI_BASE_ADDRESS_0 + (num_of_bases * 4), 0xFFFFFFFF) ; |
|
if (result < 0) |
{ |
printk("<1>Write to BAR%d failed! \n ", num_of_bases); |
return result ; |
} |
|
result = pci_read_config_dword(ppci_spartan_dev, PCI_BASE_ADDRESS_0 + (num_of_bases * 4), &base_address) ; |
if (result < 0) |
{ |
printk("<1>Read from BAR%d failed! \n ", num_of_bases); |
return result ; |
} |
|
// calculate size of this base address register's range |
size = 0xFFFFFFFF - base_address ; |
|
// store size in structure |
pspartan_dev.base_size[num_of_bases] = size + 1; |
|
// set base address back to original value |
base_address = pspartan_dev.bases[num_of_bases] ; |
|
// now write original base address back to this register |
result = pci_write_config_dword(ppci_spartan_dev, PCI_BASE_ADDRESS_0 + (num_of_bases * 4), base_address) ; |
|
if (result < 0) |
{ |
printk("<1>Write to BAR%d failed! \n ", num_of_bases); |
return result ; |
} |
num_of_bases++ ; |
// read new base address |
base_address = ppci_spartan_dev->base_address[num_of_bases] ; |
|
} |
// write original value back to command register! |
result = pci_write_config_word(ppci_spartan_dev, PCI_COMMAND, wvalue) ; |
|
if (result < 0) |
{ |
printk("<1>Write to command register failed! \n " ); |
return result ; |
} |
#endif |
if (num_of_bases < 1) |
printk("<1>No implemented base address registers found! \n ") ; |
|
pspartan_dev.current_resource = - 1 ; |
|
// store number of bases in structure |
pspartan_dev.num_of_bases = num_of_bases ; |
|
// display information about all base addresses found in this procedure |
for (num_of_bases = 0; num_of_bases < pspartan_dev.num_of_bases; num_of_bases++) |
{ |
printk("<1>BAR%d range from %08X to %08X \n ", num_of_bases, pspartan_dev.bases[num_of_bases], pspartan_dev.bases[num_of_bases] + pspartan_dev.base_size[num_of_bases]); |
} |
#ifdef __VGA__ |
for (sz = 0, size = PAGE_SIZE; size < VIDEO_SZ; sz++, size <<= 1); |
pspartan_dev.video_vbase = __get_free_pages(GFP_KERNEL, sz); |
|
if (pspartan_dev.video_vbase == 0) { |
printk(KERN_ERR "spartan: abort, cannot allocate video memory\n"); |
return -EIO; |
} |
|
pspartan_dev.video_size = PAGE_SIZE * (1 << sz); |
pspartan_dev.video_base = virt_to_bus(pspartan_dev.video_vbase); |
|
for (page = virt_to_page(pspartan_dev.video_vbase); page <= virt_to_page(pspartan_dev.video_vbase + pspartan_dev.video_size - 1); page++) |
mem_map_reserve(page); |
|
printk(KERN_INFO "spartan: framebuffer at 0x%lx (phy 0x%lx), mapped to 0x%p, size %dk\n", |
pspartan_dev.video_base, virt_to_phys(pspartan_dev.video_vbase), pspartan_dev.video_vbase, pspartan_dev.video_size/1024); |
#endif |
|
result = register_chrdev(REQUESTED_MAJOR, "spartan", &spartan_fops) ; |
if (result < 0) |
{ |
printk(KERN_WARNING "spartan: can't get major number %d\n",REQUESTED_MAJOR) ; |
return result ; |
} |
|
printk("<1> Major number for spartan is %d \n", result ); |
pspartan_dev.major = result ; |
|
return 0 ; |
} |
|
// celanup - unregister device |
void cleanup_module(void) |
{ |
int result ; |
int size, sz; |
|
#ifdef __VGA__ |
for (sz = 0, size = PAGE_SIZE; size < VIDEO_SZ; sz++, size <<= 1); |
free_pages(pspartan_dev.video_vbase, sz); |
#endif |
result = unregister_chrdev(pspartan_dev.major, "spartan") ; |
if (result < 0) |
{ |
printk("<1> spartan device with major number %d unregistration failed \n", pspartan_dev.major); |
return ; |
} |
else |
{ |
printk("<1> spartan device with major number %d unregistered succesfully \n", pspartan_dev.major); |
return ; |
} |
} |
|
MODULE_LICENSE("GPL") ; |
/driver/pci_bridge32_test
0,0 → 1,183
+
+ ¨ ¬ ° ´ ¸ ¼ À Ä È Ì
+ Ð Ô Ø Ü à U‰åƒìè9 èÏ èš' ÉÃÿ5 ÿ%¤ ÿ%¨h éàÿÿÿÿ%¬h éÐÿÿÿÿ%°h éÀÿÿÿÿ%´h é°ÿÿÿÿ%¸h é ÿÿÿÿ%¼h( éÿÿÿÿ%Àh0 é€ÿÿÿÿ%Äh8 épÿÿÿÿ%Èh@ é`ÿÿÿÿ%ÌhH éPÿÿÿÿ%ÐhP é@ÿÿÿÿ%ÔhX é0ÿÿÿÿ%Øh` é ÿÿÿÿ%Ühh éÿÿÿÿ%àhp é ÿÿÿ 1í^‰áƒäðPTRh€¬h„QVh°†è7ÿÿÿô‰öU‰åSPè [þ‘ ‹ƒH …ÀtÿЋ]üÉÉöU‰åƒì‹LÐ…ÒuI‹HЋ…Àtt&