Is it safe to use these Linux function (test_bit(), set_bit(), clear_bit()) in character device driver for 2.6.10 ppc kernel.
Hi all
I am using "test_bit(),set_bit(),clear_bit() etc" API functions provided by the Linux kernel. I want to know that if anybody is used it and have full faith in its operation then please let me know. Driver in the while loop is calling these API's hence i want to make sure that its operation will remain stable.
I need your comments in this regard
Thank you
Misbah
Signature · 2 lines
View this message in context: http://www.nabble.com/Is-it-safe-to-use-these-Linux-function-%28test_bit%28%29%2Cset_bit%28%29%2Cclear_bit%28%29%29-in-character-device-driver-for-2.6.10-ppc-kernel.-tf4527008.html#a12916782 Sent from the linuxppc-embedded mailing list archive at Nabble.com.
Quoted 1 line · Misbah khan
Hi all I am using "test_bit(),set_bit(),clear_bit() etc" API functions provided by the Linux kernel. I want to know that if anybody is used it and have full faith in its operation then please let me know. Driver in the while loop is calling these API's hence i want to make sure that its operation will remain stable.
They're used all over the place. Is there anything about them that you find suspect?
-Scott
Quoted 47 lines · Scott Wood-2 wrote:
Quoted 5 lines · Misbah khan
Hi all I am using "test_bit(),set_bit(),clear_bit() etc" API functions provided by the Linux kernel. I want to know that if anybody is used it and have full faith in its operation then please let me know. Driver in the while loop is calling these API's hence i want to make sure that its operation will remain stable.
They're used all over the place. Is there anything about them that you find suspect?
-Scott
I have devloped a character driver for FPGA which is memory mapped and using these API's to test a bit , set a bit or to clear a bit in the memory for eg :-
/* poll till data is transfered from sdram to dpram */
while((test_bit(DFR_BUSY,(UINT32 *)(\ (void *)mmap_reg_ptr + DATA_STATUS_REG))==1)\ && (delay < MAX_DELAY_BUSY)) { KDEBUG3(" In the Dfr delay loop \n"); mdelay(DELAY); delay+=DELAY; }/* End of while(test_bit(FPGA_BUSY,(void *)register name) */ if(delay==MAX_DELAY_BUSY) { KDEBUG1("Out of the the Dfr busy loop \n"); return -1; }People working for FPGA are sure that they are not making the bit high where in my driver is returning -1 from the kernel space aborting it after running for few minutes or so . Please let me know that This function is stable and i should tell them that the driver is stable in its operation and they should check it from there side.
Misbah
_______________________________________________
Linuxppc-embedded mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-embedded
Signature · 2 lines
View this message in context: http://www.nabble.com/Is-it-safe-to-use-these-Linux-function-%28test_bit%28%29%2Cset_bit%28%29%2Cclear_bit%28%29%29-in-character-device-driver-for-2.6.10-ppc-kernel.-tf4527008.html#a12934517 Sent from the linuxppc-embedded mailing list archive at Nabble.com.
Quoted 29 lines · Misbah khan
Quoted 26 lines · Scott Wood-2 wrote:
Quoted 1 line · Misbah khan
Hi all I am using "test_bit(),set_bit(),clear_bit() etc" API functions provided by the Linux kernel. I want to know that if anybody is used it and have full faith in its operation then please let me know. Driver in the while loop is calling these API's hence i want to make sure that its operation will remain stable.
They're used all over the place. Is there anything about them that you find suspect?
-Scott
I have devloped a character driver for FPGA which is memory mapped and using these API's to test a bit , set a bit or to clear a bit in the memory for eg :-
/* poll till data is transfered from sdram to dpram */
while((test_bit(DFR_BUSY,(UINT32 *)(\ (void *)mmap_reg_ptr + DATA_STATUS_REG))==1)\ && (delay < MAX_DELAY_BUSY)) { KDEBUG3(" In the Dfr delay loop \n"); mdelay(DELAY); delay+=DELAY; }/* End of while(test_bit(FPGA_BUSY,(void *)register name) */ if(delay==MAX_DELAY_BUSY) { KDEBUG1("Out of the the Dfr busy loop \n"); return -1; }
Quoted 6 lines
Quoted 6 lines
People working for FPGA are sure that they are not making the bit high where in my driver is returning -1 from the kernel space aborting it after running for few minutes or so . Please let me know that This function is stable and i should tell them that the driver is stable in its operation and they should check it from there side.
I think a more more likely source of the problem is that the FPGA
pointer is not cast volatile, or perhaps the FPGA is mapped cached and the hardware doesn't always get touched when you think it does. The bit manipulation macros are probably fine.
jeff
Quoted 89 lines · Jeff Mock-2 wrote:
Quoted 35 lines · Misbah khan
Quoted 32 lines · Scott Wood-2 wrote:
Quoted 6 lines · Misbah khan
Hi all I am using "test_bit(),set_bit(),clear_bit() etc" API functions provided by the Linux kernel. I want to know that if anybody is used it and have full faith in its operation then please let me know. Driver in the while loop is calling these API's hence i want to make sure that its
operation will remain stable.They're used all over the place. Is there anything about them that you find suspect?
-Scott
I have devloped a character driver for FPGA which is memory mapped and using these API's to test a bit , set a bit or to clear a bit in the memory for eg :-
/* poll till data is transfered from sdram to dpram */
while((test_bit(DFR_BUSY,(UINT32 *)(\ (void *)mmap_reg_ptr + DATA_STATUS_REG))==1)\ && (delay < MAX_DELAY_BUSY)) { KDEBUG3(" In the Dfr delay loop \n"); mdelay(DELAY); delay+=DELAY; }/* End of while(test_bit(FPGA_BUSY,(void *)register name) */ if(delay==MAX_DELAY_BUSY) { KDEBUG1("Out of the the Dfr busy loop \n"); return -1; }Quoted 7 lines
Quoted 7 lines
People working for FPGA are sure that they are not making the bit high where in my driver is returning -1 from the kernel space aborting it after
running for few minutes or so . Please let me know that This function is stable and i should tell them that the driver is stable in its operation and they should check it from there side.I think a more more likely source of the problem is that the FPGA pointer is not cast volatile, or perhaps the FPGA is mapped cached and the hardware doesn't always get touched when you think it does. The bit manipulation macros are probably fine.
jeff
FPGA is Indeed mapped non cashed here is the part of the code
/* Physical bus memory is mapped */
mmap_reg_ptr=(UINT32 *)ioremap_nocache(PHY_MEM_ADDR,PHY_MEM_SIZE);And is it ok if I caste FPGA pointer volatile like this will reduce the probability of failure
/* poll till data is transfered from sdram to dpram */
while((test_bit(DFR_BUSY,(volatile UINT32 *)(\ (volatile UINT32 *)mmap_reg_ptr + DATA_STATUS_REG))==1)\ && (delay < MAX_DELAY_BUSY)) { KDEBUG3(" In the Dfr delay loop \n"); mdelay(DELAY); delay+=DELAY; }/* End of while(test_bit(FPGA_BUSY,(void *)register name) */ if(delay==MAX_DELAY_BUSY) { KDEBUG1("Out of the the Dfr busy loop \n"); return CASHEL_FAILURE; }__________________
is there anything else that we could do to rely fully in our code.
Misbah
_____________________________
Linuxppc-embedded mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-embedded
Signature · 2 lines
View this message in context: http://www.nabble.com/Is-it-safe-to-use-these-Linux-function-%28test_bit%28%29%2Cset_bit%28%29%2Cclear_bit%28%29%29-in-character-device-driver-for-2.6.10-ppc-kernel.-tf4527008.html#a12937117 Sent from the linuxppc-embedded mailing list archive at Nabble.com.
Quoted 112 lines · Misbah khan
Quoted 106 lines · Jeff Mock-2 wrote:
Quoted 37 lines · Misbah khan
Quoted 34 lines · Scott Wood-2 wrote:
Quoted 8 lines · Misbah khan
Hi all I am using "test_bit(),set_bit(),clear_bit() etc" API functions provided by the Linux kernel. I want to know that if anybody is used it
and have full faith in its operation then please let me know. Driver in
the while loop is calling these API's hence i want to make sure that its
operation will remain stable.They're used all over the place. Is there anything about them that you find suspect?
-Scott
I have devloped a character driver for FPGA which is memory mapped and using these API's to test a bit , set a bit or to clear a bit in the memory for eg :-
/* poll till data is transfered from sdram to dpram */
while((test_bit(DFR_BUSY,(UINT32 *)(\ (void *)mmap_reg_ptr + DATA_STATUS_REG))==1)\ && (delay < MAX_DELAY_BUSY)) { KDEBUG3(" In the Dfr delay loop \n"); mdelay(DELAY); delay+=DELAY; }/* End of while(test_bit(FPGA_BUSY,(void *)register name) */ if(delay==MAX_DELAY_BUSY) { KDEBUG1("Out of the the Dfr busy loop \n"); return -1; }Quoted 9 lines
Quoted 9 lines
People working for FPGA are sure that they are not making the bit high where in my driver is returning -1 from the kernel space aborting it after
running for few minutes or so . Please let me know that This function is
stable and i should tell them that the driver is stable in its operation
and they should check it from there side.I think a more more likely source of the problem is that the FPGA pointer is not cast volatile, or perhaps the FPGA is mapped cached and the hardware doesn't always get touched when you think it does. The bit manipulation macros are probably fine.
jeff
FPGA is Indeed mapped non cashed here is the part of the code
/* Physical bus memory is mapped */
mmap_reg_ptr=(UINT32 *)ioremap_nocache(PHY_MEM_ADDR,PHY_MEM_SIZE);And is it ok if I caste FPGA pointer volatile like this will reduce the probability of failure
/* poll till data is transfered from sdram to dpram */
while((test_bit(DFR_BUSY,(volatile UINT32 *)(\ (volatile UINT32 *)mmap_reg_ptr + DATA_STATUS_REG))==1)\ && (delay < MAX_DELAY_BUSY)) { KDEBUG3(" In the Dfr delay loop \n"); mdelay(DELAY); delay+=DELAY; }/* End of while(test_bit(FPGA_BUSY,(void *)register name) */ if(delay==MAX_DELAY_BUSY) { KDEBUG1("Out of the the Dfr busy loop \n"); return CASHEL_FAILURE; }__________________
is there anything else that we could do to rely fully in our code.
Misbah
MAX_DELAY_BUSYcorresponds to 10 ms .Driver should poll the bit for few micro second at the max and come out .I had earlier tried with
ioread32()andiowrite32()wrapper functions but the output i got is bit swapped hence i went for direct dereferencing the pointer .do you think
in_be32()could be the best approach than direct
dereferencing. And abouttest_bit()function does it looks fine to youMisbah
_____________________________
Linuxppc-embedded mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-embedded
Signature · 2 lines
View this message in context: http://www.nabble.com/Is-it-safe-to-use-these-Linux-function-%28test_bit%28%29%2Cset_bit%28%29%2Cclear_bit%28%29%29-in-character-device-driver-for-2.6.10-ppc-kernel.-tf4527008.html#a12966462 Sent from the linuxppc-embedded mailing list archive at Nabble.com.
First, PLEASE stop quoting your own text. Do not append > in front of the lines you write yourself in the reply. It makes it impossible to tell what parts are new and what are old.
Quoted 7 lines · Misbah khan
Quoted 7 lines
Quoted 7 lines
FPGA is Indeed mapped non cashed here is the part of the code
/* Physical bus memory is mapped */
mmap_reg_ptr=(UINT32 *)ioremap_nocache(PHY_MEM_ADDR,PHY_MEM_SIZE);And is it ok if I caste FPGA pointer volatile like this will reduce the probability of failure
You cannot ever use set_bit/clear_bit to uncacheable memory. Ever. It uses load-reserve/store-conditional, and they are not legal to use to uncacheable memory.
Also, regular ioremap() is by default uncacheable, so it's quite adequate to use in this case, no need to use the _nocache version.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
do you think
in_be32()could be the best approach than direct
dereferencing. And abouttest_bit()function does it looks fine to you
You need to use in_be32() + manipulating the value + out_be32(), yes. Depending on the rest of your driver you might need to protect it with a spinlock, but that's beyond the scope of this question.
-Olof
Quoted 70 lines · Olof Johansson-2 wrote:
First, PLEASE stop quoting your own text. Do not append > in front of the lines you write yourself in the reply. It makes it impossible to tell what parts are new and what are old.
Quoted 8 lines · Misbah khan
Quoted 6 lines
Quoted 6 lines
FPGA is Indeed mapped non cashed here is the part of the code
/* Physical bus memory is mapped */
mmap_reg_ptr=(UINT32 *)ioremap_nocache(PHY_MEM_ADDR,PHY_MEM_SIZE);And is it ok if I caste FPGA pointer volatile like this will reduce
the
Quoted 1 line
Quoted 1 line
probability of failure
You cannot ever use set_bit/clear_bit to uncacheable memory. Ever. It uses load-reserve/store-conditional, and they are not legal to use to uncacheable memory.
Also, regular
ioremap()is by default uncacheable, so it's quite adequate to use in this case, no need to use the_nocacheversion.Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
do you think
in_be32()could be the best approach than direct
dereferencing. And abouttest_bit()function does it looks fine to youYou need to use
in_be32()+ manipulating the value +out_be32(), yes. Depending on the rest of your driver you might need to protect it with a spinlock, but that's beyond the scope of this question.-Olof
I am confused that some people tells me to map the memory noncacheble and some tells me not. could you tell me which is the best approach and please elaborate the reason as well. The part of the code is mentioned above is a reference and my concern are as follows:-
1. I am mapping 32 KB of memory for which i am using
_nocasheble. Is it absolutely fine????2. I am directly dereferencing the pointer to the mapped region insted of using a wrapper function due to (1) Aready used in the past and have faith in it .
(2) I had used functions likeioread32()iowrite32()in the past which
is suggested by rubini in his book on Linux device Driver but the output i got was bitswapped .3. test_bit()/clear_bit() are the functions which i am using in my driver and in the way i described above , please let me know that is looks fine in the Implimention or shall i read the value and mask the bits rather than beliving in these functions for eg :-
dfr_data_ret=*(volatile UINT32 *)((volatile UINT32 *)mmap_reg_ptr+DATA_STATUS_REG);
dfr_data_ret&=STATUS_MASK;
Please reply to clear my doubts.
Misbah
_______________________________________________
Linuxppc-embedded mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-embedded
Signature · 2 lines
View this message in context: http://www.nabble.com/Is-it-safe-to-use-these-Linux-function-%28test_bit%28%29%2Cset_bit%28%29%2Cclear_bit%28%29%29-in-character-device-driver-for-2.6.10-ppc-kernel.-tf4527008.html#a12973587 Sent from the linuxppc-embedded mailing list archive at Nabble.com.
Quoted 5 lines · Misbah khan
Quoted 4 lines · Olof Johansson-2 wrote:
First, PLEASE stop quoting your own text. Do not append > in front of the lines you write yourself in the reply. It makes it impossible to tell what parts are new and what are old.
Please read the above again, since you didn't fix your mailer.
Also, make sure it doesn't prepend spaces in front of the lines you are writing.
Quoted 4 lines
Quoted 4 lines
I am confused that some people tells me to map the memory noncacheble and some tells me not. could you tell me which is the best approach and please elaborate the reason as well. The part of the code is mentioned above is a reference and my concern are as follows:-
It depends on your application and how the FPGA is attached. Buf if it is attached outside of the coherence domain (for example on PCI), then you should map it uncacheable. Otherwise you will have to do manual flushing of caches to make sure writes make it out to the device, and also flush any copy in cache before you read any register. In other words, it makes things considerably more complicated and error-prone.
Quoted 2 lines
Quoted 2 lines
1. I am mapping 32 KB of memory for which i am using
_nocasheble. Is it absolutely fine????
Just use ioremap().
Quoted 3 lines
Quoted 3 lines
2. I am directly dereferencing the pointer to the mapped region insted of using a wrapper function due to (1) Aready used in the past and have faith in it .
I don't care if you have faith in it or not, it's still not the correct way to do it. It might work right some of the time by pure luck but it is the incorrect way of accessing device memory.
Quoted 3 lines
Quoted 3 lines
(2) I had used functions like
ioread32()iowrite32()in the past which
is suggested by rubini in his book on Linux device Driver but the output i got was bitswapped .
I assume you mean byte swapped and not bit swapped.
Are your registers on the device big- or little endian?
If they are big endian, use in_be32/out_be32. If they're little endian, use in_le32/out_le32. That will take care of any swapping for you.
Quoted 3 lines
Quoted 3 lines
3. test_bit()/clear_bit() are the functions which i am using in my driver and in the way i described above , please let me know that is looks fine in the Implimention
No it is not fine. You cannot use set_bit/clear_bit against noncacheable memory. EVER.
Quoted 9 lines
Quoted 9 lines
or shall i read the value and mask the bits rather
than beliving in these functions for eg :-dfr_data_ret=*(volatile UINT32 *)((volatile UINT32 *)mmap_reg_ptr+DATA_STATUS_REG);
dfr_data_ret&=STATUS_MASK;
Please reply to clear my doubts.
Just do what I told you earlier:
To read the status register, mask out the STATUS_MASK and write it back, do:
val = in_be32(mmap_reg_ptr + DATA_STATUS_REG);
val &= STATUS_MASK;out_be32(MMAP_REG_PTR + DATA_STATUS_REG, val);
-Olof
Hi ...
I did followed you and it worked as well. I really Thank you for it.
At one Place i am doing memcpy() of floating point data to the memory mapped registers, what could be the substitute of it like "memcpy_toio() " which is suggested in the Book. I am working BE architecture.
I would really appreaciate if you would let me know the defineation of these wrapper functions (in_be32,out_be32(),ioread32(),iowrite32(),etc) so that i could have the clear idea of the reason for not directly dreferencing the Pointer.
Misbah
Quoted 94 lines · Olof Johansson-2 wrote:
Quoted 5 lines · Misbah khan
Quoted 4 lines · Olof Johansson-2 wrote:
First, PLEASE stop quoting your own text. Do not append > in front of the lines you write yourself in the reply. It makes it impossible to tell what parts are new and what are old.
Please read the above again, since you didn't fix your mailer.
Also, make sure it doesn't prepend spaces in front of the lines you are writing.
Quoted 7 lines
Quoted 1 line
I am confused that some people tells me to map the memory noncacheble
and
Quoted 1 line
some tells me not. could you tell me which is the best approach and
please
Quoted 1 line
elaborate the reason as well. The part of the code is mentioned above
is a
Quoted 1 line
reference and my concern are as follows:-
It depends on your application and how the FPGA is attached. Buf if it is attached outside of the coherence domain (for example on PCI), then you should map it uncacheable. Otherwise you will have to do manual flushing of caches to make sure writes make it out to the device, and also flush any copy in cache before you read any register. In other words, it makes things considerably more complicated and error-prone.
Quoted 2 lines
Quoted 2 lines
1. I am mapping 32 KB of memory for which i am using
_nocasheble. Is it absolutely fine????Just use
ioremap().Quoted 5 lines
Quoted 1 line
2. I am directly dereferencing the pointer to the mapped region insted
of
Quoted 1 line
using a wrapper function due to (1) Aready used in the past and have
faith
Quoted 1 line
in it .
I don't care if you have faith in it or not, it's still not the correct way to do it. It might work right some of the time by pure luck but it is the incorrect way of accessing device memory.
Quoted 5 lines
Quoted 1 line
(2) I had used functions like
ioread32()iowrite32()in the pastwhich
Quoted 1 line
is suggested by rubini in his book on Linux device Driver but the
output i
Quoted 1 line
got was bitswapped .
I assume you mean byte swapped and not bit swapped.
Are your registers on the device big- or little endian?
If they are big endian, use in_be32/out_be32. If they're little endian, use
in_le32/out_le32. That will take care of any swapping for you.Quoted 5 lines
Quoted 1 line
3. test_bit()/clear_bit() are the functions which i am using in my
driver
Quoted 1 line
and in the way i described above , please let me know that is looks
fine
Quoted 1 line
in the Implimention
No it is not fine. You cannot use set_bit/clear_bit against noncacheable memory. EVER.
Quoted 9 lines
Quoted 9 lines
or shall i read the value and mask the bits rather
than beliving in these functions for eg :-dfr_data_ret=*(volatile UINT32 *)((volatile UINT32 *)mmap_reg_ptr+DATA_STATUS_REG);
dfr_data_ret&=STATUS_MASK;
Please reply to clear my doubts.
Just do what I told you earlier:
To read the status register, mask out the
STATUS_MASKand write it back, do:val =
in_be32(mmap_reg_ptr + DATA_STATUS_REG);
val &=STATUS_MASK;out_be32(MMAP_REG_PTR + DATA_STATUS_REG, val);-Olof
_______________________________________________
Linuxppc-embedded mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-embedded
Signature · 2 lines
View this message in context: http://www.nabble.com/Is-it-safe-to-use-these-Linux-function-%28test_bit%28%29%2Cset_bit%28%29%2Cclear_bit%28%29%29-in-character-device-driver-for-2.6.10-ppc-kernel.-tf4527008.html#a13039401 Sent from the linuxppc-embedded mailing list archive at Nabble.com.
Quoted 4 lines · Misbah khan
Hi ...
I did followed you and it worked as well. I really Thank you for it.
Quoted 8 lines
At one Place i am doing
memcpy()of floating point data to the memory mapped registers, what could be the substitute of it like "memcpy_toio()" which is suggested in the Book. I am working BE architecture.I would really appreaciate if you would let me know the defineation of these wrapper functions (in_be32,out_be32(),ioread32(),iowrite32(),etc) so that i could have the clear idea of the reason for not directly dreferencing the Pointer.
You don't want to directly dereference pointers to device registers because you don't want the processor or compiler to reorder your register accesses. The in/out_* wrappers keeps the compiler from reordering things, and the wrappers contain the 'sync' instruction which prevents the processor from reordering operations at runtime.
g.
Signature · 4 lines
Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd. [email protected] (403) 399-0195
Quoted 10 lines · Misbah khan
Quoted 7 lines · Scott Wood-2 wrote:
They're used all over the place. Is there anything about them that you find suspect?
-Scott
I have devloped a character driver for FPGA which is memory mapped and using these API's to test a bit , set a bit or to clear a bit in the memory for eg :-
Please don't use quote markers on newly added text.
Quoted 4 lines
Quoted 4 lines
/* poll till data is transfered from sdram to dpram */
while((test_bit(DFR_BUSY,(UINT32 *)(\ (void *)mmap_reg_ptr + DATA_STATUS_REG))==1)\ && (delay < MAX_DELAY_BUSY))
You should use in_be32() rather than direct dereferencing.
Quoted 12 lines
Quoted 12 lines
{ KDEBUG3(" In the Dfr delay loop \n"); mdelay(DELAY); delay+=DELAY; }/* End of while(test_bit(FPGA_BUSY,(void *)register name) */ if(delay==MAX_DELAY_BUSY) { KDEBUG1("Out of the the Dfr busy loop \n"); return -1; }
Quoted 3 lines
Quoted 3 lines
People working for FPGA are sure that they are not making the bit high where in my driver is returning -1 from the kernel space aborting it after running for few minutes or so .
I don't suppose the "few minutes" corresponds to MAX_DELAY_BUSY?
-Scott