cant figure out this PCI driver
testlaster
testlaster at gmail.com
Wed Dec 10 02:33:58 EST 2014
Hi guys.
Im first going to explain why im doing this and what I want to achieve
before giving the problem.
My main objective here is to gain access to a piece of shared memory.
The memory is shared between an FPGA and a PCI chip called a PLX9054.
I have to work through the PCI chip to gain access to the RAM.The only
way I know of In order to do that is to build a driver PCI for Linux
(Lubuntu).
Now Ive looked at a couple of examples and I have taken one of the
examples and changed it quite allot. It seems like I am attaching to the
rite device because when I check the VendorId and DeviceID they seem to
be the right ones.
For now im debugging in the .write() function just to see if Im heading
in the right direction at least "Latching on to RAM".Im doing that
because now I can see all my functions whenever I use " echo 'write' >
pciproto " where pciproto is the DEVICE file in /dev/ .
But I am not having any luck though. Ive been reading through
/linux/pci.h , /source/driver/pci/pci.c , /source/driver/dma/dma.c
and allot of other source files and headers looking for something that
can help me but what I have found doesn't seem to work. Ive tried DMA
but checking DMA capability with pci_set_dma_mask() returned a FAIL as
well as pci_request_region().
Im not quite sure what im suppose to use or to do to just be able to
latch onto the piece of RAM.
If im going towards this all wrong please let me know and also let me
know if theres any better way to do this.
Here is my CODE:
[CODE]
1.
/**
2.
* This program is an attempt to latch on to the FG memory that is
shared with the FPGA
3.
* After a data sample has been taken the fg stores the data in
this region.
4.
* This Driver will latch on to the DEV file named pciproto. For
testing purposes the /dev/pciproto has to be
5.
*created manually in the /dev folder. The following command will
create a DEV file with a maximum number of
6.
*250 and a minor number of 0: mknod pciproto c 250 0
7.
*
8.
* There are only 3 registers:
9.
* STATUS: addr = BAR2 + 0
10.
* unused for now
11.
* READ_DATA: addr = BAR2 + 1
12.
* this register can only be read. Each time it's read, the device
13.
* read a byte from his input and return it.
14.
* WRITE_DATA: addr = BAR2 + 2
15.
* this register can only be written. Each time it's written,
the device
16.
* write the byte on his output.
17.
*
18.
*/
19.
20.
#include <linux/kernel.h>
21.
#include <linux/init.h>
22.
#include <linux/module.h>
23.
#include <linux/pci.h>
24.
#include <linux/fs.h>
25.
#include <linux/cdev.h> /* for cdev_ */
26.
#include <asm/uaccess.h> /* for put_user */
27.
#include <linux/ioport.h>
28.
29.
#define MAX_DEVICE 8
30.
#define DEVICE_NAME "pciproto"
31.
#define BAR_IO 2
32.
#define BAR_MEM 3
33.
#define BAR_SETTINGS 2
34.
#define BAR_PHOTO_MEM 3
35.
36.
37.
MODULE_DESCRIPTION("Test PCI driver");
38.
MODULE_AUTHOR("Gerfg ");
39.
MODULE_LICENSE("GPL");
40.
41.
/**
42.
* This table holds the list of (VendorID,DeviceID) supported by
this driver
43.
*
44.
*/
45.
staticstructpci_device_id pci_ids[]={
46.
{PCI_DEVICE(0x10B5,0x9054),},
47.
{0,}
48.
};
49.
50.
/**
51.
* This macro ...
52.
*
53.
*/
54.
MODULE_DEVICE_TABLE(pci,pci_ids);
55.
56.
staticdev_t devno;
57.
staticintmajor;
58.
59.
/**
60.
* This structure is used to link a pci_dev to a cdev
61.
*
62.
*/
63.
structpci_cdev{
64.
intminor;
65.
structpci_dev*pci_dev;
66.
structcdev*cdev;
67.
};
68.
69.
staticstructpci_cdev pci_cdev[MAX_DEVICE];
70.
71.
/* this function initialize the table with all struct pci_cdev */
72.
staticvoidpci_cdev_init(structpci_cdev
pci_cdev[],intsize,intfirst_minor)
73.
{
74.
inti;
75.
76.
for(i=0;i<size;i++){
77.
pci_cdev[i].minor=first_minor++;
78.
pci_cdev[i].pci_dev=NULL;
79.
pci_cdev[i].cdev=NULL;
80.
printk(KERN_INFO"RAN:
pci_dev_init(-pci_cdev-,%i,%i)\n",size,pci_cdev[i].minor);
81.
}
82.
}
83.
84.
/*
85.
-1 => failed
86.
others => succes
87.
*/
88.
staticintpci_cdev_add(structpci_cdev
pci_cdev[],intsize,structpci_dev*pdev)
89.
{
90.
inti,res=-1;
91.
92.
for(i=0;i<size;i++){
93.
if(pci_cdev[i].pci_dev==NULL){
94.
pci_cdev[i].pci_dev=pdev;
95.
res=pci_cdev[i].minor;
96.
printk(KERN_INFO"RAN:
pci_cdev_add(-pci_cdev-,%i,-dev-)\n",size);
97.
break;
98.
}
99.
}
100.
101.
returnres;
102.
}
103.
104.
staticvoidpci_cdev_del(structpci_cdev
pci_cdev[],intsize,structpci_dev*pdev)
105.
{
106.
inti;
107.
108.
for(i=0;i<size;i++){
109.
if(pci_cdev[i].pci_dev==pdev){
110.
pci_cdev[i].pci_dev=NULL;
111.
printk(KERN_INFO"RAN: pci_cdev_del(pci_cdevm,%i,dev)\n",size);
112.
}
113.
}
114.
}
115.
116.
staticstructpci_dev*pci_cdev_search_pci_dev(structpci_cdev
pci_cdev[],intsize,intminor)
117.
{
118.
inti;
119.
structpci_dev*pdev=NULL;
120.
121.
for(i=0;i<size;i++){
122.
if(pci_cdev[i].minor==minor){
123.
pdev=pci_cdev[i].pci_dev;
124.
break;
125.
printk(KERN_INFO"RAN: pci_cdev_search_pci_dev()\n");
126.
}
127.
}
128.
129.
returnpdev;
130.
}
131.
132.
staticstructcdev*pci_cdev_search_cdev(structpci_cdev
pci_cdev[],intsize,intminor)
133.
{
134.
inti;
135.
structcdev*cdev=NULL;
136.
137.
for(i=0;i<size;i++){
138.
if(pci_cdev[i].minor==minor){
139.
cdev=pci_cdev[i].cdev;
140.
break;
141.
}
142.
}
143.
printk(KERN_INFO"RAN: pci_cdev_search_cdev()\n");
144.
returncdev;
145.
}
146.
147.
/*
148.
-1 => not found
149.
others => found
150.
*/
151.
staticintpci_cdev_search_minor(structpci_cdev pci_cdev[],
152.
intsize,structpci_dev*pdev)
153.
{
154.
inti,minor=-1;
155.
156.
for(i=0;i<size;i++){
157.
if(pci_cdev[i].pci_dev==pdev){
158.
minor=pci_cdev[i].minor;
159.
break;
160.
}
161.
}
162.
printk(KERN_INFO"RAN: pci_cdev_search_minor()\n");
163.
returnminor;
164.
}
165.
166.
167.
168.
/**
169.
* This function is called when the device node is opened
170.
*
171.
*/
172.
staticintpci_open(structinode*inode,structfile*file)
173.
{
174.
intminor=iminor(inode);
175.
file->private_data=(void*)pci_cdev_search_pci_dev(pci_cdev,MAX_DEVICE,minor);
176.
printk(KERN_INFO"RAN: pci_open()\n");
177.
return0;
178.
}
179.
180.
/**
181.
* This function is called when the device node is closed
182.
*
183.
*/
184.
staticintpci_release(structinode*inode,structfile*file)
185.
{
186.
return0;
187.
}
188.
189.
/**
190.
* This function is called when the device node is read
191.
*
192.
*/
193.
staticssize_t pci_read(structfile*file, /* see include/linux/fs.h */
194.
char*buffer, /* buffer to fill with data */
195.
size_tlength,/* length of the buffer */
196.
loff_t*offset)
197.
{
198.
intbyte_read=0;
199.
unsignedcharvalue;
200.
structpci_dev*pdev=(structpci_dev*)file->private_data;
201.
unsignedlongpci_io_addr=0;
202.
203.
pci_io_addr=pci_resource_start(pdev,BAR_IO);
204.
205.
while(byte_read<length){
206.
/* read a byte from the input */
207.
value=inb(pci_io_addr+1);
208.
209.
/* write the value in the user buffer */
210.
put_user(value,&buffer[byte_read]);
211.
212.
byte_read++;
213.
}
214.
printk(KERN_INFO"RAN: pci_read()\n");
215.
returnbyte_read;
216.
}
217.
218.
/**
219.
* This function is called when the device node is read
220.
*
221.
*/
222.
staticssize_t
pci_write(structfile*filp,constchar*buffer,size_tlen,loff_t*off){
223.
inti;
224.
unsignedcharvalue;
225.
structpci_dev*pdev=(structpci_dev*)filp->private_data;
226.
unsignedlongpci_reg_mem_addr=0lu;
227.
unsignedlongpci_photo_mem_addr=0lu;
228.
unsignedintdma_mask=1;
229.
inttest=2;
230.
constchar*MemRegionName=NULL;
231.
//uint32_t *NEW;
232.
//MemRegionName = (const char*)malloc(sizeof(const char));
233.
printk(KERN_INFO"RAN: pci_write()\n");
234.
pci_reg_mem_addr=pci_resource_start(pdev,BAR_SETTINGS);
235.
pci_photo_mem_addr=pci_resource_start(pdev,BAR_PHOTO_MEM);
236.
printk(KERN_INFO"Device VendorID = %x , DeviceID =
%x",pdev->vendor,pdev->device);
237.
printk(KERN_INFO"DATA WRITTEN TO DEVICE:");
238.
for(i=0;i<len;i++){
239.
/* read value on the buffer */
240.
value=(unsignedchar)buffer[i];
241.
printk(KERN_INFO"%c",value);
242.
/* write data to the device */
243.
outb(pci_reg_mem_addr+2,value);
244.
245.
}
246.
247.
248.
if((test=(pci_set_dma_mask(pdev,dma_mask)))<0)
249.
{
250.
printk(KERN_INFO"PCI device failed DMA support test returned
%u\n",test);
251.
}
252.
else
253.
{
254.
printk(KERN_INFO"PCI Dev supports DMA\n");
255.
}
256.
257.
258.
259.
if((test=(pci_request_region(pdev,BAR_PHOTO_MEM,MemRegionName)))!=0)
260.
{
261.
printk(KERN_INFO"request region failed: returned %u\n",test);
262.
}
263.
else
264.
{
265.
printk(KERN_INFO"Request region success!\n");
266.
}
267.
268.
//NEW = (uint32_t
*)mmap(0,0x7fffff,MAP_SHARED,0,"/dev/FGpci",BAR_PHOTO_MEM);
269.
270.
test=check_mem_region(pci_photo_mem_addr,0x7ffffe);
271.
printk(KERN_INFO"Region check returned %x\n",test);
272.
outb(pci_reg_mem_addr+4,0b00000111);
273.
outb(pci_reg_mem_addr+5,0b00000001);
274.
//prototype pci_resource_start(*pdev,BAR);
275.
printk("BAR_PHOTO_MEM Starts at 0x%x and len is
0x%x",pci_resource_start(pdev,BAR_PHOTO_MEM),pci_resource_len(pdev,BAR_PHOTO_MEM));
276.
277.
printk(KERN_INFO"\n");
278.
printk(KERN_INFO"CHILD: pci_reg_mem_addr = %lx\n",pci_reg_mem_addr);
279.
printk(KERN_INFO"CHILD: pci_photo_mem_addr = %lx\n",pci_photo_mem_addr);
280.
printk(KERN_INFO"CHILD: pci_reg_mem_addr+4 = %lx ||
pci_reg_mem_addr+5 = %lx\n",
281.
(pci_reg_mem_addr+4),(pci_reg_mem_addr+5));
282.
outb(pci_reg_mem_addr+5,0b00000000);
283.
returnlen;
284.
}
285.
286.
/**
287.
* This structure holds informations about the pci node
288.
*
289.
*/
290.
staticstructfile_operations pci_ops={
291.
.owner =THIS_MODULE,
292.
.read=pci_read,
293.
.write=pci_write,
294.
.open=pci_open,
295.
.release=pci_release
296.
};
297.
298.
299.
/**
300.
* This function is called when a new pci device is associated with
a driver
301.
*
302.
* return: 0 => this driver don't handle this device
303.
* 1 => this driver handle this device
304.
*
305.
*/
306.
staticintpci_probe(structpci_dev*dev,conststructpci_device_id*id)
307.
{
308.
intret,minor;
309.
structcdev*cdev;
310.
dev_t devno;
311.
312.
/* add this pci device in pci_cdev */
313.
if((minor=pci_cdev_add(pci_cdev,MAX_DEVICE,dev))<0)
314.
gotoerror;
315.
316.
/* compute major/minor number */
317.
devno=MKDEV(major,minor);
318.
319.
/* allocate struct cdev */
320.
cdev=cdev_alloc();
321.
322.
/* initialise struct cdev */
323.
cdev_init(cdev,&pci_ops);
324.
cdev->owner=THIS_MODULE;
325.
326.
/* register cdev */
327.
ret=cdev_add(cdev,devno,1);
328.
if(ret<0){
329.
dev_err(&(dev->dev),"Can't register character device\n");
330.
gotoerror;
331.
}
332.
pci_cdev[minor].cdev=cdev;
333.
334.
dev_info(&(dev->dev),"%s The major device number is %d (%d).\n",
335.
"Registeration is a success",MAJOR(devno),MINOR(devno));
336.
dev_info(&(dev->dev),"If you want to talk to the device driver,\n");
337.
dev_info(&(dev->dev),"you'll have to create a device file.\n");
338.
dev_info(&(dev->dev),"We suggest you use:\n");
339.
dev_info(&(dev->dev),"mknod %s c %d
%d\n",DEVICE_NAME,MAJOR(devno),MINOR(devno));
340.
dev_info(&(dev->dev),"The device file name is important, because\n");
341.
dev_info(&(dev->dev),"the ioctl program assumes that's the\n");
342.
dev_info(&(dev->dev),"file you'll use.\n");
343.
344.
/* enable the device */
345.
pci_enable_device(dev);
346.
347.
/* 'alloc' IO to talk with the card */
348.
if(pci_request_region(dev,BAR_PHOTO_MEM,"MEM-pci")==0){
349.
dev_err(&(dev->dev),"Can't request BAR2\n");
350.
cdev_del(cdev);
351.
gotoerror;
352.
}
353.
354.
/* check that BAR_IO is *really* IO region */
355.
if((pci_resource_flags(dev,BAR_PHOTO_MEM)&IORESOURCE_MEM)!=IORESOURCE_MEM){
356.
dev_err(&(dev->dev),"BAR2 isn't an IO region\n");
357.
cdev_del(cdev);
358.
gotoerror;
359.
}
360.
361.
362.
return1;
363.
364.
error:
365.
return0;
366.
}
367.
368.
/**
369.
* This function is called when the driver is removed
370.
*
371.
*/
372.
staticvoidpci_remove(structpci_dev*dev)
373.
{
374.
intminor;
375.
structcdev*cdev;
376.
377.
/* remove associated cdev */
378.
minor=pci_cdev_search_minor(pci_cdev,MAX_DEVICE,dev);
379.
cdev=pci_cdev_search_cdev(pci_cdev,MAX_DEVICE,minor);
380.
if(cdev!=NULL)
381.
cdev_del(cdev);
382.
383.
/* remove this device from pci_cdev */
384.
pci_cdev_del(pci_cdev,MAX_DEVICE,dev);
385.
386.
/* release the IO region */
387.
pci_release_region(dev,BAR_IO);
388.
}
389.
390.
/**
391.
* This structure holds informations about the pci driver
392.
*
393.
*/
394.
staticstructpci_driver pci_driver={
395.
.name="pci",
396.
.id_table=pci_ids,
397.
.probe=pci_probe,
398.
.remove=pci_remove,
399.
};
400.
401.
402.
/**
403.
* This function is called when the module is loaded
404.
*
405.
*/
406.
staticint__init pci_init_module(void)
407.
{
408.
intret;
409.
410.
printk(KERN_DEBUG"Module pci init\n");
411.
412.
/* allocate (several) major number */
413.
ret=alloc_chrdev_region(&devno,0,MAX_DEVICE,"buffer");
414.
if(ret<0){
415.
printk(KERN_ERR"Can't get major\n");
416.
returnret;
417.
}
418.
419.
/* get major number and save it in major */
420.
major=MAJOR(devno);
421.
422.
/* initialise pci_cdev */
423.
pci_cdev_init(pci_cdev,MAX_DEVICE,MINOR(devno));
424.
425.
/* register pci driver */
426.
ret=pci_register_driver(&pci_driver);
427.
if(ret<0){
428.
/* free major/minor number */
429.
unregister_chrdev_region(devno,1);
430.
431.
printk(KERN_ERR"pci-driver: can't register pci driver\n");
432.
returnret;
433.
}
434.
435.
436.
return0;
437.
}
438.
439.
/**
440.
* This function is called when the module is unloaded
441.
*
442.
*/
443.
staticvoidpci_exit_module(void)
444.
{
445.
inti;
446.
447.
/* unregister pci driver */
448.
pci_unregister_driver(&pci_driver);
449.
450.
/* unregister character device */
451.
for(i=0;i<MAX_DEVICE;i++){
452.
if(pci_cdev[i].pci_dev!=NULL){
453.
cdev_del(pci_cdev[i].cdev);
454.
}
455.
}
456.
457.
/* free major/minor number */
458.
unregister_chrdev_region(devno,MAX_DEVICE);
459.
460.
printk(KERN_DEBUG"Module pci exit\n");
461.
}
462.
463.
module_init(pci_init_module);
464.
module_exit(pci_exit_module);
[/CODE]
Here is my output on " tail -f /var/log/kern.log "
1.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879644] Module pci init
2.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879659] RAN:
pci_dev_init(-pci_cdev-,8,0)
3.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879663] RAN:
pci_dev_init(-pci_cdev-,8,1)
4.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879667] RAN:
pci_dev_init(-pci_cdev-,8,2)
5.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879670] RAN:
pci_dev_init(-pci_cdev-,8,3)
6.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879673] RAN:
pci_dev_init(-pci_cdev-,8,4)
7.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879677] RAN:
pci_dev_init(-pci_cdev-,8,5)
8.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879680] RAN:
pci_dev_init(-pci_cdev-,8,6)
9.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879683] RAN:
pci_dev_init(-pci_cdev-,8,7)
10.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879742] RAN:
pci_cdev_add(-pci_cdev-,8,-dev-)
11.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879754] pci
0000:02:05.0: Registeration is a success The major device number is
250 (0).
12.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879760] pci
0000:02:05.0: If you want to talk to the device driver,
13.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879765] pci
0000:02:05.0: you'll have to create a device file.
14.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879769] pci
0000:02:05.0: We suggest you use:
15.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879775] pci
0000:02:05.0: mknod FGpci c 250 0
16.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879780] pci
0000:02:05.0: The device file name is important, because
17.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879785] pci
0000:02:05.0: the ioctl program assumes that's the
18.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879790] pci
0000:02:05.0: file you'll use.
19.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879807] pci
0000:02:05.0: BAR 3: can't reserve [mem 0xe0800000-0xe0ffffff]
20.
Dec 10 09:00:49 dcam-desktop kernel: [ 2228.879813] pci
0000:02:05.0: Driver probe function unexpectedly returned 1
21.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073319] RAN: pci_open()
22.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073360] RAN: pci_write()
23.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073365] Device VendorID
= 10b5 , DeviceID = 9054
24.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073368] DATA WRITTEN TO
DEVICE:w
25.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073374] ri
26.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073381] te
27.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073387]
28.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073392] PCI device
failed DMA support test returned 4294967291
29.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073411] pci
0000:02:05.0: BAR 3: can't reserve [mem 0xe0800000-0xe0ffffff]
30.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073415] request region
failed: returned 4294967280
31.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073419] Region check
returned fffffff0
32.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073425] BAR_PHOTO_MEM
Starts at 0xe0800000 and len is 0x0
33.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073427]
34.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073431] CHILD:
pci_reg_mem_addr = e0201000
35.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073434] CHILD:
pci_photo_mem_addr = e0800000
36.
Dec 10 09:00:53 dcam-desktop kernel: [ 2233.073438] CHILD:
pci_reg_mem_addr+4 = e0201004 || pci_reg_mem_addr+5 = e0201005
37.
Dec 10 09:20:35 dcam-desktop kernel: [ 3414.852735] e100
0000:02:08.0 eth0: NIC Link is Up 100 Mbps Full Duplex
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20141210/8bfface8/attachment-0001.html
More information about the Kernelnewbies
mailing list