Re: kernel q

2003-10-21 Thread Erez Doron
o.k., here is the story:

we are developping a uwb (ultra wide band) network chip.
this should be a wireless 100-500 Mbps with Qos communication chip. ( 
bluetooth and WiFi, beware  ;-)

the prototype i am working on has it's registers and rams mapped as 
memory on a PCI card.

i tried using /dev/mem to access it, but it didn't work.
so i  tried looking at examples and builded my own driver.
i am succesfull at accessing my card as a file. (/dev/uwb/0)
i was not successful at accessing it as mmapped (i can mmap it, 
write/read to/from it, but it does not do the real writing/reading 
to/from the card, and i get no errors either).

the only issue, is that when i do a read or write, even that the length 
of the copy_from_user or copy_to_user is 4 bytes long, it seems to 
read/write more than that
so if i access (read) adress  0xa4, i get the register at 0xa0 
also read. (probably being cached)

arch is x86 (Pentium III)

any idea ?

cheers,
erez.
btw, here are the main code:

static ssize_t uwb_dev_read (struct file *filp, char *buf, size_t count,
loff_t * offp)
{
   unsigned int num=(unsigned int)filp-private_data-1;
   unsigned long p=*offp;
   ssize_t ret = 0;
   int size;
   //printk(KERN_INFO UWB read: addr=%d, len=%d\n,(int)p,(int)count);
   //printk(KERN_INFO UWB num=%d, 
num_boards=%d\n,(int)num,(int)num_boards);
   if (numnum_boards) return -EFAULT;
   if (p(unsigned int)mem_size) return -EFAULT;
   size=MIN(count,(unsigned int)mem_size-p);
   size=MIN(size,4);
   //printk(KERN_INFO UWB read addres 0x%lx..0x%lx ... ,p,p+size-1);
   //printk(KERN_INFO UWB coping to user space\n);
   if (copy_to_user (buf, uwb_mem[num]+p,  size))
return -EFAULT;
   ret=size;
   //printk(KERN_INFO UWB done read\n);
   //printk(%d bytes read \n,ret);
   *offp+=ret;
   return ret;
}

static ssize_t uwb_dev_write(struct file *filp, const char *buf, size_t 
count, loff_t * offp)
{
   unsigned int num=(unsigned int)filp-private_data-1;
   unsigned long p=*offp;
   ssize_t ret = 0;
   int size;

   if (numnum_boards) return -EFAULT;
   if (p(unsigned int)mem_size) return -EFAULT;
   size=MIN(count,(unsigned int)mem_size-p);
   size=MIN(size,4);
   if (copy_from_user (uwb_mem[num]+p, buf, size))
 return -EFAULT;
   ret=size;
   *offp+=ret;
   return ret;
}


static int uwb_dev_mmap(struct file * filp, struct vm_area_struct * vma)
{
   unsigned int num=(unsigned int)filp-private_data-1;
   //unsigned int num=0;
   //unsigned long offset = vma-vm_pgoff  PAGE_SHIFT;
   ssize_t ret = 0;
   unsigned long prot = pgprot_val(vma-vm_page_prot);
   if (boot_cpu_data.x86  3)
   prot |= _PAGE_PCD | _PAGE_PWT;
   vma-vm_page_prot = __pgprot(prot);
   /*
* Accessing memory above the top the kernel knows about or
* through a file pointer that was marked O_SYNC will be
* done non-cached.
*/
   //if (noncached_address(offset) || (file-f_flags  O_SYNC))
//   vma-vm_page_prot = pgprot_noncached(vma-vm_page_prot);
   /* Don't try to swap out physical pages.. */
   vma-vm_flags |= VM_RESERVED;
   /*
* Don't dump addresses that are not real memory to a core file.
*/
/*
   if (offset = __pa(high_memory) || (file-f_flags  O_SYNC))
   vma-vm_flags |= VM_IO;
   */
   vma-vm_flags |= VM_IO;
   if (vma-vm_end-vma-vm_start  mem_size[num]) ret= -EAGAIN;
   else
   if (remap_page_range(vma-vm_start, (unsigned long) uwb_mem[num],
vma-vm_end-vma-vm_start,
vma-vm_page_prot))
   ret= -EAGAIN;
   printk (uwb: mmap, physical_ptr=0x%8X, size=0x%X, uwb num=%d, 
vm_ptr=0x%08X, ret=%d\n,(unsigned int) uwb_mem[num],(unsigned 
int)(vma-vm_end-vma-vm_start),(int)num,(unsigned 
int)vma-vm_start,(unsigned int)ret);
   return ret;
}



/*
* uwb_init_one - look for and attempt to init a single UWB
*/
static int __init uwb_init_one (struct pci_dev *dev, int num)
{
   int rc;
   //u8 hw_status;
   DPRINTK (ENTER\n);

   mem_size[num]=UWB_ADDR_END(dev)-UWB_ADDR(dev)+1;
   uwb_mem[num] = ioremap (UWB_ADDR(dev), mem_size[num]);
   if (uwb_mem[num] == NULL) {
   printk (KERN_ERR UWB cannot ioremap UWB Memory\n);
   DPRINTK (EXIT, returning -EBUSY\n);
   rc = -EBUSY;
   return rc;
   }
   //printk(KERN_INFO UWB found addr 
%lX..%lX\n,UWB_ADDR(dev),UWB_ADDR_END(dev));
   DPRINTK (EXIT, returning 0\n);
   return 0;

}

static int __init uwb_init (void)
{
   int rc=0;
   struct pci_dev *pdev;
   int num=0;
   int i;
   char name[15];
   DPRINTK (ENTER\n);

//  init_MUTEX (uwb_open_sem);

   pci_for_each_dev(pdev) {

Re: kernel q

2003-10-21 Thread Matan Ziv-Av
On Tue, 21 Oct 2003, Erez Doron wrote:

 o.k., here is the story:
 
 we are developping a uwb (ultra wide band) network chip.
 this should be a wireless 100-500 Mbps with Qos communication chip. ( 
 bluetooth and WiFi, beware  ;-)
 
 the prototype i am working on has it's registers and rams mapped as 
 memory on a PCI card.
 
 i tried using /dev/mem to access it, but it didn't work.
 so i  tried looking at examples and builded my own driver.

You did something wrong there, since /dev/mem surely works for PCI MMIO 
regions.

You can look at the kernel module in svgalib for a simple device driver 
that allows mmap to MMIO regions.

 i am succesfull at accessing my card as a file. (/dev/uwb/0)
 i was not successful at accessing it as mmapped (i can mmap it, 
 write/read to/from it, but it does not do the real writing/reading 
 to/from the card, and i get no errors either).
 
 the only issue, is that when i do a read or write, even that the length 
 of the copy_from_user or copy_to_user is 4 bytes long, it seems to 
 read/write more than that
 so if i access (read) adress  0xa4, i get the register at 0xa0 
 also read. (probably being cached)
 
 arch is x86 (Pentium III)
 
 any idea ?

Look at the MTRR setup (cat /proc/mtrr). The default is uncached, so if 
your range is not in any of the MTRRs listed, it is accessed uncached by 
the CPU.

 btw, here are the main code:

 if (numnum_boards) return -EFAULT;
 if (p(unsigned int)mem_size) return -EFAULT;
 size=MIN(count,(unsigned int)mem_size-p);
 size=MIN(size,4);
 //printk(KERN_INFO UWB read addres 0x%lx..0x%lx ... ,p,p+size-1);
 //printk(KERN_INFO UWB coping to user space\n);
 if (copy_to_user (buf, uwb_mem[num]+p,  size))
  return -EFAULT;

I would not use copy to user directly from IO regions, since you should 
access ioremapped regions with readb, readw, readl, rather than pointer 
derefernce.  Try first reading the data, and then copying it to 
userspace. A similar remark holds for the writes, of course. Here's a 
working example from svgalib:

case _IOC_NR(SVGAHELPER_READL):
   copy_from_user(iov,(char *)arg,sizeof(iov));
   iov.val=readl(iov.port);
   copy_to_user((char *)arg,iov,sizeof(iov));
   break;


 static int uwb_dev_mmap(struct file * filp, struct vm_area_struct * vma)
 {
 //if (noncached_address(offset) || (file-f_flags  O_SYNC))
  //   vma-vm_page_prot = pgprot_noncached(vma-vm_page_prot);

Why did you leave out this code? You do want the accesses to be 
uncached.


-- 
Matan Ziv-Av. [EMAIL PROTECTED]


=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: kernel q

2003-10-21 Thread Erez Doron
afaik, /proc/bus/pci/XX/YY is configuration space and not memory space

also:
dd if=/dev/mem skip=physical adress bs=4 count=1 of=filename
does not generate any read cycle to my pci card
cheers,
erez.
Gleb Natapov wrote:

Hello,

On Tue, Oct 21, 2003 at 10:53:54AM +0200, Erez Doron wrote:
 

o.k., here is the story:

we are developping a uwb (ultra wide band) network chip.
this should be a wireless 100-500 Mbps with Qos communication chip. ( 
bluetooth and WiFi, beware  ;-)

the prototype i am working on has it's registers and rams mapped as 
memory on a PCI card.

i tried using /dev/mem to access it, but it didn't work.
so i  tried looking at examples and builded my own driver.
   

The new way of doing it from userspace is by mmapping /proc/bus/pci/XX/YY AFAIK, but 
/dev/mem
works for me. You must be doing something wrong.
--
		Gleb.
 



=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]


Re: kernel q

2003-10-21 Thread Gleb Natapov
On Tue, Oct 21, 2003 at 02:24:19PM +0200, Erez Doron wrote:
 afaik, /proc/bus/pci/XX/YY is configuration space and not memory space
it is configuration space when you read/write it and memory space when you
mmap it. Look up the implementation of mmap for this file in kernel 
(drivers/pci/proc.c)
Newest XFree86 uses this method instead of /dev/mem.

 
 also:
 dd if=/dev/mem skip=physical adress bs=4 count=1 of=filename
 does not generate any read cycle to my pci card
You can't reach PCI address space by reading /dev/mem. Look at 
drivers/char/mem.c:read_mem

/*
 * This funcion reads the *physical* memory. The f_pos points directly to the 
 * memory location. 
 */
static ssize_t read_mem(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned long end_mem;
ssize_t read;
   
end_mem = __pa(high_memory);
if (p = end_mem)
return 0;
^

 
 cheers,
 erez.
 
 
 Gleb Natapov wrote:
 
 Hello,
 
 On Tue, Oct 21, 2003 at 10:53:54AM +0200, Erez Doron wrote:
  
 
 o.k., here is the story:
 
 we are developping a uwb (ultra wide band) network chip.
 this should be a wireless 100-500 Mbps with Qos communication chip. ( 
 bluetooth and WiFi, beware  ;-)
 
 the prototype i am working on has it's registers and rams mapped as 
 memory on a PCI card.
 
 i tried using /dev/mem to access it, but it didn't work.
 so i  tried looking at examples and builded my own driver.

 
 The new way of doing it from userspace is by mmapping /proc/bus/pci/XX/YY 
 AFAIK, but /dev/mem
 works for me. You must be doing something wrong.
 
 --
  Gleb.
  
 
 
 
 
 =
 To unsubscribe, send mail to [EMAIL PROTECTED] with
 the word unsubscribe in the message body, e.g., run the command
 echo unsubscribe | mail [EMAIL PROTECTED]

--
Gleb.

=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



kernel q

2003-10-20 Thread Erez Doron
hi

i am using copy_from_user and copy_to_user functions.
how do i make that physical memory non cached ?
( it seems to write when it wants and read adresses i didnt ask it to read)
cheers,
erez.
=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]


Re: kernel q

2003-10-20 Thread guy keren

On Mon, 20 Oct 2003, Erez Doron wrote:

 i am using copy_from_user and copy_to_user functions.
 how do i make that physical memory non cached ?
 ( it seems to write when it wants and read adresses i didnt ask it to read)

can you explain what do you mean by 'reads when it wants to'? after you
'copy_from_user', your kernel-space buffer does not contain the data that
exists in the user-space buffer? if this is the case - you seem to have
some bug in your code.

the same should be for the writing part, i.e. after 'copy_to_user', the
user-space buffer should contain the desired text.

why do you think caching is your problem, anyway?

also, in what context do you use these functions? a system call? an
interrupt handler?

-- 
guy

For world domination - press 1,
 or dial 0, and please hold, for the creator. -- nob o. dy

=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: kernel q

2003-10-20 Thread Official Flamer/Cabal NON-Leader
Quoth Erez Doron:

 i am using copy_from_user and copy_to_user functions.
 how do i make that physical memory non cached ?

The simplest way is to snarf a block of contiguous memory OUTside the
kernel, export it and write to/read from it somehow (e.g. by mmap, etc).

Cheerio

-- 
---OFCNL
This is MY list. This list belongs to ME! I will flame anyone I want.
Official Flamer/Cabal NON-Leader  [EMAIL PROTECTED]

=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: kernel q

2003-10-20 Thread Muli Ben-Yehuda
On Mon, Oct 20, 2003 at 09:46:48PM +0200, Official Flamer/Cabal NON-Leader wrote:
 Quoth Erez Doron:
 
  i am using copy_from_user and copy_to_user functions.
  how do i make that physical memory non cached ?
 
 The simplest way is to snarf a block of contiguous memory OUTside the
 kernel, export it and write to/read from it somehow (e.g. by mmap,
etc).

Simplest, but it's also considered a fairly ugly hack :P
Erez, what are you trying to do, and on which arch? how to make
physical memory non cached is fairly architecture dependant, AFAIK. 

Cheers, 
Muli 
-- 
Muli Ben-Yehuda
http://www.mulix.org



signature.asc
Description: Digital signature


Re: kernel q

2003-10-20 Thread Official Flamer/Cabal NON-Leader
Quoth Muli Ben-Yehuda:

 Simplest, but it's also considered a fairly ugly hack :P

Ugly, yes. However, when you want performance and wish to avoid caching
(the latter Erez states and the first I interpolate, possibly wrongly)
and, self-admittedly, being much less conversant with optimization than
you ;-) - I suspect he would also want contiguity which, notwithstanding
the kmalloc call's availablity, is, under most real-life circumstances,
an ineffective mechanism vis-a-vis its inability to claim a significant
amount of memory, this being in use by the kernel itself and, therefore,
not available for use for any significant or interesting size, namely -
pretty much anything over a quarter meg, the latter number being the
kernel's limit in any case, as far as I remeber.

If you have parsed the above sentence, please suggest a more elegant
solution and a less inelegant hack.

And yes - it is a hack, but an effective one.

 physical memory non cached is fairly architecture dependant, AFAIK. 

I assume x86, which may be wrong. Erez?

ObLanguage - Ah - verbal contortions. I seem to be the Sir Humphrey of
Linux IL.

-- 
---OFCNL
This is MY list. This list belongs to ME! I will flame anyone I want.
Official Flamer/Cabal NON-Leader  [EMAIL PROTECTED]

=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: kernel q

2003-10-20 Thread Muli Ben-Yehuda
On Mon, Oct 20, 2003 at 10:44:09PM +0200, Official Flamer/Cabal NON-Leader wrote:
 Quoth Muli Ben-Yehuda:
 
  Simplest, but it's also considered a fairly ugly hack :P
 
 Ugly, yes. However, when you want performance and wish to avoid caching
 (the latter Erez states and the first I interpolate, possibly wrongly)
 and, self-admittedly, being much less conversant with optimization than
 you ;-) - I suspect he would also want contiguity which, notwithstanding
 the kmalloc call's availablity, is, under most real-life circumstances,
 an ineffective mechanism vis-a-vis its inability to claim a significant
 amount of memory, this being in use by the kernel itself and, therefore,
 not available for use for any significant or interesting size, namely -
 pretty much anything over a quarter meg, the latter number being the
 kernel's limit in any case, as far as I remeber.
 
 If you have parsed the above sentence, please suggest a more elegant
 solution and a less inelegant hack.

The elegance of a solution depends on how well it answers the
requirements, of course, which are inadequately specified in this
case. Assuming the need for a large contigous chunk of physical
memory, allocating it when the kernel boots up through the usual
facilities (get_free_pages) and exporting it to userspace via mmap on
a device file seems and remap_page_range seem to be the prefered way
to go. In general, the mem=XXX trick is working outside the system,
and thus considered ugly. Any solution that achieves the same goal
while working within the confines of the system, system being the
Linux kernel in this case, scores points on elegance.

vis-a-vis kmalloc's slab allocator's inherent limit of 131702 bytes,
if you need a single physically contigous area larger than the above,
you have several options: use mem=XXX, carve it out of the memory maps
we build during boot (ugly and intrusive), or use alloc_bootmem to
allocate it during boot. This is probably the best way to go with
stock kernels. There's also a patch floating around since 1.3.xx days
called 'bigphysarea' which does pretty much what the name implies, but
it has never been included AFAIK. 

 And yes - it is a hack, but an effective one.

That was never contended, oh wielder-of-the-differential-scsi-cable. 

  physical memory non cached is fairly architecture dependant, AFAIK. 
 
 I assume x86, which may be wrong. Erez?
 
 ObLanguage - Ah - verbal contortions. I seem to be the Sir Humphrey of
 Linux IL.

Oh, said contortions are quite pleasant. Do go on ;-) 

Cheers, 
Muli 
-- 
Muli Ben-Yehuda
http://www.mulix.org



signature.asc
Description: Digital signature