linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Olivier Galibert <galibert@pobox.com>
To: linux-kernel@vger.kernel.org
Subject: Re: [GIT PATCH] more Driver core patches for 2.6.19
Date: Thu, 14 Dec 2006 20:16:29 +0100	[thread overview]
Message-ID: <20061214191629.GA68100@dspnet.fr.eu.org> (raw)
In-Reply-To: <200612141345.18103.hjk@linutronix.de>

[-- Attachment #1: Type: text/plain, Size: 2665 bytes --]

On Thu, Dec 14, 2006 at 01:45:16PM +0100, Hans-Jürgen Koch wrote:
> What you suggest is not a "small kernel module". It's what we have now,
> writing a complete driver.

Who says a complete driver has to be big?


> That's what UIO does, plus some standard sysfs files, that tell you e.g.
> the size of the cards memory you can map. There are standard file names
> that allow you e.g. to automatically search for all registered uio 
> drivers and their properties.

Which makes the userspace code much more complex than needed.


> If the card already has that data in its dual port RAM, you do an
> unneccessary copy.

Unnecessary only if
  [card data rate]*[maximum userspace latency] < [dual port ram size].

Doing the buffering in the kernel where it belongs changes the right
part of the equation to [buffer size], which can be orders of
magnitude way bigger.  And you can have the card DMA into the buffer
directly if you feel like it.


> > - implements a read interface to read data from the buffer
> 
> Here you do the next unneccessary copy.

You can mmap, you can splice(), none is really hard.


> > - implement ioctls for whatever controls you need
> 
> Implementing ioctls for everything is bad coding style and a has bad
> performance.

I thought the ALSA guys always said their stuff was high performance?

In any case, if ioctl is too slow for your controls, it means that
your ioctls are too low level, as in register access instead of
"reboot card at address x".  And uio, with its lack of protection
against wandering interrupts, can't cut it.


> I said "high-end AD card", that means you have a 
> signal processor on that board, want to download firmware to it 
> and so on. You end up copying lots of data between user space
> and kernel space.

You're allowed to implement write() too.


> Yes, that's a complete kernel driver that you'd never get into
> a mainline kernel. Furthermore, the card manufacturer would have to
> employ at least two experienced Linux _kernel_ programmers. That's
> too much for a small company who's business is something different.

So they have a choice between learning a minimum of linux kernel
internals, or a minimum of uio.  I suspect the hidden kinks of uio and
relative lack of documentation make the kernel route *way* easier.


> You can achieve 100 lines with uio, including sysfs and poll. What you
> describe would never fit in 200 lines for a non-trivial card.

Ok, 200 is an exaggeration.  Here is a 600-lines 2.4 driver that does
what I say, with direct dma to the internal buffer from the card and
userland-driven firmware upload.  I know that a 2.6 version would
actually be smaller.

  OG.


[-- Attachment #2: iiadc64.c --]
[-- Type: text/x-csrc, Size: 14658 bytes --]

//========================= Official Notice ===============================
//
// "This software was developed at the National Institute of Standards
// and Technology by employees of the Federal Government in the course of
// their official duties. Pursuant to Title 17 Section 105 of the United
// States Code this software is not subject to copyright protection and
// is in the public domain.
//
// The NIST Data Flow System (NDFS) is an experimental system and is
// offered AS IS. NIST assumes no responsibility whatsoever for its use
// by other parties, and makes no guarantees and NO WARRANTIES, EXPRESS
// OR IMPLIED, about its quality, reliability, fitness for any purpose,
// or any other characteristic.
//
// We would appreciate acknowledgement if the software is used.
//
// This software can be redistributed and/or modified freely provided
// that any derivative works bear some notice that they are derived from
// it, and any modified versions bear some notice that they have been
// modified from the original."
//
//=========================================================================




#include <linux/version.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/pci.h>
#include <linux/signal.h>
#include <asm/io.h>
#include <linux/ioport.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <linux/sched.h>
#include <asm/segment.h>
#include <linux/types.h>
#include <linux/wrapper.h>
#include <linux/interrupt.h>
#include <linux/kmod.h>
#include <linux/vmalloc.h>
#include <linux/init.h>

#include "iiadc64.h"

#define DEBUG_AL(format, a...) printk(KERN_WARNING format, ##a)
#define DEBUG_ER(format, a...) printk(KERN_WARNING format, ##a)
#define DEBUG_WR(format, a...) printk(KERN_WARNING format, ##a)
#define DEBUG_IN(format, a...) printk(KERN_WARNING format, ##a)
#define DEBUG_TR(format, a...) printk(KERN_WARNING format, ##a)

enum{ MODE_MEMORY, MODE_RING, MODE_MAILBOX };
enum{ RING_SIZE = 4096*4096 };

static int iiadc64_open(struct inode *, struct file *);
static int iiadc64_release(struct inode *, struct file *);
static int iiadc64_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
static ssize_t iiadc64_read(struct file *, char *, size_t, loff_t *);
static ssize_t iiadc64_write(struct file *, const char *, size_t, loff_t *);

static struct file_operations iiadc64_fops = {
  open:    iiadc64_open,
  release: iiadc64_release,
  ioctl:   iiadc64_ioctl,
  read:    iiadc64_read,
  write:   iiadc64_write
};

struct iiadc64_state {
  struct pci_dev *dev;
  unsigned long iobase;
  unsigned int irq;
  unsigned char  *memory;
  int access_mode, access_mbox;
  int irqen;
  int irqtick;
  int ring_rpos, ring_wpos;
  int dropouts;
  spinlock_t lock;

#if LINUX_VERSION_CODE >= 0x20300
  wait_queue_head_t ring_wait;
#else
  struct wait_queue *ring_wait;
#endif
} is;


/* [DaveM] I've recoded most of this so that:
 * 1) It's easier to tell what is happening
 * 2) It's more portable, especially for translating things
 *    out of vmalloc mapped areas in the kernel.
 * 3) Less unnecessary translations happen.
 *
 * The code used to assume that the kernel vmalloc mappings
 * existed in the page tables of every process, this is simply
 * not guarenteed.  We now use pgd_offset_k which is the
 * defined way to get at the kernel page tables.
 */

/* Given PGD from the address space's page table, return the kernel
 * virtual mapping of the physical memory mapped at ADR.
 */
static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
{
  unsigned long ret = 0UL;
  pmd_t *pmd;
  pte_t *ptep, pte;
  
  if (!pgd_none(*pgd)) {
    pmd = pmd_offset(pgd, adr);
    if (!pmd_none(*pmd)) {
      ptep = pte_offset(pmd, adr);
      pte = *ptep;
      if(pte_present(pte)) {
	ret  = (unsigned long) page_address(pte_page(pte));
	ret |= (adr & (PAGE_SIZE - 1));
				
      }
    }
  }
  return ret;
}

static inline unsigned long uvirt_to_bus(unsigned long adr) 
{
  unsigned long kva, ret;

  kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
  ret = virt_to_bus((void *)kva);
  return ret;
}

static inline unsigned long kvirt_to_bus(unsigned long adr) 
{
  unsigned long va, kva, ret;

  va = VMALLOC_VMADDR(adr);
  kva = uvirt_to_kva(pgd_offset_k(va), va);
  ret = virt_to_bus((void *)kva);
  return ret;
}

/* Here we want the physical address of the memory.
 * This is used when initializing the contents of the
 * area and marking the pages as reserved.
 */
static inline unsigned long kvirt_to_pa(unsigned long adr) 
{
  unsigned long va, kva, ret;

  va = VMALLOC_VMADDR(adr);
  kva = uvirt_to_kva(pgd_offset_k(va), va);
  ret = __pa(kva);
  return ret;
}

static void * rvmalloc(signed long size)
{
  void * mem;
  unsigned long adr, page;

  mem=vmalloc_32(size);
  if (mem) 
    {
      memset(mem, 0, size); /* Clear the ram out, no junk to the user */
      adr=(unsigned long) mem;
      while (size > 0) 
	{
	  page = kvirt_to_pa(adr);
	  mem_map_reserve(virt_to_page(__va(page)));
	  adr+=PAGE_SIZE;
	  size-=PAGE_SIZE;
	}
    }
  return mem;
}

static void rvfree(void * mem, signed long size)
{
  unsigned long adr, page;
        
  if (mem) 
    {
      adr=(unsigned long) mem;
      while (size > 0) 
	{
	  page = kvirt_to_pa(adr);
	  mem_map_unreserve(virt_to_page(__va(page)));
	  adr+=PAGE_SIZE;
	  size-=PAGE_SIZE;
	}
      vfree(mem);
    }
}

static unsigned int iiadc64_mailbox_read(int box)
{
  int counter = 100000;
  int mask = 0xf0000 << (box*4);
  while(!(inl(is.iobase + 0x34) & mask) && (--counter));
  if(!counter)
    DEBUG_ER("iiadc64:  Timeout on mailbox %d read\n", box);
  return inl(is.iobase + 0x10 + 4*box);
}

static int iiadc64_mailbox_check_read(int box)
{
  int mask = 0xf0000 << (box*4);
  return (inl(is.iobase + 0x34) & mask) != 0;
}

static void iiadc64_mailbox_write(int box, unsigned int data)
{
  int counter = 100000;
  int mask = 0xf << box;
  while((inl(is.iobase + 0x34) & mask) && (--counter));
  if(!counter)
    DEBUG_ER("iiadc64:  Timeout on mailbox %d write\n", box);
  outl(data, is.iobase + 4*box);
}

static void iiadc64_irq(int irq, void *dev_id, struct pt_regs *regs)
{
  unsigned int istat;
  istat = inl(is.iobase + 0x38);

  if(istat & 0x20000) {
    unsigned int request = iiadc64_mailbox_read(1);

    if(request == 1) {
      spin_lock(&is.lock);
      is.ring_wpos = 0;
      is.ring_rpos = 0;
      is.dropouts = 0;
      spin_unlock(&is.lock);

      iiadc64_mailbox_write(0, 0);
    } else {
      int delta;
      int csize;
      request *= 4096;
      delta = request - is.ring_wpos;
      if(delta < 0)
	delta += RING_SIZE;

      spin_lock(&is.lock);
      csize = is.ring_wpos - is.ring_rpos;
      if(csize < 0)
	csize += RING_SIZE;
      if(csize + delta > RING_SIZE)
	is.dropouts++;

      is.ring_wpos = request;
      is.irqtick++;
      spin_unlock(&is.lock);
      wake_up_interruptible(&is.ring_wait);
    }
  }

  if(istat & 0x800000)
    outl(istat, is.iobase + 0x38);
}

static void iiadc64_reset(void)
{
  unsigned int intcsr;
  unsigned int timeout;
  unsigned int val;

  if(is.irqen)
    intcsr = 0x003f1400;
  else
    intcsr = 0x003f0000;

  outl(intcsr, is.iobase + 0x38);
  outl(0x0f000000, is.iobase + 0x3c);
  timeout = HZ/10;
  do {
    current->state = TASK_INTERRUPTIBLE;
    timeout = schedule_timeout(timeout);
  } while (timeout);
  outl(0x00000000, is.iobase + 0x3c);
  timeout = HZ/5;
  do {
    current->state = TASK_INTERRUPTIBLE;
    timeout = schedule_timeout(timeout);
  } while (timeout);

  if(is.irqen)
    outl(0x00000600, is.iobase + 0x3c);

  val = iiadc64_mailbox_read(0);
  if(val != 0x1f)
    DEBUG_ER("iiadc64: Wrong value in mailbox 0 after reset : %08x\n", val);
  else
    DEBUG_IN("iiadc64: Reset successful\n");

  while(iiadc64_mailbox_check_read(0))
    (void)iiadc64_mailbox_read(0);

  is.ring_rpos = 0;
  is.ring_wpos = 0;
}

static int iiadc64_open(struct inode *inode, struct file *file)
{
  is.access_mode = MODE_MEMORY;
  is.irqtick = 0;
  is.ring_wpos = is.ring_rpos = 0;
  is.dropouts = 0;
  if(request_irq(is.irq, iiadc64_irq, SA_SHIRQ, "iiadc64", &is)) {
    DEBUG_ER("iiadc64: Couldn't get shared irq %d\n", is.irq);
    return -EIO;
  }
  is.irqen = 1;
  iiadc64_reset();
  
  MOD_INC_USE_COUNT;
  return 0;
}

static int iiadc64_release(struct inode *inode, struct file *file)
{
  is.irqen = 0;
  iiadc64_reset();
  free_irq(is.irq, &is);
  
  MOD_DEC_USE_COUNT;
  return 0;
}

static int iiadc64_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param)
{
  switch(cmd) {
  case II_RESET:
    iiadc64_reset();
    break;

  case II_MODE_MEMORY:
    is.access_mode = MODE_MEMORY;
    break;

  case II_MODE_RING:
    is.access_mode = MODE_RING;
    break;

  case II_MODE_MAILBOX: {
    int mbox, err;
    err = get_user(mbox, (int *)param);
    if(err)
      return err;
    if(mbox<0 || mbox>3)
      return -EINVAL;
    
    is.access_mode = MODE_MAILBOX;
    is.access_mbox = mbox;
    break;
  }

  case II_PCI_TABLE: {
    unsigned int adr;
    int err;
    int i;
    err = get_user(adr, (unsigned int *)param);
    if(err)
      return err;

    for(i=0; i<RING_SIZE/4096; i++) {
      iiadc64_mailbox_write(0, 1);
      iiadc64_mailbox_write(0, adr++);
      iiadc64_mailbox_write(0, kvirt_to_bus((unsigned long)is.memory+i*4096));
    }

    break;
  }

  case II_RUN: {
    unsigned int adr;
    int err;
    err = get_user(adr, (unsigned int *)param);
    if(err)
      return err;
	
    iiadc64_mailbox_write(0, 3);
    iiadc64_mailbox_write(0, adr);
    break;
  }

  default:
    return -ENOTTY;
  }
  return 0;
}

static ssize_t iiadc64_read(struct file *file, char *buf, size_t size, loff_t *offset)
{
  switch(is.access_mode) {
  case MODE_MEMORY: {
    size_t cur_size;
    int adr = *offset / 4;
    
    cur_size = size;
    while(cur_size > 0) {
      size_t block_size = cur_size;
      unsigned int *data = (unsigned int *)is.memory;
      size_t cb_size;
      
      if(block_size > PAGE_SIZE)
	block_size = PAGE_SIZE;
      
      cur_size -= block_size;
      cb_size = block_size;
      
      while(cb_size) {
	iiadc64_mailbox_write(0, 2);
	iiadc64_mailbox_write(0, adr++);
	*data++ = iiadc64_mailbox_read(0);
	cb_size -= 4;
      }
      
      if(copy_to_user(buf, (const void *)is.memory, block_size))
	return -EFAULT;
      buf += block_size;
    }
    
    *offset += size;
    return size;
  }
  case MODE_RING: {
    size_t cur_size;
    unsigned long flags;
    int avail, dropouts;

    cur_size = size;
    while(cur_size) {
      size_t block_size;
      spin_lock_irqsave(&is.lock, flags);
      while(is.ring_wpos == is.ring_rpos) {
	spin_unlock_irqrestore(&is.lock, flags);

	interruptible_sleep_on(&is.ring_wait);
	if (signal_pending(current)) {
	  DEBUG_TR("iiadc64: ERESTARTSYS\n");
	  return -ERESTARTSYS;
	}
	spin_lock_irqsave(&is.lock, flags);
      }

      avail = is.ring_wpos - is.ring_rpos;
      spin_unlock_irqrestore(&is.lock, flags);

      if(avail < 0)
	avail += RING_SIZE;

      block_size = cur_size;
      if(block_size > avail)
	block_size = avail;
      if(block_size + is.ring_rpos > RING_SIZE)
	block_size = RING_SIZE - is.ring_rpos;

      if(copy_to_user(buf, (const void *)(is.memory + is.ring_rpos), block_size))
	return -EFAULT;

      spin_lock_irqsave(&is.lock, flags);
      is.ring_rpos += block_size;
      if(is.ring_rpos == RING_SIZE)
	is.ring_rpos = 0;

      dropouts = is.dropouts;
      is.dropouts = 0;
      spin_unlock_irqrestore(&is.lock, flags);

      if(dropouts)
	DEBUG_ER("iiadc64:  Dropout detected\n");

      buf += block_size;
      cur_size -= block_size;
    }
    *offset += size;
    return size;
  }
  case MODE_MAILBOX: {
    size_t cur_size = size;
    for(;;) {
      unsigned int val = iiadc64_mailbox_read(is.access_mbox);
      if(put_user(val, (unsigned int *)buf))
	return -EFAULT;
      buf += sizeof(unsigned int);
      if(cur_size <= sizeof(unsigned int))
	break;
      cur_size -= sizeof(unsigned int);
    }
    *offset += size;
    return size;
  }
  default:
    return -ENOTTY;
  }
}

static ssize_t iiadc64_write(struct file *file, const char *buf, size_t size, loff_t *offset)
{
  switch(is.access_mode) {
  case MODE_MEMORY: {
    size_t cur_size;
    int adr = *offset / 4;
    
    cur_size = size;
    while(cur_size > 0) {
      size_t block_size = cur_size;
      unsigned int *data = (unsigned int *)is.memory;
      
      if(block_size > PAGE_SIZE)
	block_size = PAGE_SIZE;
      
      if(copy_from_user((void *)is.memory, buf, block_size))
	return -EFAULT;
      buf += block_size;
      cur_size -= block_size;
      
      while(block_size) {
	iiadc64_mailbox_write(0, 1);
	iiadc64_mailbox_write(0, adr++);
	iiadc64_mailbox_write(0, *data++);
	block_size -= 4;
      }
    }
    
    *offset += size;
    return size;
  }
  case MODE_MAILBOX: {
    size_t cur_size = size;
    for(;;) {
      unsigned int val;
      if(get_user(val, (unsigned int *)buf))
	return -EFAULT;
      iiadc64_mailbox_write(is.access_mbox, val);
      buf += sizeof(unsigned int);
      if(cur_size <= sizeof(unsigned int))
	break;
      cur_size -= sizeof(unsigned int);
    }
    *offset += size;
    return size;
  }
  default:
    return -ENOTTY;
  }
}


#ifdef MODULE
int init_module(void)
#else
  int iiadc64_init(void)
#endif
{
  DEBUG_AL("IIADC64 minimal kernel driver (c) 1999 Olivier Galibert\n");

  is.dev = pci_find_device(0x10e8, 0x807f, 0);
  if(!is.dev) {
    DEBUG_ER("iiadc64: Unable to find the DSP board\n");
    return -EIO;
  }

#if LINUX_VERSION_CODE >= 0x20400
  if(pci_enable_device(is.dev))
    return -EIO;

  pci_set_master(is.dev);

  is.iobase = pci_resource_start(is.dev, 0);
#else
  is.iobase = is.dev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;
#endif
  is.irq = is.dev->irq;
  is.memory = rvmalloc(RING_SIZE);

  if(!is.memory) {
    DEBUG_ER("iiadc64: Couldn't allocate ring buffer\n");
    return -EIO;
  }

  if (register_chrdev(II_MAJOR, "iiadc64", &iiadc64_fops)) {
    DEBUG_ER("iiadc64: Unable to register character device\n");
    return -EIO;
  }

  DEBUG_IN("iiadc64: DSP board found, io at 0x%lx, irq %u\n", is.iobase, is.irq);

#if LINUX_VERSION_CODE >= 0x20300
  init_waitqueue_head(&is.ring_wait);
#else
  is.ring_wait = 0;
  init_waitqueue(&is.ring_wait);
#endif

  is.lock = SPIN_LOCK_UNLOCKED;

  iiadc64_reset();

  return 0;
}

#ifdef MODULE
void cleanup_module(void)
{
  rvfree(is.memory, RING_SIZE);
  unregister_chrdev(II_MAJOR, "iiadc64");
}
#endif

[-- Attachment #3: iiadc64.h --]
[-- Type: text/x-chdr, Size: 1477 bytes --]

//========================= Official Notice ===============================
//
// "This software was developed at the National Institute of Standards
// and Technology by employees of the Federal Government in the course of
// their official duties. Pursuant to Title 17 Section 105 of the United
// States Code this software is not subject to copyright protection and
// is in the public domain.
//
// The NIST Data Flow System (NDFS) is an experimental system and is
// offered AS IS. NIST assumes no responsibility whatsoever for its use
// by other parties, and makes no guarantees and NO WARRANTIES, EXPRESS
// OR IMPLIED, about its quality, reliability, fitness for any purpose,
// or any other characteristic.
//
// We would appreciate acknowledgement if the software is used.
//
// This software can be redistributed and/or modified freely provided
// that any derivative works bear some notice that they are derived from
// it, and any modified versions bear some notice that they have been
// modified from the original."
//
//=========================================================================



#ifndef __IIADC64_H
#define __IIADC64_H

#include <linux/ioctl.h>

#define II_MAJOR 121

#define II_RESET		_IO(II_MAJOR, 0)
#define II_MODE_MEMORY		_IO(II_MAJOR, 1)
#define II_MODE_RING		_IO(II_MAJOR, 2)
#define II_MODE_MAILBOX		_IOR(II_MAJOR, 3, int)
#define II_PCI_TABLE		_IOR(II_MAJOR, 4, unsigned int)
#define II_RUN			_IOR(II_MAJOR, 5, unsigned int)

#endif

  reply	other threads:[~2006-12-14 19:16 UTC|newest]

Thread overview: 201+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-12-13 19:52 [GIT PATCH] more Driver core patches for 2.6.19 Greg KH
     [not found] ` <1166039585152-git-send-email-greg@kroah.com>
     [not found]   ` <11660395913232-git-send-email-greg@kroah.com>
     [not found]     ` <11660395951158-git-send-email-greg@kroah.com>
     [not found]       ` <11660395998-git-send-email-greg@kroah.com>
2006-12-13 19:52         ` [PATCH 5/14] Driver core: show "initstate" of module Greg KH
2006-12-13 19:52           ` [PATCH 6/14] driver core: delete virtual directory on class_unregister() Greg KH
2006-12-13 19:52             ` [PATCH 7/14] DebugFS : inotify create/mkdir support Greg KH
2006-12-13 19:52               ` [PATCH 8/14] DebugFS : coding style fixes Greg KH
2006-12-13 19:53                 ` [PATCH 9/14] DebugFS : file/directory creation error handling Greg KH
2006-12-13 19:53                   ` [PATCH 10/14] DebugFS : more " Greg KH
2006-12-13 19:53                     ` [PATCH 11/14] DebugFS : file/directory removal fix Greg KH
2006-12-13 19:53                       ` [PATCH 12/14] Driver core: "platform_driver_probe() can save codespace": save codespace Greg KH
2006-12-13 19:53                         ` [PATCH 13/14] Driver core: Make platform_device_add_data accept a const pointer Greg KH
2006-12-13 19:53                           ` [PATCH 14/14] Driver core: deprecate PM_LEGACY, default it to N Greg KH
2006-12-13 20:12 ` [GIT PATCH] more Driver core patches for 2.6.19 Linus Torvalds
2006-12-13 20:31   ` Greg KH
2006-12-13 20:58     ` Linus Torvalds
2006-12-13 21:08       ` Linus Torvalds
2006-12-13 21:15         ` Arjan van de Ven
2006-12-14  9:30           ` Muli Ben-Yehuda
2006-12-14 10:13             ` Hans-Jürgen Koch
2006-12-13 21:36       ` Thomas Gleixner
2006-12-13 21:46       ` Benjamin Herrenschmidt
2006-12-13 23:40       ` Greg KH
2006-12-14  8:49       ` Duncan Sands
2006-12-14  9:56         ` Hans-Jürgen Koch
2006-12-14 11:51           ` Olivier Galibert
2006-12-14 12:45             ` Hans-Jürgen Koch
2006-12-14 19:16               ` Olivier Galibert [this message]
2006-12-14 12:39           ` Alan
2006-12-14 13:08             ` Hans-Jürgen Koch
2006-12-14 17:02           ` Jan Engelhardt
2006-12-14 17:17             ` Hans-Jürgen Koch
2006-12-14 17:57               ` Jan Engelhardt
2006-12-16 20:13             ` Lee Revell
2006-12-16 20:28               ` Jan Engelhardt
2006-12-14 17:34           ` Bernd Petrovitsch
2006-12-14 17:47             ` Hans-Jürgen Koch
2006-12-14 17:59               ` Bernd Petrovitsch
2006-12-14 12:27         ` James Courtier-Dutton
2006-12-13 20:38   ` Michael K. Edwards
2006-12-13 21:02     ` Greg KH
2006-12-13 21:32       ` Martin Bligh
2006-12-13 21:47         ` Andrew Morton
2006-12-13 22:09           ` GPL only modules [was Re: [GIT PATCH] more Driver core patches for 2.6.19] Greg KH
2006-12-14  0:32             ` Greg KH
2006-12-14  0:43               ` Jonathan Corbet
2006-12-14  0:55                 ` Greg KH
2006-12-14  1:00                   ` Linus Torvalds
2006-12-14  1:08                     ` Michael K. Edwards
2006-12-14  1:30                   ` Grzegorz Kulewski
2006-12-14  1:58                     ` Greg KH
2006-12-14  4:15                   ` Linus Torvalds
2006-12-14  5:39                     ` Martin J. Bligh
2006-12-14  6:01                       ` Hua Zhong
2006-12-14 11:14                         ` Alan
2006-12-14 11:31                           ` Hans-Jürgen Koch
2006-12-14 12:42                             ` Alan
2006-12-14 12:54                               ` Hans-Jürgen Koch
2006-12-14 16:59                                 ` Greg KH
2006-12-14 18:26                                   ` Alan
2006-12-14 21:16                                     ` Greg KH
2006-12-14 12:55                               ` Jan Engelhardt
2006-12-14 13:10                                 ` Arjan van de Ven
2006-12-14 17:17                                   ` Jan Engelhardt
2006-12-17 10:54                                     ` Geert Uytterhoeven
2006-12-14  8:03                       ` James Morris
2006-12-14 15:39                         ` Adrian Bunk
2006-12-14 20:08                           ` David Schwartz
2006-12-15 14:05                             ` Paolo Ornati
2006-12-17 10:11                             ` Geert Uytterhoeven
2006-12-17 10:56                               ` Rafael J. Wysocki
2006-12-19 12:57                               ` Marek Wawrzyczny
2006-12-19 13:56                                 ` Diego Calleja
2006-12-19 16:46                                   ` Gene Heskett
2006-12-19 17:11                                     ` Bill Nottingham
2006-12-19 17:24                                       ` Gene Heskett
2006-12-19 17:13                                     ` Diego Calleja
2006-12-20  5:11                                 ` Valdis.Kletnieks
2006-12-20 19:29                                   ` David Schwartz
2006-12-20 20:52                                     ` Valdis.Kletnieks
2006-12-20 21:10                                       ` alan
2006-12-21 15:34                                   ` Marek Wawrzyczny
2006-12-21 16:43                                     ` Horst H. von Brand
2006-12-21 19:28                                     ` Valdis.Kletnieks
2006-12-24  3:11                                       ` Horst H. von Brand
2006-12-20  4:27                               ` Steven Rostedt
2006-12-14 13:07                       ` Dave Jones
2006-12-14 15:05                         ` Adrian Bunk
2006-12-14 16:11                           ` Dave Jones
2006-12-14 16:31                             ` Olivier Galibert
2006-12-14 15:36                         ` Martin J. Bligh
2006-12-14 17:20                         ` Jan Engelhardt
2006-12-14 14:12                       ` Ben Collins
2006-12-14 15:10                         ` James Courtier-Dutton
2006-12-14 16:09                           ` Dave Jones
2006-12-14 16:36                           ` Ben Collins
2006-12-14 17:34                         ` Jan Engelhardt
2006-12-14 19:29                         ` Michael Buesch
2006-12-14 20:19                           ` Ben Collins
2006-12-14  7:24                     ` Jeffrey V. Merkey
2006-12-14  8:21                     ` David Woodhouse
2006-12-14 11:25                       ` Alan
2007-01-22 23:37                         ` dfsg isn't fsf (Re: GPL only modules [was Re: [GIT PATCH] more Driver core patches for 2.6.19]) Oleg Verych
2006-12-14 14:53                       ` GPL only modules [was Re: [GIT PATCH] more Driver core patches for 2.6.19] Theodore Tso
2006-12-14 16:52                       ` Linus Torvalds
2006-12-14 17:33                         ` Jeff V. Merkey
2006-12-14 18:01                           ` Martin J. Bligh
2006-12-14 18:12                             ` Jeff V. Merkey
2006-12-14 18:37                               ` Linus Torvalds
2006-12-14 18:30                                 ` Jeff V. Merkey
2006-12-14  9:34                     ` James Courtier-Dutton
2006-12-24 11:57                       ` Mark Hounschell
2006-12-24 13:22                         ` Sean
2006-12-24 14:42                           ` Mark Hounschell
2006-12-14 10:49                     ` Xavier Bestel
2006-12-14 13:04                     ` Dave Jones
2006-12-14 13:46                     ` Ben Collins
2006-12-14 17:21                       ` Jan Engelhardt
2006-12-14 17:49                         ` Ben Collins
2006-12-14 15:46                     ` Jeff Garzik
2006-12-14 17:03                       ` Linus Torvalds
2006-12-14 17:08                         ` Chris Wedgwood
2006-12-14 17:38                           ` Christoph Hellwig
2006-12-14 17:52                             ` Chris Wedgwood
2006-12-14 18:09                               ` Jan Engelhardt
2006-12-18 10:28                                 ` GPL only modules Eric W. Biederman
2006-12-14 18:15                               ` GPL only modules [was Re: [GIT PATCH] more Driver core patches for 2.6.19] Eric Sandeen
2006-12-14 18:39                                 ` Chris Wedgwood
2006-12-14 18:51                                   ` Linus Torvalds
2006-12-14 19:42                                   ` Scott Preece
2006-12-14 19:34                                     ` Jeff V. Merkey
2006-12-15  5:28                                       ` GPL only modules Alexandre Oliva
2006-12-15 10:13                                       ` GPL only modules [was Re: [GIT PATCH] more Driver core patches for 2.6.19] Eduard Bloch
2006-12-15 17:44                                       ` Dave Neuer
2006-12-18 10:55                                       ` Eric W. Biederman
2006-12-18 17:05                                         ` Jeff V. Merkey
2006-12-14 19:49                                     ` Hua Zhong
2006-12-17 10:57                             ` Geert Uytterhoeven
2006-12-14 16:17                     ` Adrian Bunk
2006-12-14 16:33                       ` Alan
2006-12-14 16:54                         ` Adrian Bunk
2006-12-14 17:17                         ` Theodore Tso
2006-12-14 18:18                           ` Alan
2006-12-14 19:51                           ` Adrian Bunk
2006-12-21 15:38                             ` Pavel Machek
2006-12-23 11:24                               ` Adrian Bunk
2006-12-23 21:36                                 ` Pavel Machek
2006-12-24  1:07                                   ` Adrian Bunk
2006-12-19 15:12                     ` free module selection Markus Elfring
2006-12-14  5:10                   ` GPL only modules [was Re: [GIT PATCH] more Driver core patches for 2.6.19] Bill Nottingham
2006-12-14  8:48                     ` Greg KH
2006-12-14 14:02                       ` Rik van Riel
2006-12-14 15:42                         ` Chris Friesen
2006-12-14 15:47                         ` Alan
2006-12-14 15:48                           ` Jeff Garzik
2006-12-14 22:21                             ` Dave Airlie
2006-12-14 22:26                               ` Michael Buesch
2006-12-14 22:39                                 ` Dave Airlie
2006-12-14 22:45                                   ` Michael Buesch
2006-12-14 19:32                         ` Bill Nottingham
2006-12-14  5:58                   ` Nigel Cunningham
2006-12-14  7:54                   ` David Schwartz
2006-12-14  8:21                   ` David Woodhouse
2006-12-14 10:36                 ` Alan
2006-12-14 14:57                   ` Adrian Bunk
2006-12-24 14:27               ` Pavel Machek
2006-12-24 19:59                 ` Dmitry Torokhov
2006-12-13 22:20           ` [GIT PATCH] more Driver core patches for 2.6.19 Michael K. Edwards
2006-12-13 22:59             ` Kyle Moffett
2006-12-13 23:55             ` Alan
2006-12-14  2:11               ` Al Viro
2006-12-14 17:22               ` Linus Torvalds
2006-12-14 15:13             ` Rik van Riel
2006-12-13 21:48       ` Michael K. Edwards
2006-12-13 21:03     ` Linus Torvalds
2006-12-16  9:05       ` Pavel Machek
2006-12-16 11:04         ` Jörn Engel
2006-12-17 10:49           ` Pavel Machek
2006-12-13 21:14   ` Benjamin Herrenschmidt
2006-12-13 21:22     ` Jan Engelhardt
2006-12-13 23:28       ` Linus Torvalds
2006-12-14 11:18         ` Jan Engelhardt
2006-12-14 11:26           ` Jan Engelhardt
2006-12-14 17:32             ` Linus Torvalds
2006-12-14 18:04               ` Jan Engelhardt
2006-12-14 17:26           ` Linus Torvalds
2006-12-14 20:47             ` Thomas Gleixner
2006-12-14 22:59               ` Linus Torvalds
2006-12-14 23:37                 ` Thomas Gleixner
2006-12-13 21:26     ` Linus Torvalds
2006-12-13 22:14       ` Benjamin Herrenschmidt
2006-12-13 22:30         ` Thomas Gleixner
2006-12-13 22:39           ` Benjamin Herrenschmidt
2006-12-13 23:11             ` Thomas Gleixner
2006-12-13 23:39               ` Michael K. Edwards
2006-12-14  0:00               ` Alan
2006-12-13 23:56           ` Alan
2006-12-14  0:08             ` Greg KH
2006-12-14  9:15             ` Thomas Gleixner
2006-12-14 11:33               ` Alan
2006-12-13 22:40         ` Thomas Gleixner
2006-12-13 22:45           ` Benjamin Herrenschmidt
2006-12-13 23:15             ` Thomas Gleixner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20061214191629.GA68100@dspnet.fr.eu.org \
    --to=galibert@pobox.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).