This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Question on EMIF interface to a CAN Controller Chip



I am trying to get my CAN controller driver going on CS3 0x4000000 in the emif.
 
However when I try and access that memory in the driver i am getting
 
Unable to handle kernel paging request at virtual address 04000000 when i call __raw_readb on that address.
 
I have successfully been able to do request_mem_region and ioremap_nocache calls which is what i think is necessary for this.
 
Any ideas what I might be doing wrong?

  • It sounds like you are on the right track, and I believe that raw_readb should work, but as I understand that is an older format, you may want to try using unsigned int ioread8(void *addr); instead of raw_readb to see if that works or at least prompts a different error, as I understand these functions do additional checking. For reference you may want to take a look at the Accessing I/O Memory portion of chapter 9 of Linux Device Drivers Third Edition.

    Aside from this you may want to double check the address values you are using to ensure that they make sense and you are really accessing what you want to.

  • Please note that before using functions like ioread8 (which should be used instead of readb for new source code), you must first make sure the memory region you are trying to access is allocated and mapped. You can use

    > /proc/iomem

    to see if the memory region has been allocated; as far as mapping is concerned, you may want grep your code and look for calls to corresponding ioremap; otherwise, you may have to call this function yourself prior to using readb or ioread8.

  • I think the request_mem_region does the verification that the region is available, is /proc/iomem also necessary?

  • Bernie,

    FYI, Chapter 9 of LDD3 you cited above suggests request_mem_region is unsafe and should be avoided; I think the /proc/iomem function is the way to go.

  • Juan Gonzales said:

    Bernie,

    FYI, Chapter 9 of LDD3 you cited above suggests request_mem_region is unsafe and should be avoided; I think the /proc/iomem function is the way to go.

    I believe you are thinking of check_mem_region instead of request_mem_region, the book seems to suggest using request_mem_region but goes to say that check_mem_region is old and unsafe, shown on page 249.

  • Thanks for the help.   I figured out what I was doing wrong.  I needed to be using the address returned by ioremap_nocache for these calls.  Instead of the 0x4000000.  Still learning embedded linux or linux for that matter.

     

  • I stand corrected. 

    Please note that you do not want to allocate a memory region (via request_mem_region) if it has already been allocated; hence first, you should use '/proc/iomem' to determine this; if it has not been allocated, then you will need to use 'request_mem_region' to do this.  The next step, would be to ensure the memory has been mapped; unfortunately, there is no easy way I can think of to do this except by searching (using grep command) the Linux kernel source code; again, if this has not been done, then you will need to call ioremap to accomplish this.