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;
}TSStreamPci;
/* 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 */
ioctl(dsphandle,PPC2DSP_CONSISTENT_COPY_TO_KERNEL,¤tstream);
/* Interrupt the DSP */
WriteToDSP(PacketReady,0x1);
ioctl(dsphandle,PPC2DSP_SET_HDCR,&interrupt);
/* Wait until the DSP acknowledges transfer */
while(ReadFromDSP(PacketReady)){}
/* Read kernel buffer back */
ioctl(dsphandle,PPC2DSP_CONSISTENT_COPY_FROM_KERNEL,¤tstream);
/* 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:
case PPC2DSP_CONSISTENT_COPY_TO_KERNEL:
{
TSStreamPci currentstream;
if(copy_from_user(¤tstream,(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;
}
break;
}
case PPC2DSP_CONSISTENT_COPY_FROM_KERNEL:
{
TSStreamPci currentstream;
if(copy_from_user(¤tstream,(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;
}
break;
}
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 :)
marc.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-dev
mailing list