lkml.org 
[lkml]   [1999]   [Dec]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
Subjectproblem with unregister_chrdev in 2.3.30 ?
I'm writing a minimalist module driver to play with a dsp card.
insmod goes nicely, rmmod _seems_ to go nicely, but them cat
/proc/devices generates an oops:


Dec 8 08:43:11 athena kernel: IIADC64 minimal kernel driver (c) 1999 Olivier Galibert
Dec 8 08:43:11 athena kernel: iiadc64: DSP board found, io at 0xd800, irq 9
Dec 8 08:43:15 athena kernel: iiadc64: Reset successful
Dec 8 08:43:39 athena kernel: Unable to handle kernel paging request at virtual address cc4106ab
Dec 8 08:43:39 athena kernel: printing eip:
Dec 8 08:43:39 athena kernel: c0211ed5
Dec 8 08:43:39 athena kernel: *pde = 0135e063
Dec 8 08:43:39 athena kernel: *pte = 00000000
Dec 8 08:43:39 athena kernel: Oops: 0000
Dec 8 08:43:39 athena kernel: CPU: 0
Dec 8 08:43:39 athena kernel: EIP: 0010:[vsprintf+477/988]
Dec 8 08:43:39 athena kernel: EFLAGS: 00010297
Dec 8 08:43:39 athena kernel: eax: cc4106ab ebx: ffffffff ecx: cc4106ab edx: fffffffe
Dec 8 08:43:39 athena kernel: esi: ffffffff edi: ca7cd063 ebp: ca9dff38 esp: ca9dfef8
Dec 8 08:43:39 athena kernel: ds: 0018 es: 0018 ss: 0018
Dec 8 08:43:39 athena kernel: Process cat (pid: 855, stackpage=ca9df000)
Dec 8 08:43:39 athena kernel: Stack: ca7cd000 c0270e44 0000004e c021f473 00000000 00000000 0000000a c02120e8
Dec 8 08:43:39 athena kernel: ca7cd05f c021f405 ca9dff30 c0129403 ca7cd05f c021f400 00000079 cc4106ab
Dec 8 08:43:39 athena kernel: 00000c00 00000000 ca7cd000 ca7cd000 c0153aad ca7cd000 cb11de1c 00000c00
Dec 8 08:43:39 athena kernel: Call Trace: [tvecs+24743/33588] [sprintf+20/4896] [tvecs+24633/33588] [get_device_list+67/168] [tvecs+24628/33588] [<cc4106ab>] [devices_read_proc+21/72]
Dec 8 08:43:39 athena kernel: [proc_file_read+274/564] [sys_read+189/220] [system_call+52/56]
Dec 8 08:43:39 athena kernel: Code: 80 38 00 74 07 40 4a 83 fa ff 75 f4 29 c8 89 c6 8b 44 24 1c
OG.
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/malloc.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>
#include <linux/delay.h>
#include <linux/pci.h>

#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/ptrace.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)

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 = {
0, /* llseek */
0, /* read */
0, /* write */
0, /* readdir */
0, /* poll */
0/*iiadc64_ioctl*/,/* ioctl */
0, /* mmap */
iiadc64_open, /* open */
0, /* flush */
iiadc64_release, /* release */
0, /* fsync */
0, /* fasync */
0, /* check_media_change */
0, /* revalidate */
0 /* lock */
};
struct iiadc64_state {
struct pci_dev *dev;
unsigned long iobase;
unsigned int irq;
unsigned long memory;
} is;
static unsigned int iiadc64_mailbox_read(int box)
{
int counter = 100000;
int mask = 0xf0000 << box;
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;
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_reset(void)
{
unsigned int intcsr;
unsigned int timeout;
unsigned int val;
intcsr = inl(is.iobase + 0x38);
outl(intcsr & 0xfcffffff, is.iobase + 0x38);
outl(0x0f000000, is.iobase + 0x3c);
timeout = 2*HZ;
do {
current->state = TASK_INTERRUPTIBLE;
timeout = schedule_timeout(timeout);
} while (timeout);
outl(0x00000000, is.iobase + 0x3c);
timeout = 2*HZ;
do {
current->state = TASK_INTERRUPTIBLE;
timeout = schedule_timeout(timeout);
} while (timeout);
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);
}
static int iiadc64_open(struct inode *inode, struct file *file)
{
MOD_INC_USE_COUNT;
DEBUG_IN("iiadc64: open\n");
return 0;
}
static int iiadc64_release(struct inode *inode, struct file *file)
{
DEBUG_IN("iiadc64: close\n");
MOD_DEC_USE_COUNT;
return 0;
}

#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;
}
is.iobase = is.dev->resource[0].start;
is.irq = is.dev->irq;
is.memory = get_free_page(GFP_KERNEL);

if (register_chrdev(121, "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);

iiadc64_reset();

return 0;
}
#ifdef MODULE
void cleanup_module(void)
{
free_page(is.memory);
unregister_chrdev(120, "iiadc64");
}
#endif
\
 
 \ /
  Last update: 2005-03-22 13:55    [from the cache]
©2003-2011 Jasper Spaans