]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.2.18pre6 2.2.18pre6
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:22:17 +0000 (15:22 -0500)
committerAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:22:17 +0000 (15:22 -0500)
o Fix the IDE PCI not compiling bug (Dag Wieers)
o Kill an escaped reference to vger.rutgers (Dave Miller)
o Small rtl8139 fixups (Jeff Garzik)
o Add USB bluetooth driver (Greg Kroah-Hartman)
o Fix oops in visor driver (Greg Kroah-Hartman)
o Remove some unneeded ext2 includes,fix a bug (Andreas Dilger)
in the UFS code
o Fix rtc race between timer and rtc irq (Andrea Arcangeli)
o Fix slow gettimeofday SMP race (Andrea Arcangeli)
o Check lost_ticks in settimeofday to be more (Andrea Arcangeli)
precise

18 files changed:
Documentation/nmi_watchdog.txt
Makefile
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/kernel/time.c
arch/i386/kernel/i386_ksyms.c
arch/i386/kernel/time.c
drivers/ap1000/ap.c
drivers/ap1000/ddv.c
drivers/block/ide-pci.c
drivers/char/rtc.c
drivers/net/rtl8139.c
drivers/usb/Config.in
drivers/usb/Makefile
drivers/usb/bluetooth.c [new file with mode: 0644]
drivers/usb/serial/visor.c
fs/ufs/ialloc.c
include/linux/ext2_fs_sb.h
kernel/ksyms.c

index 58303e947f39a5472e7fe74f368211f07d3e1a40..f156029ca44beee1fe1aae0f286d9414b630d714 100644 (file)
@@ -30,5 +30,5 @@ http://people.redhat.com/mingo/NMI-watchdog-patches/
 
 [ feel free to send bug reports, suggestions and patches to
   Ingo Molnar <mingo@redhat.com> or the Linux SMP mailing
-  list at <linux-smp@vger.rutgers.edu> ]
+  list at <linux-smp@vger.kernel.org> ]
 
index 7cfa63258605d6853b0119801f70351987a30440..7c76248187b95588733562437c26c1e834607c9e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 18
-EXTRAVERSION = pre5
+EXTRAVERSION = pre6
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
index 88ecc2aec6880a6fd57086b73b2bb45ea207ca65..04c9256db25ca1f7c0562ae6c6735f9019b23ac6 100644 (file)
@@ -37,6 +37,7 @@
 extern struct hwrpb_struct *hwrpb;
 extern void dump_thread(struct pt_regs *, struct user *);
 extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
+extern spinlock_t rtc_lock;
 
 /* these are C runtime functions with special calling conventions: */
 extern void __divl (void);
@@ -188,6 +189,8 @@ EXPORT_SYMBOL(local_bh_count);
 EXPORT_SYMBOL(local_irq_count);
 #endif /* __SMP__ */
 
+EXPORT_SYMBOL(rtc_lock);
+
 /*
  * The following are special because they're not called
  * explicitly (the C compiler or assembler generates them in
index ebe39e330e69dbf4080861a600c0c20d2261f99d..0791ca7e7177343a876cf018f49a4206781b40ea 100644 (file)
@@ -47,6 +47,7 @@ extern volatile unsigned long lost_ticks;     /* kernel/sched.c */
 
 static int set_rtc_mmss(unsigned long);
 
+spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
 
 /*
  * Shift amount by which scaled_ticks_per_cycle is scaled.  Shifting
@@ -455,6 +456,8 @@ set_rtc_mmss(unsigned long nowtime)
        int real_seconds, real_minutes, cmos_minutes;
        unsigned char save_control, save_freq_select;
 
+       /* irq are locally disabled here */
+       spin_lock(&rtc_lock);
        /* Tell the clock it's being set */
        save_control = CMOS_READ(RTC_CONTROL);
        CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
@@ -504,6 +507,7 @@ set_rtc_mmss(unsigned long nowtime)
         */
        CMOS_WRITE(save_control, RTC_CONTROL);
        CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+       spin_unlock(&rtc_lock);
 
        return retval;
 }
index d0ff4f3b3e1079d4cca42f09085fe71b8c95989f..23fa07d021d16b23d67fe4be0c4b6204879ca867 100644 (file)
@@ -20,6 +20,7 @@
 
 extern void dump_thread(struct pt_regs *, struct user *);
 extern int dump_fpu(elf_fpregset_t *);
+extern spinlock_t rtc_lock;
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
 extern struct drive_info_struct drive_info;
@@ -119,3 +120,5 @@ EXPORT_SYMBOL(mca_is_adapter_used);
 #ifdef CONFIG_VT
 EXPORT_SYMBOL(screen_info);
 #endif
+
+EXPORT_SYMBOL(rtc_lock);
index fd5d4e028b671c27d42cca70ec534363e9d81acf..78dbaa8d36c3dc89d8c3c9729a93ce260f30c31d 100644 (file)
@@ -77,6 +77,9 @@ static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */
 unsigned long fast_gettimeoffset_quotient=0;
 
 extern rwlock_t xtime_lock;
+extern volatile unsigned long lost_ticks;
+
+spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
 
 static inline unsigned long do_fast_gettimeoffset(void)
 {
@@ -112,6 +115,8 @@ static inline unsigned long do_fast_gettimeoffset(void)
 
 #ifndef CONFIG_X86_TSC
 
+spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
+
 /* This function must be called with interrupts disabled 
  * It was inspired by Steve McCanne's microtime-i386 for BSD.  -- jrs
  * 
@@ -156,6 +161,8 @@ static unsigned long do_slow_gettimeoffset(void)
         */
        unsigned long jiffies_t;
 
+       /* gets recalled with irq locally disabled */
+       spin_lock(&i8253_lock);
        /* timer count may underflow right here */
        outb_p(0x00, 0x43);     /* latch the count ASAP */
 
@@ -214,6 +221,7 @@ static unsigned long do_slow_gettimeoffset(void)
                }
        } else
                jiffies_p = jiffies_t;
+       spin_unlock(&i8253_lock);
 
        count_p = count;
 
@@ -237,7 +245,6 @@ static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
  */
 void do_gettimeofday(struct timeval *tv)
 {
-       extern volatile unsigned long lost_ticks;
        unsigned long flags;
        unsigned long usec, sec;
 
@@ -271,6 +278,7 @@ void do_settimeofday(struct timeval *tv)
         * would have done, and then undo it!
         */
        tv->tv_usec -= do_gettimeoffset();
+       tv->tv_usec -= lost_ticks * (1000000 / HZ);
 
        while (tv->tv_usec < 0) {
                tv->tv_usec += 1000000;
@@ -301,6 +309,8 @@ static int set_rtc_mmss(unsigned long nowtime)
        int real_seconds, real_minutes, cmos_minutes;
        unsigned char save_control, save_freq_select;
 
+       /* gets recalled with irq locally disabled */
+       spin_lock(&rtc_lock);
        save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
        CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
 
@@ -346,6 +356,7 @@ static int set_rtc_mmss(unsigned long nowtime)
         */
        CMOS_WRITE(save_control, RTC_CONTROL);
        CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+       spin_unlock(&rtc_lock);
 
        return retval;
 }
@@ -447,10 +458,19 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
                rdtscl(last_tsc_low);
 
+#if 0 /*
+       * SUBTLE: this is not necessary from here because it's implicit in the
+       * write xtime_lock.
+       */
+               spin_lock(&i8253_lock);
+#endif
                outb_p(0x00, 0x43);     /* latch the count ASAP */
 
                count = inb_p(0x40);    /* read the latched count */
                count |= inb(0x40) << 8;
+#if 0
+               spin_unlock(&i8253_lock);
+#endif
 
                count = ((LATCH-1) - count) * TICK_SIZE;
                delay_at_last_interrupt = (count + LATCH/2) / LATCH;
index ce50c5edb31957d6fa3c8bd9048f4e9cf7633154..c79386e15985a5ac152fcc0b323631ed21849549 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/fs.h>
-#include <linux/ext2_fs.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/module.h>
index 4a21a588212e46ac681be5bbe7d402d0a0e06c1a..901a971acdca4ed9ef591d7a341972b2bc29d2f2 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/fs.h>
-#include <linux/ext2_fs.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/mm.h>
index d9104b2dd0ed6c7fa88890fac6b66e55cbae3c5a..ea09ecbffc4b4ad2c278c90291c852d1a85c1d09 100644 (file)
@@ -467,12 +467,12 @@ __initfunc(void ide_scan_pcibus (void))
                /*
                 *      Don't try and tune a VIA 82C586 or 586A
                 */
-               if (IDE_PCI_DEVID_RQ(devid, DEVID_VP_IDE))
+               if (IDE_PCI_DEVID_EQ(devid, DEVID_VP_IDE))
                {
                        autodma_default = 0;
                        break;
                }
-               if (IDE_PCI_DEVID_RQ(devid, DEVID_VP_OLDIDE))
+               if (IDE_PCI_DEVID_EQ(devid, DEVID_VP_OLDIDE))
                {
                        autodma_default = 0;
                        break;
index 6425f1dc940faec43c9ed604e586aa2807115e34..9b14e6af65b5964168913d20b944a6b0ed7080ab 100644 (file)
@@ -113,10 +113,15 @@ static unsigned long epoch = 1900;        /* year corresponding to 0x00   */
 unsigned char days_in_mo[] = 
 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
+extern spinlock_t rtc_lock;
+
 /*
  *     A very tiny interrupt handler. It runs with SA_INTERRUPT set,
- *     so that there is no possibility of conflicting with the
- *     set_rtc_mmss() call that happens during some timer interrupts.
+ *     but there is possibility of conflicting with the set_rtc_mmss()
+ *     call (the rtc irq and the timer irq can easily run at the same
+ *     time in two different CPUs). So we need to serializes
+ *     accesses to the chip with the rtc_lock spinlock that each
+ *     architecture should implement in the timer code.
  *     (See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.)
  */
 
@@ -131,7 +136,10 @@ static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        rtc_irq_data += 0x100;
        rtc_irq_data &= ~0xff;
+       /* runs with irq locally disabled (see SA_INTERRUPT flag). */
+       spin_lock(&rtc_lock);
        rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
+       spin_unlock(&rtc_lock);
        wake_up_interruptible(&rtc_wait);       
 
        if (rtc_status & RTC_TIMER_ON)
@@ -276,8 +284,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                if (sec >= 60)
                        sec = 0xff;
 
-               save_flags(flags);
-               cli();
+               spin_lock_irqsave(&rtc_lock, flags);
                if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) ||
                    RTC_ALWAYS_BCD)
                {
@@ -288,7 +295,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                CMOS_WRITE(hrs, RTC_HOURS_ALARM);
                CMOS_WRITE(min, RTC_MINUTES_ALARM);
                CMOS_WRITE(sec, RTC_SECONDS_ALARM);
-               restore_flags(flags);
+               spin_unlock_irqrestore(&rtc_lock, flags);
 
                return 0;
        }
@@ -336,12 +343,11 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                if ((yrs -= epoch) > 255)    /* They are unsigned */
                        return -EINVAL;
 
-               save_flags(flags);
-               cli();
+               spin_lock_irqsave(&rtc_lock, flags);
                if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
                    || RTC_ALWAYS_BCD) {
                        if (yrs > 169) {
-                               restore_flags(flags);
+                               spin_unlock_irqrestore(&rtc_lock, flags);
                                return -EINVAL;
                        }
                        if (yrs >= 100)
@@ -370,7 +376,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                CMOS_WRITE(save_control, RTC_CONTROL);
                CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
 
-               restore_flags(flags);
+               spin_unlock_irqrestore(&rtc_lock, flags);
                return 0;
        }
        case RTC_IRQP_READ:     /* Read the periodic IRQ rate.  */
@@ -405,12 +411,11 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
                rtc_freq = arg;
 
-               save_flags(flags);
-               cli();
+               spin_lock_irqsave(&rtc_lock, flags);
                val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
                val |= (16 - tmp);
                CMOS_WRITE(val, RTC_FREQ_SELECT);
-               restore_flags(flags);
+               spin_unlock_irqrestore(&rtc_lock, flags);
                return 0;
        }
 #ifdef __alpha__
@@ -465,15 +470,14 @@ static int rtc_release(struct inode *inode, struct file *file)
        unsigned char tmp;
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&rtc_lock, flags);
        tmp = CMOS_READ(RTC_CONTROL);
        tmp &=  ~RTC_PIE;
        tmp &=  ~RTC_AIE;
        tmp &=  ~RTC_UIE;
        CMOS_WRITE(tmp, RTC_CONTROL);
        CMOS_READ(RTC_INTR_FLAGS);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&rtc_lock, flags);
 
        if (rtc_status & RTC_TIMER_ON) {
                rtc_status &= ~RTC_TIMER_ON;
@@ -546,11 +550,10 @@ __initfunc(int rtc_init(void))
                while (jiffies - uip_watchdog < 2*HZ/100)
                        barrier();
        
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&rtc_lock, flags);
        year = CMOS_READ(RTC_YEAR);
        ctrl = CMOS_READ(RTC_CONTROL);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&rtc_lock, flags);
        
        if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
                BCD_TO_BIN(year);       /* This should never happen... */
@@ -568,11 +571,10 @@ __initfunc(int rtc_init(void))
        init_timer(&rtc_irq_timer);
        rtc_irq_timer.function = rtc_dropped_irq;
        rtc_wait = NULL;
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&rtc_lock, flags);
        /* Initialize periodic freq. to CMOS reset default, which is 1024Hz */
        CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) & 0xF0) | 0x06), RTC_FREQ_SELECT);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&rtc_lock, flags);
        rtc_freq = 1024;
        return 0;
 }
@@ -596,12 +598,11 @@ void rtc_dropped_irq(unsigned long data)
        printk(KERN_INFO "rtc: lost some interrupts at %ldHz.\n", rtc_freq);
        mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&rtc_lock, flags);
        rtc_irq_data += ((rtc_freq/HZ)<<8);
        rtc_irq_data &= ~0xff;
        rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);     /* restart */
-       restore_flags(flags);
+       spin_unlock_irqrestore(&rtc_lock, flags);
 }
 
 /*
@@ -615,11 +616,10 @@ int get_rtc_status(char *buf)
        unsigned char batt, ctrl;
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&rtc_lock, flags);
        batt = CMOS_READ(RTC_VALID) & RTC_VRT;
        ctrl = CMOS_READ(RTC_CONTROL);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&rtc_lock, flags);
 
        p = buf;
 
@@ -690,10 +690,9 @@ static inline unsigned char rtc_is_updating(void)
        unsigned long flags;
        unsigned char uip;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&rtc_lock, flags);
        uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&rtc_lock, flags);
        return uip;
 }
 
@@ -723,8 +722,7 @@ void get_rtc_time(struct rtc_time *rtc_tm)
         * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
         * by the RTC when initially set to a non-zero value.
         */
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&rtc_lock, flags);
        rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
        rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
        rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
@@ -732,7 +730,7 @@ void get_rtc_time(struct rtc_time *rtc_tm)
        rtc_tm->tm_mon = CMOS_READ(RTC_MONTH);
        rtc_tm->tm_year = CMOS_READ(RTC_YEAR);
        ctrl = CMOS_READ(RTC_CONTROL);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&rtc_lock, flags);
 
        if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
        {
@@ -763,13 +761,12 @@ void get_rtc_alm_time(struct rtc_time *alm_tm)
         * Only the values that we read from the RTC are set. That
         * means only tm_hour, tm_min, and tm_sec.
         */
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&rtc_lock, flags);
        alm_tm->tm_sec = CMOS_READ(RTC_SECONDS_ALARM);
        alm_tm->tm_min = CMOS_READ(RTC_MINUTES_ALARM);
        alm_tm->tm_hour = CMOS_READ(RTC_HOURS_ALARM);
        ctrl = CMOS_READ(RTC_CONTROL);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&rtc_lock, flags);
 
        if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
        {
@@ -794,13 +791,12 @@ void mask_rtc_irq_bit(unsigned char bit)
        unsigned char val;
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&rtc_lock, flags);
        val = CMOS_READ(RTC_CONTROL);
        val &=  ~bit;
        CMOS_WRITE(val, RTC_CONTROL);
        CMOS_READ(RTC_INTR_FLAGS);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&rtc_lock, flags);
        rtc_irq_data = 0;
 }
 
@@ -809,12 +805,11 @@ void set_rtc_irq_bit(unsigned char bit)
        unsigned char val;
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&rtc_lock, flags);
        val = CMOS_READ(RTC_CONTROL);
        val |= bit;
        CMOS_WRITE(val, RTC_CONTROL);
        CMOS_READ(RTC_INTR_FLAGS);
        rtc_irq_data = 0;
-       restore_flags(flags);
+       spin_unlock_irqrestore(&rtc_lock, flags);
 }
index 4f1e965853c4889f4258d9ca41fc3ac92ee49551..03270e5725c8a606ec84ad441bc68d792f6dadfe 100644 (file)
@@ -1235,8 +1235,9 @@ static int rtl8129_rx(struct device *dev)
                        /* Malloc up new buffer, compatible with net-2e. */
                        /* Omit the four octet CRC from the length. */
                        struct sk_buff *skb;
+                       int pkt_size = rx_size - 4;
 
-                       skb = dev_alloc_skb(rx_size + 2);
+                       skb = dev_alloc_skb(pkt_size + 2);
                        if (skb == NULL) {
                                printk(KERN_WARNING"%s: Memory squeeze, deferring packet.\n",
                                           dev->name);
@@ -1247,12 +1248,12 @@ static int rtl8129_rx(struct device *dev)
                        }
                        skb->dev = dev;
                        skb_reserve(skb, 2);    /* 16 byte align the IP fields. */
-                       if (ring_offset+rx_size+4 > RX_BUF_LEN) {
+                       if (ring_offset+rx_size > RX_BUF_LEN) {
                                int semi_count = RX_BUF_LEN - ring_offset - 4;
                                memcpy(skb_put(skb, semi_count), &rx_ring[ring_offset + 4],
                                           semi_count);
-                               memcpy(skb_put(skb, rx_size-semi_count), rx_ring,
-                                          rx_size-semi_count);
+                               memcpy(skb_put(skb, pkt_size-semi_count), rx_ring,
+                                          pkt_size-semi_count);
                                if (rtl8129_debug > 4) {
                                        int i;
                                        printk(KERN_DEBUG"%s:  Frame wrap @%d",
@@ -1265,17 +1266,17 @@ static int rtl8129_rx(struct device *dev)
                        } else {
 #if 1  /* USE_IP_COPYSUM */
                                eth_copy_and_sum(skb, &rx_ring[ring_offset + 4],
-                                                rx_size - 4, 0);
-                               skb_put(skb, rx_size - 4);
+                                                pkt_size, 0);
+                               skb_put(skb, pkt_size);
 #else
-                               memcpy(skb_put(skb, rx_size), &rx_ring[ring_offset + 4],
-                                          rx_size);
+                               memcpy(skb_put(skb, pkt_size), &rx_ring[ring_offset + 4],
+                                          pkt_size);
 #endif
                        }
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
 #if LINUX_VERSION_CODE > 0x20119
-                       tp->stats.rx_bytes += rx_size;
+                       tp->stats.rx_bytes += pkt_size;
 #endif
                        tp->stats.rx_packets++;
                }
index 70dc742f0a5bfc28abb80e24e4aaf14c95291552..b46b6bea9189d130d1f14f799308120b4bbe693a 100644 (file)
@@ -69,6 +69,7 @@ comment 'USB Devices'
       dep_tristate '  USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB
       dep_tristate '  D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV
       dep_tristate '  Microtek X6USB scanner support (EXPERIMENTAL)' CONFIG_USB_MICROTEK $CONFIG_SCSI
+      dep_tristate '  USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB
    fi
    dep_tristate '  Kawasaki USB-ethernet controller' CONFIG_USB_KAWETH $CONFIG_USB
 
index a729900d00e1338d525cb7805650be5e67172cd5..cf91f2acc0d7436c37e9d50845be63507e105e50 100644 (file)
@@ -84,6 +84,7 @@ obj-$(CONFIG_USB_RIO500)      += rio500.o
 obj-$(CONFIG_USB_DSBR)         += dsbr100.o
 obj-$(CONFIG_USB_MICROTEK)     += microtek.o
 obj-$(CONFIG_USB_KAWETH)       += kaweth.o
+obj-$(CONFIG_USB_BLUETOOTH)    += bluetooth.o
 
 # Extract lists of the multi-part drivers.
 # The 'int-*' lists are the intermediate files used to build the multi's.
diff --git a/drivers/usb/bluetooth.c b/drivers/usb/bluetooth.c
new file mode 100644 (file)
index 0000000..1b02b02
--- /dev/null
@@ -0,0 +1,1234 @@
+/*
+ * bluetooth.c   Version 0.5
+ *
+ * Copyright (c) 2000 Greg Kroah-Hartman       <greg@kroah.com>
+ * Copyright (c) 2000 Mark Douglas Corner      <mcorner@umich.edu>
+ *
+ * USB Bluetooth driver, based on the Bluetooth Spec version 1.0B
+ *
+ * (08/06/2000) Version 0.5 gkh
+ *     Fixed problem of not resubmitting the bulk read urb if there is
+ *     an error in the callback.  Ericsson devices seem to need this.
+ *
+ * (07/11/2000) Version 0.4 gkh
+ *     Fixed bug in disconnect for when we call tty_hangup
+ *     Fixed bug in bluetooth_ctrl_msg where the bluetooth struct was not
+ *     getting attached to the control urb properly.
+ *     Fixed bug in bluetooth_write where we pay attention to the result
+ *     of bluetooth_ctrl_msg.
+ *
+ * (08/03/2000) Version 0.3 gkh mdc
+ *     Merged in Mark's changes to make the driver play nice with the Axis
+ *     stack.
+ *     Made the write bulk use an urb pool to enable larger transfers with
+ *     fewer calls to the driver.
+ *     Fixed off by one bug in acl pkt receive
+ *     Made packet counters specific to each bluetooth device 
+ *     Added checks for zero length callbacks
+ *     Added buffers for int and bulk packets.  Had to do this otherwise 
+ *     packet types could intermingle.
+ *     Made a control urb pool for the control messages.
+ *
+ * (07/11/2000) Version 0.2 gkh
+ *     Fixed a small bug found by Nils Faerber in the usb_bluetooth_probe 
+ *     function.
+ *
+ * (07/09/2000) Version 0.1 gkh
+ *     Initial release. Has support for sending ACL data (which is really just
+ *     a HCI frame.) Raw HCI commands and HCI events are not supported.
+ *     A ioctl will probably be needed for the HCI commands and events in the
+ *     future. All isoch endpoints are ignored at this time also.
+ *     This driver should work for all currently shipping USB Bluetooth 
+ *     devices at this time :)
+ * 
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/malloc.h>
+#include <linux/fcntl.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/devfs_fs_kernel.h>
+
+#define DEBUG
+#include <linux/usb.h>
+
+/* Module information */
+MODULE_AUTHOR("Greg Kroah-Hartman, Mark Douglas Corner");
+MODULE_DESCRIPTION("USB Bluetooth driver");
+
+/* define this if you have hardware that is not good */
+/*#define      BTBUGGYHARDWARE */
+
+/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
+#define WIRELESS_CLASS_CODE                    0xe0
+#define RF_SUBCLASS_CODE                       0x01
+#define BLUETOOTH_PROGRAMMING_PROTOCOL_CODE    0x01
+
+
+#define BLUETOOTH_TTY_MAJOR    240     /* Prototype number for now */
+#define BLUETOOTH_TTY_MINORS   8
+
+#define USB_BLUETOOTH_MAGIC    0x6d02  /* magic number for bluetooth struct */
+
+#define BLUETOOTH_CONTROL_REQUEST_TYPE 0x20
+
+/* Bluetooth packet types */
+#define CMD_PKT                        0x01
+#define ACL_PKT                        0x02
+#define SCO_PKT                        0x03
+#define EVENT_PKT              0x04
+#define ERROR_PKT              0x05
+#define NEG_PKT                        0x06
+
+/* Message sizes */
+#define MAX_EVENT_SIZE         0xFF
+#define EVENT_HDR_SIZE         3       /* 2 for the header + 1 for the type indicator */
+#define EVENT_BUFFER_SIZE      (MAX_EVENT_SIZE + EVENT_HDR_SIZE)
+
+#define MAX_ACL_SIZE           0xFFFF
+#define ACL_HDR_SIZE           5       /* 4 for the header + 1 for the type indicator */
+#define ACL_BUFFER_SIZE                (MAX_ACL_SIZE + ACL_HDR_SIZE)
+
+/* parity check flag */
+#define RELEVANT_IFLAG(iflag)  (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+#define CHAR2INT16(c1,c0)      (((u32)((c1) & 0xff) << 8) + (u32)((c0) & 0xff))
+#define MIN(a,b)               (((a)<(b))?(a):(b))
+
+#define NUM_BULK_URBS          24
+#define NUM_CONTROL_URBS       16
+
+struct usb_bluetooth {
+       int                     magic;
+       struct usb_device *     dev;
+       struct tty_driver *     tty_driver;     /* the tty_driver for this device */
+       struct tty_struct *     tty;            /* the coresponding tty for this port */
+
+       unsigned char           minor;          /* the starting minor number for this device */
+       char                    active;         /* someone has this device open */
+       int                     throttle;       /* throttled by tty layer */
+       
+       __u8                    control_out_bInterfaceNum;
+       struct urb *            control_urb_pool[NUM_CONTROL_URBS];
+       devrequest              dr[NUM_CONTROL_URBS];
+
+       unsigned char *         interrupt_in_buffer;
+       struct urb *            interrupt_in_urb;
+
+       unsigned char *         bulk_in_buffer;
+       struct urb *            read_urb;
+
+       int                     bulk_out_size;
+       struct urb *            write_urb_pool[NUM_BULK_URBS];
+       __u8                    bulk_out_endpointAddress;
+
+       wait_queue_head_t       write_wait;
+
+       struct tq_struct        tqueue;         /* task queue for line discipline waking up */
+       
+       unsigned int            int_packet_pos;
+       unsigned char           int_buffer[EVENT_BUFFER_SIZE];
+       unsigned int            bulk_packet_pos;
+       unsigned char           bulk_buffer[ACL_BUFFER_SIZE];   /* 64k preallocated, fix? */
+};
+
+
+/* local function prototypes */
+static int  bluetooth_open             (struct tty_struct *tty, struct file *filp);
+static void bluetooth_close            (struct tty_struct *tty, struct file *filp);
+static int  bluetooth_write            (struct tty_struct *tty, int from_user, const unsigned char *buf, int count);
+static int  bluetooth_write_room       (struct tty_struct *tty);
+static int  bluetooth_chars_in_buffer  (struct tty_struct *tty);
+static void bluetooth_throttle         (struct tty_struct *tty);
+static void bluetooth_unthrottle       (struct tty_struct *tty);
+static int  bluetooth_ioctl            (struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
+static void bluetooth_set_termios      (struct tty_struct *tty, struct termios *old);
+
+static void bluetooth_int_callback             (struct urb *urb);
+static void bluetooth_ctrl_callback            (struct urb *urb);
+static void bluetooth_read_bulk_callback       (struct urb *urb);
+static void bluetooth_write_bulk_callback      (struct urb *urb);
+
+static void * usb_bluetooth_probe      (struct usb_device *dev, unsigned int ifnum);
+static void usb_bluetooth_disconnect   (struct usb_device *dev, void *ptr);
+
+
+static struct usb_driver usb_bluetooth_driver = {
+       name:           "bluetooth",
+       probe:          usb_bluetooth_probe,
+       disconnect:     usb_bluetooth_disconnect,
+};
+
+static int                     bluetooth_refcount;
+static struct tty_driver       bluetooth_tty_driver;
+static struct tty_struct *     bluetooth_tty[BLUETOOTH_TTY_MINORS];
+static struct termios *                bluetooth_termios[BLUETOOTH_TTY_MINORS];
+static struct termios *                bluetooth_termios_locked[BLUETOOTH_TTY_MINORS];
+static struct usb_bluetooth    *bluetooth_table[BLUETOOTH_TTY_MINORS] = {NULL, };
+
+
+
+static inline int bluetooth_paranoia_check (struct usb_bluetooth *bluetooth, const char *function)
+{
+       if (!bluetooth) {
+               dbg("%s - bluetooth == NULL", function);
+               return -1;
+       }
+       if (bluetooth->magic != USB_BLUETOOTH_MAGIC) {
+               dbg("%s - bad magic number for bluetooth", function);
+               return -1;
+       }
+
+       return 0;
+}
+
+
+static inline struct usb_bluetooth* get_usb_bluetooth (struct usb_bluetooth *bluetooth, const char *function)
+{
+       if (!bluetooth || 
+           bluetooth_paranoia_check (bluetooth, function)) { 
+               /* then say that we dont have a valid usb_bluetooth thing, which will
+                * end up generating -ENODEV return values */
+               return NULL;
+       }
+
+       return bluetooth;
+}
+
+
+static inline struct usb_bluetooth *get_bluetooth_by_minor (int minor)
+{
+       return bluetooth_table[minor];
+}
+
+
+static int bluetooth_ctrl_msg (struct usb_bluetooth *bluetooth, int request, int value, void *buf, int len)
+{
+       struct urb *urb = NULL;
+       devrequest *dr = NULL;
+       int i;
+       int status;
+
+       dbg (__FUNCTION__);
+
+       /* try to find a free urb in our list */
+       for (i = 0; i < NUM_CONTROL_URBS; ++i) {
+               if (bluetooth->control_urb_pool[i]->status != -EINPROGRESS) {
+                       urb = bluetooth->control_urb_pool[i];
+                       dr = &bluetooth->dr[i];
+                       break;
+               }
+       }
+       if (urb == NULL) {
+               dbg (__FUNCTION__ " - no free urbs");
+               return -ENOMEM;
+       }
+
+       /* free up the last buffer that this urb used */
+       if (urb->transfer_buffer != NULL) {
+               kfree(urb->transfer_buffer);
+               urb->transfer_buffer = NULL;
+       }
+
+       dr->requesttype = BLUETOOTH_CONTROL_REQUEST_TYPE;
+       dr->request = request;
+       dr->value = cpu_to_le16p(&value);
+       dr->index = cpu_to_le16p(&bluetooth->control_out_bInterfaceNum);
+       dr->length = cpu_to_le16p(&len);
+       
+       FILL_CONTROL_URB (urb, bluetooth->dev, usb_sndctrlpipe(bluetooth->dev, 0),
+                         (unsigned char*)dr, buf, len, bluetooth_ctrl_callback, bluetooth);
+
+       /* send it down the pipe */
+       status = usb_submit_urb(urb);
+       if (status)
+               dbg(__FUNCTION__ " - usb_submit_urb(control) failed with status = %d", status);
+       
+       return 0;
+}
+
+
+
+
+
+/*****************************************************************************
+ * Driver tty interface functions
+ *****************************************************************************/
+static int bluetooth_open (struct tty_struct *tty, struct file * filp)
+{
+       struct usb_bluetooth *bluetooth;
+       int result;
+
+       dbg(__FUNCTION__);
+
+       /* initialize the pointer incase something fails */
+       tty->driver_data = NULL;
+
+       /* get the bluetooth object associated with this tty pointer */
+       bluetooth = get_bluetooth_by_minor (MINOR(tty->device));
+
+       if (bluetooth_paranoia_check (bluetooth, __FUNCTION__)) {
+               return -ENODEV;
+       }
+
+       if (bluetooth->active) {
+               dbg (__FUNCTION__ " - device already open");
+               return -EINVAL;
+       }
+
+       /* set up our structure making the tty driver remember our object, and us it */
+       tty->driver_data = bluetooth;
+       bluetooth->tty = tty;
+
+       bluetooth->active = 1;
+
+       /* Reset the packet position counters */
+       bluetooth->int_packet_pos = 0;
+       bluetooth->bulk_packet_pos = 0;
+
+#ifndef BTBUGGYHARDWARE
+       /* Start reading from the device */
+       result = usb_submit_urb(bluetooth->read_urb);
+       if (result)
+               dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed with status %d", result);
+#endif
+       result = usb_submit_urb(bluetooth->interrupt_in_urb);
+       if (result)
+               dbg(__FUNCTION__ " - usb_submit_urb(interrupt in) failed with status %d", result);
+
+       return 0;
+}
+
+
+static void bluetooth_close (struct tty_struct *tty, struct file * filp)
+{
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+       int i;
+
+       if (!bluetooth) {
+               return;
+       }
+
+       dbg(__FUNCTION__);
+
+       if (!bluetooth->active) {
+               dbg (__FUNCTION__ " - device not opened");
+               return;
+       }
+
+       /* shutdown any bulk reads and writes that might be going on */
+       for (i = 0; i < NUM_BULK_URBS; ++i)
+               usb_unlink_urb (bluetooth->write_urb_pool[i]);
+       usb_unlink_urb (bluetooth->read_urb);
+
+       bluetooth->active = 0;
+}
+
+
+static int bluetooth_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count)
+{
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+       struct urb *urb = NULL;
+       unsigned char *new_buffer;
+       const unsigned char *current_position;
+       int status;
+       int bytes_sent;
+       int buffer_size;
+       int i;
+
+       if (!bluetooth) {
+               return -ENODEV;
+       }
+
+       dbg(__FUNCTION__ " - %d byte(s)", count);
+
+       if (!bluetooth->active) {
+               dbg (__FUNCTION__ " - device not opened");
+               return -EINVAL;
+       }
+
+       if (count == 0) {
+               dbg(__FUNCTION__ " - write request of 0 bytes");
+               return 0;
+       }
+       if (count == 1) {
+               dbg(__FUNCTION__ " - write request only included type %d", buf[0]);
+               return 1;
+       }
+
+#ifdef DEBUG
+       printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ " - length = %d, data = ", count);
+       for (i = 0; i < count; ++i) {
+               printk ("%.2x ", buf[i]);
+       }
+       printk ("\n");
+#endif
+
+       switch (*buf) {
+               /* First byte indicates the type of packet */
+               case CMD_PKT:
+                       /* dbg(__FUNCTION__ "- Send cmd_pkt len:%d", count);*/
+
+                       if (in_interrupt()){
+                               printk("cmd_pkt from interrupt!\n");
+                               return count;
+                       }
+
+                       new_buffer = kmalloc (count-1, GFP_KERNEL);
+
+                       if (!new_buffer) {
+                               err (__FUNCTION__ "- out of memory.");
+                               return -ENOMEM;
+                       }
+
+                       if (from_user)
+                               copy_from_user (new_buffer, buf+1, count-1);
+                       else
+                               memcpy (new_buffer, buf+1, count-1);
+
+                       if (bluetooth_ctrl_msg (bluetooth, 0x00, 0x00, new_buffer, count-1) != 0) {
+                               kfree (new_buffer);
+                               return 0;
+                       }
+
+                       /* need to free new_buffer somehow... FIXME */
+                       return count;
+
+               case ACL_PKT:
+                       current_position = buf;
+                       ++current_position;
+                       --count;
+                       bytes_sent = 0;
+
+                       while (count > 0) {
+                               urb = NULL;
+
+                               /* try to find a free urb in our list */
+                               for (i = 0; i < NUM_BULK_URBS; ++i) {
+                                       if (bluetooth->write_urb_pool[i]->status != -EINPROGRESS) {
+                                               urb = bluetooth->write_urb_pool[i];
+                                               break;
+                                       }
+                               }
+                               if (urb == NULL) {
+                                       dbg (__FUNCTION__ " - no free urbs");
+                                       return bytes_sent;
+                               }
+                               
+                               /* free up the last buffer that this urb used */
+                               if (urb->transfer_buffer != NULL) {
+                                       kfree(urb->transfer_buffer);
+                                       urb->transfer_buffer = NULL;
+                               }
+
+                               buffer_size = MIN (count, bluetooth->bulk_out_size);
+                               
+                               new_buffer = kmalloc (buffer_size, GFP_KERNEL);
+                               if (new_buffer == NULL) {
+                                       err(__FUNCTION__" no more kernel memory...");
+                                       return bytes_sent;
+                               }
+
+                               if (from_user)
+                                       copy_from_user(new_buffer, current_position, buffer_size);
+                               else
+                                       memcpy (new_buffer, current_position, buffer_size);
+
+                               /* build up our urb */
+                               FILL_BULK_URB (urb, bluetooth->dev, usb_sndbulkpipe(bluetooth->dev, bluetooth->bulk_out_endpointAddress),
+                                               new_buffer, buffer_size, bluetooth_write_bulk_callback, bluetooth);
+                               urb->transfer_flags |= USB_QUEUE_BULK;
+
+                               /* send it down the pipe */
+                               status = usb_submit_urb(urb);
+                               if (status)
+                                       dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status);
+#ifdef BTBUGGYHARDWARE
+                               /* A workaround for the stalled data bug */
+                               /* May or may not be needed...*/
+                               if (count != 0) {
+                                       udelay(500);
+                               }
+#endif
+                               current_position += buffer_size;
+                               bytes_sent += buffer_size;
+                               count -= buffer_size;
+                       }
+
+                       return bytes_sent + 1;
+               
+               default :
+                       dbg(__FUNCTION__" - unsupported (at this time) write type");
+       }
+
+       return 0;
+} 
+
+
+static int bluetooth_write_room (struct tty_struct *tty) 
+{
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+       int room = 0;
+       int i;
+
+       if (!bluetooth) {
+               return -ENODEV;
+       }
+
+       dbg(__FUNCTION__);
+
+       if (!bluetooth->active) {
+               dbg (__FUNCTION__ " - device not open");
+               return -EINVAL;
+       }
+
+       for (i = 0; i < NUM_BULK_URBS; ++i) {
+               if (bluetooth->write_urb_pool[i]->status != -EINPROGRESS) {
+                       room += bluetooth->bulk_out_size;
+               }
+       }
+
+       dbg(__FUNCTION__ " - returns %d", room);
+       return room;
+}
+
+
+static int bluetooth_chars_in_buffer (struct tty_struct *tty) 
+{
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+       int chars = 0;
+       int i;
+
+       if (!bluetooth) {
+               return -ENODEV;
+       }
+
+       if (!bluetooth->active) {
+               dbg (__FUNCTION__ " - device not open");
+               return -EINVAL;
+       }
+
+       for (i = 0; i < NUM_BULK_URBS; ++i) {
+               if (bluetooth->write_urb_pool[i]->status == -EINPROGRESS) {
+                       chars += bluetooth->write_urb_pool[i]->transfer_buffer_length;
+               }
+       }
+
+       dbg (__FUNCTION__ " - returns %d", chars);
+       return chars;
+}
+
+
+static void bluetooth_throttle (struct tty_struct * tty)
+{
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+
+       if (!bluetooth) {
+               return;
+       }
+
+       dbg(__FUNCTION__);
+
+       if (!bluetooth->active) {
+               dbg (__FUNCTION__ " - device not open");
+               return;
+       }
+       
+       dbg(__FUNCTION__ " unsupported (at this time)");
+
+       return;
+}
+
+
+static void bluetooth_unthrottle (struct tty_struct * tty)
+{
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+
+       if (!bluetooth) {
+               return;
+       }
+
+       dbg(__FUNCTION__);
+
+       if (!bluetooth->active) {
+               dbg (__FUNCTION__ " - device not open");
+               return;
+       }
+
+       dbg(__FUNCTION__ " unsupported (at this time)");
+}
+
+
+static int bluetooth_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
+{
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+
+       if (!bluetooth) {
+               return -ENODEV;
+       }
+
+       dbg(__FUNCTION__ " - cmd 0x%.4x", cmd);
+
+       if (!bluetooth->active) {
+               dbg (__FUNCTION__ " - device not open");
+               return -ENODEV;
+       }
+
+       /* FIXME!!! */
+       return -ENOIOCTLCMD;
+}
+
+
+static void bluetooth_set_termios (struct tty_struct *tty, struct termios * old)
+{
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+
+       if (!bluetooth) {
+               return;
+       }
+
+       dbg(__FUNCTION__);
+
+       if (!bluetooth->active) {
+               dbg (__FUNCTION__ " - device not open");
+               return;
+       }
+
+       /* FIXME!!! */
+
+       return;
+}
+
+
+#ifdef BTBUGGYHARDWARE
+void btusb_enable_bulk_read(struct tty_struct *tty){
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+
+       if (!bluetooth) {
+               return;
+       }
+
+       dbg(__FUNCTION__);
+
+       if (!bluetooth->active) {
+               dbg (__FUNCTION__ " - device not open");
+               return;
+       }
+
+       if (bluetooth->read_urb)
+               if (usb_submit_urb(bluetooth->read_urb))
+                       dbg (__FUNCTION__ " - usb_submit_urb(read bulk) failed");
+}
+
+void btusb_disable_bulk_read(struct tty_struct *tty){
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__);
+
+       if (!bluetooth) {
+               return;
+       }
+
+       dbg(__FUNCTION__);
+
+       if (!bluetooth->active) {
+               dbg (__FUNCTION__ " - device not open");
+               return;
+       }
+
+       if ((bluetooth->read_urb) && (bluetooth->read_urb->actual_length))
+               usb_unlink_urb(bluetooth->read_urb);
+}
+#endif
+
+
+/*****************************************************************************
+ * urb callback functions
+ *****************************************************************************/
+
+
+static void bluetooth_int_callback (struct urb *urb)
+{
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
+       unsigned char *data = urb->transfer_buffer;
+       unsigned int i;
+       unsigned int count = urb->actual_length;
+       unsigned int packet_size;
+
+       dbg(__FUNCTION__);
+
+       if (!bluetooth) {
+               dbg(__FUNCTION__ " - bad bluetooth pointer, exiting");
+               return;
+       }
+
+       if (urb->status) {
+               dbg(__FUNCTION__ " - nonzero int status received: %d", urb->status);
+               return;
+       }
+
+       if (!count) {
+               dbg(__FUNCTION__ " - zero length int");
+               return;
+       }
+
+
+#ifdef DEBUG
+       if (count) {
+               printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ "- length = %d, data = ", count);
+               for (i = 0; i < count; ++i) {
+                       printk ("%.2x ", data[i]);
+               }
+               printk ("\n");
+       }
+#endif
+
+#ifdef BTBUGGYHARDWARE
+       if ((count >= 2) && (data[0] == 0xFF) && (data[1] == 0x00)) {
+               data += 2;
+               count -= 2;
+       }
+       if (count == 0) {
+               urb->actual_length = 0;
+               return;
+       }
+#endif
+       /* We add  a packet type identifier to the beginning of each
+          HCI frame.  This makes the data in the tty look like a
+          serial USB devices.  Each HCI frame can be broken across
+          multiple URBs so we buffer them until we have a full hci
+          packet */
+
+       if (!bluetooth->int_packet_pos) {
+               bluetooth->int_buffer[0] = EVENT_PKT;
+               bluetooth->int_packet_pos++;
+       }
+       
+       if (bluetooth->int_packet_pos + count > EVENT_BUFFER_SIZE) {
+               err(__FUNCTION__ " - exceeded EVENT_BUFFER_SIZE");
+               bluetooth->int_packet_pos = 0;
+               return;
+       }
+
+       memcpy (&bluetooth->int_buffer[bluetooth->int_packet_pos],
+               urb->transfer_buffer, count);
+       bluetooth->int_packet_pos += count;
+       urb->actual_length = 0;
+
+       if (bluetooth->int_packet_pos >= EVENT_HDR_SIZE)
+               packet_size = bluetooth->int_buffer[2];
+       else
+               return;
+
+       if (packet_size + EVENT_HDR_SIZE < bluetooth->int_packet_pos) {
+               err(__FUNCTION__ " - packet was too long");
+               bluetooth->int_packet_pos = 0;
+               return;
+       }
+
+       if (packet_size + EVENT_HDR_SIZE == bluetooth->int_packet_pos){
+               for (i = 0; i < bluetooth->int_packet_pos; ++i)
+                       tty_insert_flip_char(bluetooth->tty, bluetooth->int_buffer[i], 0);
+               tty_flip_buffer_push(bluetooth->tty);
+
+               bluetooth->int_packet_pos = 0;
+       }
+}
+
+
+static void bluetooth_ctrl_callback (struct urb *urb)
+{
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
+
+       dbg(__FUNCTION__);
+
+       if (!bluetooth) {
+               dbg(__FUNCTION__ " - bad bluetooth pointer, exiting");
+               return;
+       }
+
+       if (urb->status) {
+               dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);
+               return;
+       }
+}
+
+
+static void bluetooth_read_bulk_callback (struct urb *urb)
+{
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
+       unsigned char *data = urb->transfer_buffer;
+       unsigned int count = urb->actual_length;
+       unsigned int i;
+       uint packet_size;
+
+#ifdef BTBUGGYHARDWARE
+       if ((count == 4) && (data[0] == 0x00) && (data[1] == 0x00)
+           && (data[2] == 0x00) && (data[3] == 0x00)) {
+               urb->actual_length = 0;
+               if (usb_submit_urb(urb))
+                       dbg(__FUNCTION__ " - failed resubmitting read urb");
+
+               return;
+       }
+#endif
+
+       dbg(__FUNCTION__);
+
+       if (!bluetooth) {
+               dbg(__FUNCTION__ " - bad bluetooth pointer, exiting");
+               goto exit;
+       }
+
+       if (urb->status) {
+               dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);
+               goto exit;
+       }
+
+       if (!count) {
+               dbg(__FUNCTION__ " - zero length read bulk");
+               goto exit;
+       }
+
+#ifdef DEBUG
+       if (count) {
+               printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ "- length = %d, data = ", count);
+               for (i = 0; i < count; ++i) {
+                       printk ("%.2x ", data[i]);
+               }
+               printk ("\n");
+       }
+#endif
+       /* We add  a packet type identifier to the beginning of each
+          HCI frame.  This makes the data in the tty look like a
+          serial USB devices.  Each HCI frame can be broken across
+          multiple URBs so we buffer them until we have a full hci
+          packet */
+       
+       if (!bluetooth->bulk_packet_pos) {
+               bluetooth->bulk_buffer[0] = ACL_PKT;
+               bluetooth->bulk_packet_pos++;
+       }
+
+       if (bluetooth->bulk_packet_pos + count > ACL_BUFFER_SIZE) {
+               err(__FUNCTION__ " - exceeded ACL_BUFFER_SIZE");
+               bluetooth->bulk_packet_pos = 0;
+               goto exit;
+       }
+
+       memcpy (&bluetooth->bulk_buffer[bluetooth->bulk_packet_pos],
+               urb->transfer_buffer, count);
+       bluetooth->bulk_packet_pos += count;
+       urb->actual_length = 0;
+
+       if (bluetooth->bulk_packet_pos >= ACL_HDR_SIZE) {
+               packet_size = CHAR2INT16(bluetooth->bulk_buffer[4],bluetooth->bulk_buffer[3]);
+       } else {
+               goto exit;
+       }
+
+       if (packet_size + ACL_HDR_SIZE < bluetooth->bulk_packet_pos) {
+               err(__FUNCTION__ " - packet was too long");
+               bluetooth->bulk_packet_pos = 0;
+               goto exit;
+       }
+
+       if (packet_size + ACL_HDR_SIZE == bluetooth->bulk_packet_pos) {
+               for (i = 0; i < bluetooth->bulk_packet_pos; ++i)
+                       tty_insert_flip_char(bluetooth->tty, bluetooth->bulk_buffer[i], 0);
+               tty_flip_buffer_push(bluetooth->tty);
+               bluetooth->bulk_packet_pos = 0;
+       }       
+
+exit:
+       if (usb_submit_urb(urb))
+               dbg(__FUNCTION__ " - failed resubmitting read urb");
+
+       return;
+}
+
+
+static void bluetooth_write_bulk_callback (struct urb *urb)
+{
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
+
+       dbg(__FUNCTION__);
+
+       if (!bluetooth) {
+               dbg(__FUNCTION__ " - bad bluetooth pointer, exiting");
+               return;
+       }
+
+       if (urb->status) {
+               dbg(__FUNCTION__ " - nonzero write bulk status received: %d", urb->status);
+               return;
+       }
+
+       /* wake up our little function to let the tty layer know that something happened */
+       queue_task(&bluetooth->tqueue, &tq_immediate);
+       mark_bh(IMMEDIATE_BH);
+       return;
+}
+
+
+static void bluetooth_softint(void *private)
+{
+       struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)private, __FUNCTION__);
+       struct tty_struct *tty;
+
+       dbg(__FUNCTION__);
+
+       if (!bluetooth) {
+               return;
+       }
+
+       tty = bluetooth->tty;
+       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) {
+               dbg(__FUNCTION__ " - write wakeup call.");
+               (tty->ldisc.write_wakeup)(tty);
+       }
+
+       wake_up_interruptible(&tty->write_wait);
+}
+
+
+static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum)
+{
+       struct usb_bluetooth *bluetooth = NULL;
+       struct usb_interface_descriptor *interface;
+       struct usb_endpoint_descriptor *endpoint;
+       struct usb_endpoint_descriptor *interrupt_in_endpoint[8];
+       struct usb_endpoint_descriptor *bulk_in_endpoint[8];
+       struct usb_endpoint_descriptor *bulk_out_endpoint[8];
+       int control_out_endpoint;
+
+       int minor;
+       int buffer_size;
+       int i;
+       int num_interrupt_in = 0;
+       int num_bulk_in = 0;
+       int num_bulk_out = 0;
+
+       /* see if this device has the proper class signature */
+       if ((dev->descriptor.bDeviceClass != WIRELESS_CLASS_CODE) || 
+           (dev->descriptor.bDeviceSubClass != RF_SUBCLASS_CODE) ||
+           (dev->descriptor.bDeviceProtocol != BLUETOOTH_PROGRAMMING_PROTOCOL_CODE)) {
+               dbg (__FUNCTION__ " - class signature %d, %d, %d did not match", 
+                    dev->descriptor.bDeviceClass, dev->descriptor.bDeviceSubClass,
+                    dev->descriptor.bDeviceProtocol);
+               return NULL;
+       }
+
+       interface = &dev->actconfig->interface[ifnum].altsetting[0];
+       control_out_endpoint = interface->bInterfaceNumber;
+
+       /* find the endpoints that we need */
+       for (i = 0; i < interface->bNumEndpoints; ++i) {
+               endpoint = &interface->endpoint[i];
+
+               if ((endpoint->bEndpointAddress & 0x80) &&
+                   ((endpoint->bmAttributes & 3) == 0x02)) {
+                       /* we found a bulk in endpoint */
+                       dbg("found bulk in");
+                       bulk_in_endpoint[num_bulk_in] = endpoint;
+                       ++num_bulk_in;
+               }
+
+               if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
+                   ((endpoint->bmAttributes & 3) == 0x02)) {
+                       /* we found a bulk out endpoint */
+                       dbg("found bulk out");
+                       bulk_out_endpoint[num_bulk_out] = endpoint;
+                       ++num_bulk_out;
+               }
+
+               if ((endpoint->bEndpointAddress & 0x80) &&
+                   ((endpoint->bmAttributes & 3) == 0x03)) {
+                       /* we found a interrupt in endpoint */
+                       dbg("found interrupt in");
+                       interrupt_in_endpoint[num_interrupt_in] = endpoint;
+                       ++num_interrupt_in;
+               }
+       }
+
+       /* according to the spec, we can only have 1 bulk_in, 1 bulk_out, and 1 interrupt_in endpoints */
+       if ((num_bulk_in != 1) ||
+           (num_bulk_out != 1) ||
+           (num_interrupt_in != 1)) {
+               dbg (__FUNCTION__ " - improper number of endpoints. Bluetooth driver not bound.");
+               return NULL;
+       }
+
+       MOD_INC_USE_COUNT;
+       info("USB Bluetooth converter detected");
+
+       for (minor = 0; minor < BLUETOOTH_TTY_MINORS && bluetooth_table[minor]; ++minor)
+               ;
+       if (bluetooth_table[minor]) {
+               err("No more free Bluetooth devices");
+               MOD_DEC_USE_COUNT;
+               return NULL;
+       }
+
+       if (!(bluetooth = kmalloc(sizeof(struct usb_bluetooth), GFP_KERNEL))) {
+               err("Out of memory");
+               MOD_DEC_USE_COUNT;
+               return NULL;
+       }
+
+       memset(bluetooth, 0, sizeof(struct usb_bluetooth));
+
+       bluetooth->magic = USB_BLUETOOTH_MAGIC;
+       bluetooth->dev = dev;
+       bluetooth->minor = minor;
+       bluetooth->tqueue.routine = bluetooth_softint;
+       bluetooth->tqueue.data = bluetooth;
+
+       /* record the interface number for the control out */
+       bluetooth->control_out_bInterfaceNum = control_out_endpoint;
+       
+       /* create our control out urb pool */ 
+       for (i = 0; i < NUM_CONTROL_URBS; ++i) {
+               struct urb  *urb = usb_alloc_urb(0);
+               if (urb == NULL) {
+                       err("No free urbs available");
+                       goto probe_error;
+               }
+               urb->transfer_buffer = NULL;
+               bluetooth->control_urb_pool[i] = urb;
+       }
+
+       /* set up the endpoint information */
+       endpoint = bulk_in_endpoint[0];
+       bluetooth->read_urb = usb_alloc_urb (0);
+       if (!bluetooth->read_urb) {
+               err("No free urbs available");
+               goto probe_error;
+       }
+       buffer_size = endpoint->wMaxPacketSize;
+       bluetooth->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
+       if (!bluetooth->bulk_in_buffer) {
+               err("Couldn't allocate bulk_in_buffer");
+               goto probe_error;
+       }
+       FILL_BULK_URB(bluetooth->read_urb, dev, usb_rcvbulkpipe(dev, endpoint->bEndpointAddress),
+                     bluetooth->bulk_in_buffer, buffer_size, bluetooth_read_bulk_callback, bluetooth);
+
+       endpoint = bulk_out_endpoint[0];
+       bluetooth->bulk_out_endpointAddress = endpoint->bEndpointAddress;
+       
+       /* create our write urb pool */ 
+       for (i = 0; i < NUM_BULK_URBS; ++i) {
+               struct urb  *urb = usb_alloc_urb(0);
+               if (urb == NULL) {
+                       err("No free urbs available");
+                       goto probe_error;
+               }
+               urb->transfer_buffer = NULL;
+               bluetooth->write_urb_pool[i] = urb;
+       }
+       
+       bluetooth->bulk_out_size = endpoint->wMaxPacketSize * 2;
+
+       endpoint = interrupt_in_endpoint[0];
+       bluetooth->interrupt_in_urb = usb_alloc_urb(0);
+       if (!bluetooth->interrupt_in_urb) {
+               err("No free urbs available");
+               goto probe_error;
+       }
+       buffer_size = endpoint->wMaxPacketSize;
+       bluetooth->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
+       if (!bluetooth->interrupt_in_buffer) {
+               err("Couldn't allocate interrupt_in_buffer");
+               goto probe_error;
+       }
+       FILL_INT_URB(bluetooth->interrupt_in_urb, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress),
+                    bluetooth->interrupt_in_buffer, buffer_size, bluetooth_int_callback,
+                    bluetooth, endpoint->bInterval);
+
+       /* initialize the devfs nodes for this device and let the user know what bluetooths we are bound to */
+       tty_register_devfs (&bluetooth_tty_driver, 0, minor);
+       info("Bluetooth converter now attached to ttyBLUE%d (or usb/ttblue/%d for devfs)", minor, minor);
+
+       bluetooth_table[minor] = bluetooth;
+
+       return bluetooth; /* success */
+
+probe_error:
+       if (bluetooth->read_urb)
+               usb_free_urb (bluetooth->read_urb);
+       if (bluetooth->bulk_in_buffer)
+               kfree (bluetooth->bulk_in_buffer);
+       if (bluetooth->interrupt_in_urb)
+               usb_free_urb (bluetooth->interrupt_in_urb);
+       if (bluetooth->interrupt_in_buffer)
+               kfree (bluetooth->interrupt_in_buffer);
+       for (i = 0; i < NUM_BULK_URBS; ++i)
+               if (bluetooth->write_urb_pool[i])
+                       usb_free_urb (bluetooth->write_urb_pool[i]);
+       for (i = 0; i < NUM_CONTROL_URBS; ++i) 
+               if (bluetooth->control_urb_pool[i])
+                       usb_free_urb (bluetooth->control_urb_pool[i]);
+
+       bluetooth_table[minor] = NULL;
+
+       /* free up any memory that we allocated */
+       kfree (bluetooth);
+       MOD_DEC_USE_COUNT;
+       return NULL;
+}
+
+
+static void usb_bluetooth_disconnect(struct usb_device *dev, void *ptr)
+{
+       struct usb_bluetooth *bluetooth = (struct usb_bluetooth *) ptr;
+       int i;
+
+       if (bluetooth) {
+               if ((bluetooth->active) && (bluetooth->tty))
+                       tty_hangup(bluetooth->tty);
+
+               bluetooth->active = 0;
+
+               if (bluetooth->read_urb) {
+                       usb_unlink_urb (bluetooth->read_urb);
+                       usb_free_urb (bluetooth->read_urb);
+               }
+               if (bluetooth->bulk_in_buffer)
+                       kfree (bluetooth->bulk_in_buffer);
+
+               if (bluetooth->interrupt_in_urb) {
+                       usb_unlink_urb (bluetooth->interrupt_in_urb);
+                       usb_free_urb (bluetooth->interrupt_in_urb);
+               }
+               if (bluetooth->interrupt_in_buffer)
+                       kfree (bluetooth->interrupt_in_buffer);
+
+               tty_unregister_devfs (&bluetooth_tty_driver, bluetooth->minor);
+
+               for (i = 0; i < NUM_BULK_URBS; ++i) {
+                       if (bluetooth->write_urb_pool[i]) {
+                               usb_unlink_urb (bluetooth->write_urb_pool[i]);
+                               if (bluetooth->write_urb_pool[i]->transfer_buffer)
+                                       kfree (bluetooth->write_urb_pool[i]->transfer_buffer);
+                               usb_free_urb (bluetooth->write_urb_pool[i]);
+                       }
+               }
+               for (i = 0; i < NUM_CONTROL_URBS; ++i) {
+                       if (bluetooth->control_urb_pool[i]) {
+                               usb_unlink_urb (bluetooth->control_urb_pool[i]);
+                               if (bluetooth->control_urb_pool[i]->transfer_buffer)
+                                       kfree (bluetooth->control_urb_pool[i]->transfer_buffer);
+                               usb_free_urb (bluetooth->control_urb_pool[i]);
+                       }
+               }
+               
+               info("Bluetooth converter now disconnected from ttyBLUE%d", bluetooth->minor);
+
+               bluetooth_table[bluetooth->minor] = NULL;
+
+               /* free up any memory that we allocated */
+               kfree (bluetooth);
+
+       } else {
+               info("device disconnected");
+       }
+
+       MOD_DEC_USE_COUNT;
+}
+
+
+static struct tty_driver bluetooth_tty_driver = {
+       magic:                  TTY_DRIVER_MAGIC,
+       driver_name:            "usb-bluetooth",
+       name:                   "usb/ttblue/%d",
+       major:                  BLUETOOTH_TTY_MAJOR,
+       minor_start:            0,
+       num:                    BLUETOOTH_TTY_MINORS,
+       type:                   TTY_DRIVER_TYPE_SERIAL,
+       subtype:                SERIAL_TYPE_NORMAL,
+       flags:                  TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
+
+       refcount:               &bluetooth_refcount,
+       table:                  bluetooth_tty,
+       termios:                bluetooth_termios,
+       termios_locked:         bluetooth_termios_locked,
+
+       open:                   bluetooth_open,
+       close:                  bluetooth_close,
+       write:                  bluetooth_write,
+       write_room:             bluetooth_write_room,
+       ioctl:                  bluetooth_ioctl,
+       set_termios:            bluetooth_set_termios,
+       throttle:               bluetooth_throttle,
+       unthrottle:             bluetooth_unthrottle,
+       chars_in_buffer:        bluetooth_chars_in_buffer,
+};
+
+
+int usb_bluetooth_init(void)
+{
+       int i;
+       int result;
+
+       /* Initalize our global data */
+       for (i = 0; i < BLUETOOTH_TTY_MINORS; ++i) {
+               bluetooth_table[i] = NULL;
+       }
+
+       info ("USB Bluetooth support registered");
+
+       /* register the tty driver */
+       bluetooth_tty_driver.init_termios          = tty_std_termios;
+       bluetooth_tty_driver.init_termios.c_cflag  = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+       if (tty_register_driver (&bluetooth_tty_driver)) {
+               err(__FUNCTION__ " - failed to register tty driver");
+               return -1;
+       }
+
+       /* register the USB driver */
+       result = usb_register(&usb_bluetooth_driver);
+       if (result < 0) {
+               tty_unregister_driver(&bluetooth_tty_driver);
+               err("usb_register failed for the USB bluetooth driver. Error number %d", result);
+               return -1;
+       }
+
+       return 0;
+}
+
+
+void usb_bluetooth_exit(void)
+{
+       usb_deregister(&usb_bluetooth_driver);
+       tty_unregister_driver(&bluetooth_tty_driver);
+}
+
+
+module_init(usb_bluetooth_init);
+module_exit(usb_bluetooth_exit);
+
+
index bc0ea807a40b1608b4bbcacf0bb43d3ecd4291d7..49c152c4365a55bcaa5e521dfc98891e9a4e4f97 100644 (file)
  *     (at your option) any later version.
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
- * 
+ *
+ * (09/06/2000) gkh
+ *     Fixed oops in visor_exit.  Need to uncomment usb_unlink_urb call _after_
+ *     the host controller drivers set urb->dev = NULL when the urb is finished.
+ *
  * (08/08/2000) gkh
  *     Fixed endian problem in visor_startup.
  *     Fixed MOD_INC and MOD_DEC logic and the ability to open a port more 
@@ -457,7 +461,10 @@ void visor_exit (void)
        usb_serial_deregister (&handspring_device);
        
        for (i = 0; i < NUM_URBS; ++i) {
-               usb_unlink_urb(write_urb_pool[i]);
+               /* FIXME - uncomment the following usb_unlink_urb call when
+                * the host controllers get fixed to set urb->dev = NULL after
+                * the urb is finished.  Otherwise this call oopses. */
+               /* usb_unlink_urb(write_urb_pool[i]); */
                if (write_urb_pool[i]->transfer_buffer)
                        kfree(write_urb_pool[i]->transfer_buffer);
                usb_free_urb (write_urb_pool[i]);
index fa4dfa06afdd32621efb9c460d0b1e14cd2547ba..5d974fa7a75092071df731f8bbf03df86d1fd114 100644 (file)
@@ -275,9 +275,7 @@ cg_found:
        inode->i_nlink = 1;
        inode->i_dev = sb->s_dev;
        inode->i_uid = current->fsuid;
-       if (test_opt (sb, GRPID))
-               inode->i_gid = dir->i_gid;
-       else if (dir->i_mode & S_ISGID) {
+       if (dir->i_mode & S_ISGID) {
                inode->i_gid = dir->i_gid;
                if (S_ISDIR(mode))
                        mode |= S_ISGID;
index 207216323d18e64ef4a1399120b1b0b2d7f3206d..9dd7f86892eccda88a0d246d4b0dfe76b9ffe724 100644 (file)
@@ -16,7 +16,6 @@
 #ifndef _LINUX_EXT2_FS_SB
 #define _LINUX_EXT2_FS_SB
 
-#include <linux/ext2_fs.h>
 
 /*
  * The following is not needed anymore since the descriptors buffer
index 89e3bc6a50939f625613bdb08978b73c64a27db3..f66a22980ddb91f56f84189494f4c4aea10594fb 100644 (file)
@@ -23,8 +23,6 @@
 #include <linux/serial.h>
 #include <linux/locks.h>
 #include <linux/delay.h>
-#include <linux/minix_fs.h>
-#include <linux/ext2_fs.h>
 #include <linux/random.h>
 #include <linux/reboot.h>
 #include <linux/pagemap.h>