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    [W:0.028 / U:0.500 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site