PCI Memory mapping

Marc Leeman marc.leeman at barco.com
Thu Mar 25 01:25:24 EST 2004

This is getting weird, I found a solution to the problem, well kind of.

Let's introduce the major players in this drama:

 /* communication struct between user and kernel space , in driver.h
  * kernel include */
 typedef struct SStreamPci {
         unsigned int pciaddress;
         unsigned int useraddress;
         unsigned char stream;

 /* user space program */
 /* as long as not all data is transferred */
 while(userptr < (userbuffer + (TRANSFER_SIZE>>2))){
   /* currentstream is a struct that is passed to the kernel of
    * type TSStreamPci */
   currentstream.useraddress = (unsigned)userptr;

   /* copy our buffer to the kernel (PCI_TRANSFER_SIZE), 4k */

   /* Interrupt the DSP */

   /* Wait until the DSP acknowledges transfer */

   /* Read kernel buffer back */

   /* increment pointer */
   userptr += (BLOCK_TRANSFER_SIZE >> 2);

The strange thing is that this works only and only if I do a transfer
back from kernel space into the userbuffer AFTER the DSP has
acknowledged transferring the data. Note that this data is never used
again. Doing this copy_to_user before DSP acknowledgement still results
in the afore mentioned data corruption.

The associated ioctls are:
    TSStreamPci currentstream;
    if(copy_from_user(&currentstream,(TSStreamPci*) arg,sizeof(TSStreamPci))){
      return -EFAULT;
    if(copy_from_user(driver_data.device[currentstream.stream]->kern_addr,(char*)currentstream.useraddress, PCI_TRANSFER_SIZE)){
      return -EFAULT;
    TSStreamPci currentstream;
    if(copy_from_user(&currentstream,(TSStreamPci*) arg, sizeof(TSStreamPci))){
      return -EFAULT;
    if(copy_to_user((char*)currentstream.useraddress,driver_data.device[currentstream.stream]->kern_addr, PCI_TRANSFER_SIZE)){
      return -EFAULT;

There is about a 10% bandwith reduction (due to PPC utilisation I would
assume) over the PCI, so I can live with that; but what bothers me is
not knowing _why_, ... Especially since I want my first module not to
contain too large beginners mistakes :)


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

More information about the Linuxppc-dev mailing list