From: Linus Torvalds Date: Fri, 23 Nov 2007 20:18:44 +0000 (-0500) Subject: Import 2.2.7 X-Git-Tag: 2.2.7 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=a228ad145d4769fdb57e212178926e46ca337e44;p=history.git Import 2.2.7 --- diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 7e4f3d04e7c2..b558535aa94b 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -4,7 +4,7 @@ Richard Gooch - 27-JUN-1998 + 23-APR-1999 Conventions used in this document
@@ -129,7 +129,7 @@ struct file_system_type { name: the name of the filesystem type, such as "ext2", "iso9660", "msdos" and so on - fs_flags: various flags (i.e. if it is a read-only FS) + fs_flags: various flags (i.e. FS_REQUIRES_DEV, FS_NO_DCACHE, etc.) read_super: the method to call when a new instance of this filesystem should be mounted diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index f4a92cfd2453..fc6dce28f06f 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.157 1999/01/19 07:54:32 davem Exp $ +/* $Id: entry.S,v 1.158 1999/04/27 14:35:07 davem Exp $ * arch/sparc/kernel/entry.S: Sparc trap low-level entry points. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -874,7 +874,7 @@ C_LABEL(vac_hwflush_patch2_on): sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG ! We want error in %l5, vaddr in %l6 sun4c_fault: #ifdef CONFIG_SUN4 - sethi C_LABEL(sun4c_memerr_reg), %l4 + sethi %hi(C_LABEL(sun4c_memerr_reg)), %l4 ld [%l4+%lo(C_LABEL(sun4c_memerr_reg))], %l4 ! memerr ctrl reg addr ld [%l4], %l6 ! memerr ctrl reg ld [%l4 + 4], %l5 ! memerr vaddr reg @@ -956,7 +956,7 @@ sun4c_fault: sll %l6, 2, %l6 ld [%l4 + %l6], %l4 #ifdef CONFIG_SUN4 - sethi PAGE_MASK, %l6 + sethi %hi(PAGE_MASK), %l6 andcc %l4, %l6, %g0 #else andcc %l4, PAGE_MASK, %g0 @@ -1117,7 +1117,7 @@ C_LABEL(num_context_patch2): #ifndef CONFIG_SUN4 and %l4, PAGE_MASK, %l4 #else - sethi PAGE_MASK, %l6 + sethi %hi(PAGE_MASK), %l6 and %l4, %l6, %l4 #endif diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 90fcd884ac4f..5b63aa11ad60 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.186 1999/04/13 14:17:19 jj Exp $ +/* $Id: srmmu.c,v 1.187 1999/04/28 17:00:45 davem Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1949,12 +1949,13 @@ __initfunc(unsigned long srmmu_paging_init(unsigned long start_mem, unsigned lon /* Find the number of contexts on the srmmu. */ cpunode = prom_getchild(prom_root_node); num_contexts = 0; - while((cpunode = prom_getsibling(cpunode)) != 0) { + while(cpunode != 0) { prom_getstring(cpunode, "device_type", node_str, sizeof(node_str)); if(!strcmp(node_str, "cpu")) { num_contexts = prom_getintdefault(cpunode, "mmu-nctx", 0x8); break; } + cpunode = prom_getsibling(cpunode); } } diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c index a6d751e3a4ab..02f91a226e30 100644 --- a/arch/sparc64/kernel/cpu.c +++ b/arch/sparc64/kernel/cpu.c @@ -69,7 +69,7 @@ __initfunc(void cpu_probe(void)) fprs = fprs_read (); fprs_write (FPRS_FEF); - __asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]" : "=r" (ver) : "r" (&fpu_vers)); + __asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]" : "=&r" (ver) : "r" (&fpu_vers)); fprs_write (fprs); manuf = ((ver >> 48)&0xffff); diff --git a/drivers/block/rd.c b/drivers/block/rd.c index e8f4a0554be7..6aa91e3843a1 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c @@ -295,6 +295,8 @@ __initfunc(int rd_init(void)) #ifdef MODULE +MODULE_PARM (rd_size, "1i"); + int init_module(void) { int error = rd_init(); diff --git a/drivers/net/ppp.c b/drivers/net/ppp.c index 7a0a00063102..8fa3d8b3a582 100644 --- a/drivers/net/ppp.c +++ b/drivers/net/ppp.c @@ -4,7 +4,7 @@ * Al Longyear * Extensively rewritten by Paul Mackerras * - * ==FILEVERSION 990114== + * ==FILEVERSION 990331== * * NOTE TO MAINTAINERS: * If you modify this file at all, please set the number above to the @@ -45,9 +45,8 @@ #define PPP_MAX_RCV_QLEN 32 /* max # frames we queue up for pppd */ -/* $Id: ppp.c,v 1.19 1998/07/07 04:27:37 paulus Exp $ */ +/* $Id: ppp.c,v 1.24 1999/03/31 06:07:57 paulus Exp $ */ -#include #include #include #include @@ -61,6 +60,7 @@ #include #include #include +#include /* to get the struct task_struct */ #include /* used in new tty drivers */ #include /* used in new tty drivers */ #include @@ -90,6 +90,9 @@ #include #endif +typedef ssize_t rw_ret_t; +typedef size_t rw_count_t; + /* * Local functions */ @@ -101,9 +104,11 @@ static void ppp_unregister_compressor (struct compressor *cp); static void ppp_async_init(struct ppp *ppp); static void ppp_async_release(struct ppp *ppp); +static int ppp_tty_sync_push(struct ppp *ppp); static int ppp_tty_push(struct ppp *ppp); static int ppp_async_encode(struct ppp *ppp); static int ppp_async_send(struct ppp *, struct sk_buff *); +static int ppp_sync_send(struct ppp *, struct sk_buff *); static int ppp_ioctl(struct ppp *, unsigned int, unsigned long); static int ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp); @@ -186,10 +191,10 @@ EXPORT_SYMBOL(ppp_unregister_compressor); * TTY callbacks */ -static ssize_t ppp_tty_read(struct tty_struct *, struct file *, __u8 *, - size_t); -static ssize_t ppp_tty_write(struct tty_struct *, struct file *, const __u8 *, - size_t); +static rw_ret_t ppp_tty_read(struct tty_struct *, struct file *, __u8 *, + rw_count_t); +static rw_ret_t ppp_tty_write(struct tty_struct *, struct file *, const __u8 *, + rw_count_t); static int ppp_tty_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long); static unsigned int ppp_tty_poll(struct tty_struct *tty, struct file *filp, @@ -236,7 +241,6 @@ __u16 ppp_crc16_table[256] = 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; -EXPORT_SYMBOL(ppp_crc16_table); #ifdef CHECK_CHARACTERS static __u32 paritytab[8] = @@ -458,13 +462,13 @@ ppp_tty_close (struct tty_struct *tty) * Read a PPP frame from the rcv_q list, * waiting if necessary */ -static ssize_t +static rw_ret_t ppp_tty_read(struct tty_struct *tty, struct file *file, __u8 * buf, - size_t nr) + rw_count_t nr) { struct ppp *ppp = tty2ppp (tty); struct sk_buff *skb; - ssize_t len, err; + rw_ret_t len, err; /* * Validate the pointers @@ -546,9 +550,9 @@ out: * Writing to a tty in ppp line discipline sends a PPP frame. * Used by pppd to send control packets (LCP, etc.). */ -static ssize_t +static rw_ret_t ppp_tty_write(struct tty_struct *tty, struct file *file, const __u8 * data, - size_t count) + rw_count_t count) { struct ppp *ppp = tty2ppp (tty); __u8 *new_data; @@ -600,7 +604,7 @@ ppp_tty_write(struct tty_struct *tty, struct file *file, const __u8 * data, */ ppp_send_ctrl(ppp, skb); - return (ssize_t) count; + return (rw_ret_t) count; } /* @@ -798,6 +802,135 @@ ppp_tty_wakeup (struct tty_struct *tty) ppp_output_wakeup(ppp); } +/* + * Send a packet to the peer over a synchronous tty line. + * All encoding and FCS are handled by hardware. + * Addr/Ctrl and Protocol field compression implemented. + * Returns -1 iff the packet could not be accepted at present, + * 0 if the packet was accepted but we can't accept another yet, or + * 1 if we can accept another packet immediately. + * If this procedure returns 0, ppp_output_wakeup will be called + * exactly once. + */ +static int +ppp_sync_send(struct ppp *ppp, struct sk_buff *skb) +{ + unsigned char *data; + int islcp; + + CHECK_PPP(0); + + if (ppp->tpkt != NULL) + return -1; + ppp->tpkt = skb; + + data = ppp->tpkt->data; + + /* + * LCP packets with code values between 1 (configure-reqest) + * and 7 (code-reject) must be sent as though no options + * had been negotiated. + */ + islcp = PPP_PROTOCOL(data) == PPP_LCP + && 1 <= data[PPP_HDRLEN] && data[PPP_HDRLEN] <= 7; + + /* only reset idle time for data packets */ + if (PPP_PROTOCOL(data) < 0x8000) + ppp->last_xmit = jiffies; + ++ppp->stats.ppp_opackets; + ppp->stats.ppp_ooctects += ppp->tpkt->len; + + if ( !(data[2]) && (ppp->flags & SC_COMP_PROT) ) { + /* compress protocol field */ + data[2] = data[1]; + data[1] = data[0]; + skb_pull(ppp->tpkt,1); + data = ppp->tpkt->data; + } + + /* + * Do address/control compression + */ + if ((ppp->flags & SC_COMP_AC) && !islcp + && PPP_ADDRESS(data) == PPP_ALLSTATIONS + && PPP_CONTROL(data) == PPP_UI) { + /* strip addr and control field */ + skb_pull(ppp->tpkt,2); + } + + return ppp_tty_sync_push(ppp); +} + +/* + * Push a synchronous frame out to the tty. + * Returns 1 if frame accepted (or discarded), 0 otherwise. + */ +static int +ppp_tty_sync_push(struct ppp *ppp) +{ + int sent; + struct tty_struct *tty = ppp2tty(ppp); + unsigned long flags; + + CHECK_PPP(0); + + if (ppp->tpkt == NULL) + return 0; + + /* prevent reentrancy with tty_pushing flag */ + save_flags(flags); + cli(); + if (ppp->tty_pushing) { + /* record wakeup attempt so we don't loose */ + /* a wakeup call while doing push processing */ + ppp->woke_up=1; + restore_flags(flags); + return 0; + } + ppp->tty_pushing = 1; + restore_flags(flags); + + if (tty == NULL || tty->disc_data != (void *) ppp) + goto flush; + + for(;;){ + ppp->woke_up=0; + + /* Note: Sync driver accepts complete frame or nothing */ + tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); + sent = tty->driver.write(tty, 0, ppp->tpkt->data, ppp->tpkt->len); + if (sent < 0) { + /* write error (possible loss of CD) */ + /* record error and discard current packet */ + ppp->stats.ppp_oerrors++; + break; + } + ppp->stats.ppp_obytes += sent; + if (sent < ppp->tpkt->len) { + /* driver unable to accept frame just yet */ + save_flags(flags); + cli(); + if (ppp->woke_up) { + /* wake up called while processing */ + /* try to send the frame again */ + restore_flags(flags); + continue; + } + /* wait for wakeup callback to try send again */ + ppp->tty_pushing = 0; + restore_flags(flags); + return 0; + } + break; + } +flush: + /* done with current packet (sent or discarded) */ + kfree_skb(ppp->tpkt); + ppp->tpkt = 0; + ppp->tty_pushing = 0; + return 1; +} + /* * Send a packet to the peer over an async tty line. * Returns -1 iff the packet could not be accepted at present, @@ -830,6 +963,9 @@ ppp_tty_push(struct ppp *ppp) { int avail, sent, done = 0; struct tty_struct *tty = ppp2tty(ppp); + + if ( ppp->flags & SC_SYNC ) + return ppp_tty_sync_push(ppp); CHECK_PPP(0); if (ppp->tty_pushing) @@ -1028,6 +1164,73 @@ ppp_tty_receive (struct tty_struct *tty, const __u8 * data, ppp->stats.ppp_ibytes += count; skb = ppp->rpkt; + + if ( ppp->flags & SC_SYNC ) { + /* synchronous mode */ + + if (ppp->toss==0xE0) { + /* this is the 1st frame, reset vj comp */ + ppp_receive_error(ppp); + ppp->toss = 0; + } + + /* + * Allocate an skbuff for frame. + * The 128 is room for VJ header expansion. + */ + + if (skb == NULL) + skb = dev_alloc_skb(ppp->mru + 128 + PPP_HDRLEN); + + if (skb == NULL) { + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "couldn't " + "alloc skb for recv\n"); + } else { + /* + * Decompress A/C and protocol compression here. + */ + p = skb_put(skb, 2); + p[0] = PPP_ALLSTATIONS; + p[1] = PPP_UI; + if (*data == PPP_ALLSTATIONS) { + data += 2; + count -= 2; + } + if ((*data & 1) != 0) { + p = skb_put(skb, 1); + p[0] = 0; + } + + /* copy frame to socket buffer */ + p = skb_put(skb, count); + memcpy(p,data,count); + + /* + * Check if we've overflowed the MRU + */ + if (skb->len >= ppp->mru + PPP_HDRLEN + 2 + || skb_tailroom(skb) <= 0) { + ++ppp->estats.rx_length_errors; + if (ppp->flags & SC_DEBUG) + printk(KERN_DEBUG "rcv frame too long: " + "len=%d mru=%d hroom=%d troom=%d\n", + skb->len, ppp->mru, skb_headroom(skb), + skb_tailroom(skb)); + } else { + if (!ppp_receive_frame(ppp, skb)) { + kfree_skb(skb); + ppp_receive_error(ppp); + } + } + + /* Reset for the next frame */ + skb = NULL; + } + ppp->rpkt = skb; + return; + } + while (count-- > 0) { /* * Collect the character and error condition for the character. @@ -1291,9 +1494,6 @@ ppp_dev_close (struct device *dev) CHECK_PPP_MAGIC(ppp); - /* ppp_dev_close may be called with tbusy==1 so we must set it to 0 */ - dev->tbusy=0; - MOD_DEC_USE_COUNT; return 0; @@ -1850,23 +2050,25 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb) return 0; } - /* - * Verify the FCS of the frame and discard the FCS characters - * from the end of the buffer. - */ - if (ppp->rfcs != PPP_GOODFCS) { - if (ppp->flags & SC_DEBUG) { - printk(KERN_DEBUG - "ppp: frame with bad fcs, length = %d\n", - count); - ppp_print_buffer("bad frame", data, count); + if ( !(ppp->flags & SC_SYNC) ) { + /* + * Verify the FCS of the frame and discard the FCS characters + * from the end of the buffer. + */ + if (ppp->rfcs != PPP_GOODFCS) { + if (ppp->flags & SC_DEBUG) { + printk(KERN_DEBUG + "ppp: frame with bad fcs, length = %d\n", + count); + ppp_print_buffer("bad frame", data, count); + } + ++ppp->estats.rx_crc_errors; + return 0; } - ++ppp->estats.rx_crc_errors; - return 0; + count -= 2; /* ignore the fcs characters */ + skb_trim(skb, count); } - count -= 2; /* ignore the fcs characters */ - skb_trim(skb, count); - + /* * Process the active decompressor. */ @@ -2055,7 +2257,7 @@ rcv_proto_vjc_comp(struct ppp *ppp, struct sk_buff *skb) return 0; new_count = slhc_uncompress(ppp->slcomp, skb->data + PPP_HDRLEN, skb->len - PPP_HDRLEN); - if (new_count<=0) { + if (new_count <= 0) { if (ppp->flags & SC_DEBUG) printk(KERN_NOTICE "ppp: error in VJ decompression\n"); @@ -2234,7 +2436,10 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) /* * Send the frame */ - ret = ppp_async_send(ppp, skb); + if ( ppp->flags & SC_SYNC ) + ret = ppp_sync_send(ppp, skb); + else + ret = ppp_async_send(ppp, skb); if (ret > 0) { /* we can release the lock */ ppp->xmit_busy = 0; diff --git a/drivers/sbus/audio/cs4231.c b/drivers/sbus/audio/cs4231.c index f236fb6be035..61eca133629a 100644 --- a/drivers/sbus/audio/cs4231.c +++ b/drivers/sbus/audio/cs4231.c @@ -2183,7 +2183,6 @@ static int eb4231_attach(struct sparcaudio_driver *drv, sizeof(struct linux_ebus_dma)); release_region((unsigned long)cs4231_chip->eb2p, sizeof(struct linux_ebus_dma)); - cleanup: kfree(drv->private); return -EIO; } diff --git a/drivers/sbus/char/pcikbd.c b/drivers/sbus/char/pcikbd.c index 6e14d6d7c7d2..b73740922ac8 100644 --- a/drivers/sbus/char/pcikbd.c +++ b/drivers/sbus/char/pcikbd.c @@ -1,4 +1,4 @@ -/* $Id: pcikbd.c,v 1.25 1999/02/08 07:01:48 ecd Exp $ +/* $Id: pcikbd.c,v 1.26 1999/04/28 11:55:42 davem Exp $ * pcikbd.c: Ultra/AX PC keyboard support. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -228,8 +228,6 @@ unsigned char pcikbd_sysrq_xlate[128] = "\r\000/"; /* 0x60 - 0x6f */ #endif -static unsigned int prev_scancode = 0; - int pcikbd_setkeycode(unsigned int scancode, unsigned int keycode) { if(scancode < SC_LIM || scancode > 255 || keycode > 127) diff --git a/drivers/usb/Config.in b/drivers/usb/Config.in index b7955ad3041d..669478cd0a6a 100644 --- a/drivers/usb/Config.in +++ b/drivers/usb/Config.in @@ -12,13 +12,14 @@ mainmenu_option next_comment comment 'USB drivers - not for the faint of heart' if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'Support for USB (EXPERIMENTAL!)' CONFIG_USB - if [ "$CONFIG_USB" = "y" ]; then + tristate 'Support for USB (EXPERIMENTAL!)' CONFIG_USB + if [ ! "$CONFIG_USB" = "n" ]; then bool 'UHCI (intel PIIX4 and others) support?' CONFIG_USB_UHCI bool 'OHCI (compaq and some others) support?' CONFIG_USB_OHCI bool 'USB mouse support' CONFIG_USB_MOUSE bool 'USB keyboard support' CONFIG_USB_KBD + bool 'USB audio parsing support' CONFIG_USB_AUDIO fi fi diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 867560883c06..0d3eadacad07 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -16,44 +16,60 @@ ALL_SUB_DIRS := $(SUB_DIRS) L_TARGET := usb.a M_OBJS := -L_OBJS := usb.o hub.o usb-debug.o +L_OBJS := LX_OBJS := +USBX_OBJS := usb.o hub.o usb-debug.o -ifeq ($(CONFIG_USB_UHCI),y) - L_OBJS += uhci.o uhci-debug.o -else - ifeq ($(CONFIG_USB_UHCI),m) - MX_OBJS += usb-uhci.o uhci-debug.o - endif +ifeq ($(CONFIG_USB_MOUSE),y) + USBX_OBJS += mouse.o endif -ifeq ($(CONFIG_USB_OHCI),y) - L_OBJS += ohci.o ohci-debug.o -else - ifeq ($(CONFIG_USB_UHCI),m) - MX_OBJS += ohci.o ohci-debug.o - endif +ifeq ($(CONFIG_USB_KBD),y) + USBX_OBJS += keyboard.o keymap.o endif -ifeq ($(CONFIG_USB_MOUSE),y) - L_OBJS += mouse.o -else - ifeq ($(CONFIG_USB_UHCI),m) - MX_OBJS += mouse.o +ifeq ($(CONFIG_USB_AUDIO),y) + USBX_OBJS += audio.o +endif + +ifeq ($(CONFIG_USB), y) + L_OBJS += $(USBX_OBJS) +endif + +ifeq ($(CONFIG_USB_UHCI),y) + ifeq ($(CONFIG_USB), y) + L_OBJS += uhci.o uhci-debug.o + else + ifeq ($(CONFIG_USB),m) + M_OBJS += usb-uhci.o + MIX_OBJS += $(USBX_OBJS) + endif endif endif -ifeq ($(CONFIG_USB_KBD),y) - L_OBJS += keyboard.o keymap.o -else - ifeq ($(CONFIG_USB_UHCI),m) - MX_OBJS += keyboard.o +ifeq ($(CONFIG_USB_OHCI),y) + ifeq ($(CONFIG_USB), y) + L_OBJS += ohci.o ohci-debug.o + else + ifeq ($(CONFIG_USB),m) + USBO_OBJS += ohci.o ohci-debug.o + M_OBJS += usb-ohci.o + MIX_OBJS += $(USBX_OBJS) + endif endif endif + include $(TOPDIR)/Rules.make keymap.o: keymap.c keymap.c: maps/serial.map maps/usb.map maps/fixup.map ./mkmap > $@ + +usb-uhci.o: uhci.o uhci-debug.o $(USBX_OBJS) + $(LD) $(LD_RFLAG) -r -o $@ uhci.o uhci-debug.o $(USBX_OBJS) + +usb-ohci.o: ohci.o ohci-debug.o $(USBX_OBJS) + $(LD) $(LD_RFLAG) -r -o $@ ohci.o ohci-debug.o $(USBX_OBJS) + diff --git a/drivers/usb/audio.c b/drivers/usb/audio.c new file mode 100644 index 000000000000..8b0c9d15c748 --- /dev/null +++ b/drivers/usb/audio.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include +#include "usb.h" + +static int usb_audio_probe(struct usb_device *dev); +static void usb_audio_disconnect(struct usb_device *dev); +static LIST_HEAD(usb_audio_list); + +struct usb_audio +{ + struct usb_device *dev; + struct list_head list; +}; + +static struct usb_driver usb_audio_driver = +{ + "audio", + usb_audio_probe, + usb_audio_disconnect, + {NULL, NULL} +}; + + +static int usb_audio_irq(int state, void *buffer, void *dev_id) +{ + struct usb_audio *aud = (struct usb_audio*) dev_id; + return 1; +} + +static int usb_audio_probe(struct usb_device *dev) +{ + struct usb_interface_descriptor *interface; + struct usb_endpoint_descriptor *endpoint; + struct usb_audio *aud; + + int i; + int na=0; + + interface = &dev->config[0].interface[0]; + + for(i=0;iconfig[0].bNumInterfaces;i++) + { + int x; + + endpoint = &interface->endpoint[i]; + + if(interface->bInterfaceClass != 1) + continue; + + printk(KERN_INFO "USB audio device detected.\n"); + + switch(interface->bInterfaceSubClass) + { + case 0x01: + printk(KERN_INFO "audio: Control device.\n"); + break; + case 0x02: + printk(KERN_INFO "audio: streaming.\n"); + break; + case 0x03: + printk(KERN_INFO "audio: nonstreaming.\n"); + break; + } + na++; + } + + if(na==0) + return -1; + + aud = kmalloc(sizeof(struct usb_audio), GFP_KERNEL); + if(aud) + { + memset(aud, 0, sizeof(*aud)); + aud->dev = dev; + dev->private = aud; + + endpoint = &interface->endpoint[0]; + +// usb_set_configuration(dev, dev->config[0].bConfigurationValue); +// usb_set_protocol(dev, 0); +// usb_set_idle(dev, 0, 0); + + usb_request_irq(dev, + usb_rcvctrlpipe(dev, endpoint->bEndpointAddress), + usb_audio_irq, + endpoint->bInterval, + aud); + + list_add(&aud->list, &usb_audio_list); + } + return 0; +} + +static void usb_audio_disconnect(struct usb_device *dev) +{ + struct usb_audio *aud = (struct usb_audio*) dev->private; + if(aud) + { + dev->private = NULL; + list_del(&aud->list); + kfree(aud); + } + printk(KERN_INFO "USB audio driver removed.\n"); +} + +int usb_audio_init(void) +{ + usb_register(&usb_audio_driver); + return 0; +} + +/* + * Support functions for parsing + */ + +void usb_audio_interface(struct usb_interface_descriptor *interface, u8 *data) +{ +} + +void usb_audio_endpoint(struct usb_endpoint_descriptor *interface, u8 *data) +{ +} + diff --git a/drivers/usb/inits.h b/drivers/usb/inits.h index d59848615b36..c1cc4f282c1d 100644 --- a/drivers/usb/inits.h +++ b/drivers/usb/inits.h @@ -1,3 +1,4 @@ int bp_mouse_init(void); int usb_kbd_init(void); +int usb_audio_init(void); int hub_init(void); diff --git a/drivers/usb/uhci.c b/drivers/usb/uhci.c index 244cdd9b237b..95311855d4d4 100644 --- a/drivers/usb/uhci.c +++ b/drivers/usb/uhci.c @@ -1182,9 +1182,16 @@ int uhci_init(void) if (retval < 0) continue; +#ifdef CONFIG_USB_MOUSE usb_mouse_init(); +#endif +#ifdef CONFIG_USB_KBD usb_kbd_init(); +#endif hub_init(); +#ifdef CONFIG_USB_AUDIO + usb_audio_init(); +#endif #ifdef CONFIG_APM apm_register_callback(&handle_apm_event); #endif diff --git a/drivers/usb/uhci.h b/drivers/usb/uhci.h index 0c351f1f6b93..f063356acc58 100644 --- a/drivers/usb/uhci.h +++ b/drivers/usb/uhci.h @@ -102,7 +102,7 @@ struct uhci_td { */ struct uhci; -#define UHCI_MAXTD 32 +#define UHCI_MAXTD 64 #define UHCI_MAXQH 16 diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c index cc6ed027c6ab..398f63a44182 100644 --- a/drivers/usb/usb.c +++ b/drivers/usb/usb.c @@ -101,43 +101,93 @@ void usb_device_descriptor(struct usb_device *dev) static int usb_expect_descriptor(unsigned char *ptr, int len, unsigned char desctype, unsigned char descindex) { int parsed = 0; + int n_len; + unsigned short n_desc; for (;;) { - unsigned short n_desc; - int n_len, i; + int i; if (len < descindex) return -1; n_desc = *(unsigned short *)ptr; + n_len = n_desc & 0xff; + if (n_desc == ((desctype << 8) + descindex)) - return parsed; + break; + + if (((n_desc >> 8)&0xFF) == desctype && + n_len > descindex) + { + printk("bug: oversized descriptor.\n"); + break; + } + + if (n_len < 2 || n_len > len) + { + printk("Short descriptor.\n"); + return -1; + } printk( "Expected descriptor %02X/%02X, got %02X/%02X - skipping\n", desctype, descindex, (n_desc >> 8) & 0xFF, n_desc & 0xFF); - n_len = n_desc & 0xff; - if (n_len < 2 || n_len > len) - return -1; for (i = 0 ; i < n_len; i++) printk(" %d %02x\n", i, ptr[i]); len -= n_len; ptr += n_len; parsed += n_len; } + + printk("Found %02X:%02X\n", + desctype, descindex); + return parsed; +} + +/* + * Parse the even more incomprehensible mess made of the USB spec + * by USB audio having private magic to go with it. + */ + +static int usb_check_descriptor(unsigned char *ptr, int len, unsigned char desctype) +{ + int n_len = ptr[0]; + + if (n_len < 2 || n_len > len) + { + printk("Short descriptor.\n"); + return -1; + } + + if (ptr[1] == desctype) + return 0; + + return -1; } -static int usb_parse_endpoint(struct usb_endpoint_descriptor *endpoint, unsigned char *ptr, int len) + +static int usb_parse_endpoint(struct usb_device *dev, struct usb_endpoint_descriptor *endpoint, unsigned char *ptr, int len) { int parsed = usb_expect_descriptor(ptr, len, USB_DT_ENDPOINT, 7); + int i; if (parsed < 0) return parsed; + memcpy(endpoint, ptr + parsed, ptr[parsed]); + + parsed += ptr[parsed]; + len -= ptr[parsed]; - memcpy(endpoint, ptr + parsed, 7); - return parsed + 7; + while((i = usb_check_descriptor(ptr+parsed, len, 0x25))>=0) + { + usb_audio_endpoint(endpoint, ptr+parsed+i); + len -= ptr[parsed+i]; + parsed += ptr[parsed+i]; + } + + return parsed;// + ptr[parsed]; } -static int usb_parse_interface(struct usb_interface_descriptor *interface, unsigned char *ptr, int len) +static int usb_parse_interface(struct usb_device *dev, struct usb_interface_descriptor *interface, unsigned char *ptr, int len) { int i; int parsed = usb_expect_descriptor(ptr, len, USB_DT_INTERFACE, 9); @@ -146,19 +196,29 @@ static int usb_parse_interface(struct usb_interface_descriptor *interface, unsig if (parsed < 0) return parsed; - memcpy(interface, ptr + parsed, 9); - len -= 9; - parsed += 9; + memcpy(interface, ptr + parsed, *ptr); + len -= ptr[parsed]; + parsed += ptr[parsed]; + while((i=usb_check_descriptor(ptr+parsed, len, 0x24))>=0) + { + usb_audio_interface(interface, ptr+parsed+i); + len -= ptr[parsed+i]; + parsed += ptr[parsed+i]; + } + if (interface->bNumEndpoints > USB_MAXENDPOINTS) + { + printk(KERN_WARNING "usb: too many endpoints.\n"); return -1; + } for (i = 0; i < interface->bNumEndpoints; i++) { - if(((USB_DT_HID << 8) | 9) == *(unsigned short*)(ptr + parsed)) { - parsed += 9; /* skip over the HID descriptor for now */ - len -= 9; - } - retval = usb_parse_endpoint(interface->endpoint + i, ptr + parsed, len); +// if(((USB_DT_HID << 8) | 9) == *(unsigned short*)(ptr + parsed)) { +// parsed += 9; /* skip over the HID descriptor for now */ +// len -= 9; +// } + retval = usb_parse_endpoint(dev, interface->endpoint + i, ptr + parsed, len); if (retval < 0) return retval; parsed += retval; len -= retval; @@ -166,7 +226,7 @@ static int usb_parse_interface(struct usb_interface_descriptor *interface, unsig return parsed; } -static int usb_parse_config(struct usb_config_descriptor *config, unsigned char *ptr, int len) +static int usb_parse_config(struct usb_device *dev, struct usb_config_descriptor *config, unsigned char *ptr, int len) { int i; int parsed = usb_expect_descriptor(ptr, len, USB_DT_CONFIG, 9); @@ -174,17 +234,21 @@ static int usb_parse_config(struct usb_config_descriptor *config, unsigned char if (parsed < 0) return parsed; - memcpy(config, ptr + parsed, 9); - len -= 9; - parsed += 9; + memcpy(config, ptr + parsed, *ptr); + len -= *ptr; + parsed += *ptr; if (config->bNumInterfaces > USB_MAXINTERFACES) + { + printk(KERN_WARNING "usb: too many interfaces.\n"); return -1; + } for (i = 0; i < config->bNumInterfaces; i++) { - int retval = usb_parse_interface(config->interface + i, ptr + parsed, len); + int retval = usb_parse_interface(dev, config->interface + i, ptr + parsed, len); if (retval < 0) - return retval; + return parsed; // HACK +// return retval; parsed += retval; len -= retval; } @@ -197,10 +261,13 @@ int usb_parse_configuration(struct usb_device *dev, void *__buf, int bytes) unsigned char *ptr = __buf; if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) + { + printk(KERN_WARNING "usb: too many configurations.\n"); return -1; + } for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { - int retval = usb_parse_config(dev->config + i, ptr, bytes); + int retval = usb_parse_config(dev, dev->config + i, ptr, bytes); if (retval < 0) return retval; ptr += retval; @@ -451,7 +518,7 @@ int usb_get_report(struct usb_device *dev) int usb_get_configuration(struct usb_device *dev) { unsigned int size; - unsigned char buffer[128]; + unsigned char buffer[400]; /* Get the first 8 bytes - guaranteed */ if (usb_get_descriptor(dev, USB_DT_CONFIG, 0, buffer, 8)) @@ -460,7 +527,10 @@ int usb_get_configuration(struct usb_device *dev) /* Get the full buffer */ size = *(unsigned short *)(buffer+2); if (size > sizeof(buffer)) + { + printk(KERN_INFO "usb: truncated DT_CONFIG (want %d).\n", size); size = sizeof(buffer); + } if (usb_get_descriptor(dev, USB_DT_CONFIG, 0, buffer, size)) return -1; diff --git a/drivers/usb/usb.h b/drivers/usb/usb.h index b317acfc5997..ac22192c5ef9 100644 --- a/drivers/usb/usb.h +++ b/drivers/usb/usb.h @@ -107,9 +107,9 @@ struct usb_devmap { * I'm not proud. I just want this dang * thing to start working. */ -#define USB_MAXCONFIG 1 -#define USB_MAXINTERFACES 3 -#define USB_MAXENDPOINTS 3 +#define USB_MAXCONFIG 2 +#define USB_MAXINTERFACES 8 +#define USB_MAXENDPOINTS 4 struct usb_device_descriptor { __u8 bLength; @@ -355,5 +355,17 @@ void usb_show_endpoint_descriptor(struct usb_endpoint_descriptor *); void usb_show_hub_descriptor(struct usb_hub_descriptor *); void usb_show_device(struct usb_device *); +/* + * Audio parsing helpers + */ + +#ifdef CONFIG_USB_AUDIO +void usb_audio_interface(struct usb_interface_descriptor *, u8 *); +void usb_audio_endpoint(struct usb_endpoint_descriptor *, u8 *); +#else +extern inline void usb_audio_interface(struct usb_interface_descriptor *, u8 *) {} +extern inline void usb_audio_endpoint(struct usb_endpoint_descriptor *, u8 *) {} +#endif + #endif diff --git a/drivers/video/fbcon-cfb2.c b/drivers/video/fbcon-cfb2.c index 668177df091b..5b339a4fa39d 100644 --- a/drivers/video/fbcon-cfb2.c +++ b/drivers/video/fbcon-cfb2.c @@ -50,7 +50,7 @@ static u_char nibbletab_cfb2[]={ void fbcon_cfb2_setup(struct display *p) { - p->next_line = p->var.xres_virtual>>2; + p->next_line = p->line_length ? p->line_length : p->var.xres_virtual>>2; p->next_plane = 0; } diff --git a/drivers/video/fbcon-cfb4.c b/drivers/video/fbcon-cfb4.c index a86ec1596c9d..6248c28eee89 100644 --- a/drivers/video/fbcon-cfb4.c +++ b/drivers/video/fbcon-cfb4.c @@ -50,7 +50,7 @@ static u16 nibbletab_cfb4[] = { void fbcon_cfb4_setup(struct display *p) { - p->next_line = p->var.xres_virtual>>1; + p->next_line = p->line_length ? p->line_length : p->var.xres_virtual>>1; p->next_plane = 0; } diff --git a/fs/proc/openpromfs.c b/fs/proc/openpromfs.c index 09844e156ba9..dcb007f11cad 100644 --- a/fs/proc/openpromfs.c +++ b/fs/proc/openpromfs.c @@ -1,4 +1,4 @@ -/* $Id: openpromfs.c,v 1.32 1998/11/18 06:15:20 davem Exp $ +/* $Id: openpromfs.c,v 1.33 1999/04/28 11:57:33 davem Exp $ * openpromfs.c: /proc/openprom handling routines * * Copyright (C) 1996-1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -59,7 +59,7 @@ static struct openpromfs_dev **devices; static int openpromfs_create (struct inode *, struct dentry *, int); static int openpromfs_readdir(struct file *, void *, filldir_t); -static int openpromfs_lookup(struct inode *, struct dentry *dentry); +static struct dentry *openpromfs_lookup(struct inode *, struct dentry *dentry); static int openpromfs_unlink (struct inode *, struct dentry *dentry); static ssize_t nodenum_read(struct file *file, char *buf, @@ -685,7 +685,7 @@ static int lookup_children(u16 n, const char * name, int len) return 0; } -static int openpromfs_lookup(struct inode * dir, struct dentry *dentry) +static struct dentry *openpromfs_lookup(struct inode * dir, struct dentry *dentry) { int ino = 0; #define OPFSL_DIR 0 @@ -776,11 +776,11 @@ static int openpromfs_lookup(struct inode * dir, struct dentry *dentry) if (ino) type = OPFSL_DIR; else - return -ENOENT; + return ERR_PTR(-ENOENT); } inode = proc_get_inode (dir->i_sb, ino, 0); if (!inode) - return -EINVAL; + return ERR_PTR(-EINVAL); switch (type) { case OPFSL_DIR: inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; @@ -827,7 +827,7 @@ static int openpromfs_lookup(struct inode * dir, struct dentry *dentry) inode->i_uid = 0; d_add(dentry, inode); - return 0; + return NULL; } static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filldir) diff --git a/fs/proc/root.c b/fs/proc/root.c index 2c4fbe8dc775..f1ad39981a49 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -181,14 +181,14 @@ struct proc_dir_entry proc_sys_root = { #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE) static int (*proc_openprom_defreaddir_ptr)(struct file *, void *, filldir_t); -static int (*proc_openprom_deflookup_ptr)(struct inode *, struct dentry *); +static struct dentry * (*proc_openprom_deflookup_ptr)(struct inode *, struct dentry *); void (*proc_openprom_use)(struct inode *, int) = 0; static struct openpromfs_dev *proc_openprom_devices = NULL; static ino_t proc_openpromdev_ino = PROC_OPENPROMD_FIRST; struct inode_operations * proc_openprom_register(int (*readdir)(struct file *, void *, filldir_t), - int (*lookup)(struct inode *, struct dentry *), + struct dentry * (*lookup)(struct inode *, struct dentry *), void (*use)(struct inode *, int), struct openpromfs_dev ***devices) { @@ -250,7 +250,7 @@ proc_openprom_defreaddir(struct file * filp, void * dirent, filldir_t filldir) } #define OPENPROM_DEFREADDIR proc_openprom_defreaddir -static int +static struct dentry * proc_openprom_deflookup(struct inode * dir, struct dentry *dentry) { request_module("openpromfs"); @@ -258,7 +258,7 @@ proc_openprom_deflookup(struct inode * dir, struct dentry *dentry) proc_openprom_deflookup) return proc_openprom_inode_operations.lookup (dir, dentry); - return -ENOENT; + return ERR_PTR(-ENOENT); } #define OPENPROM_DEFLOOKUP proc_openprom_deflookup #else diff --git a/include/asm-alpha/siginfo.h b/include/asm-alpha/siginfo.h index f9f3e040ad44..a8bedd8e0a21 100644 --- a/include/asm-alpha/siginfo.h +++ b/include/asm-alpha/siginfo.h @@ -138,7 +138,7 @@ typedef struct siginfo { */ #define TRAP_BRKPT 1 /* process breakpoint */ #define TRAP_TRACE 2 /* process trace trap */ -#define NSIGTRAP +#define NSIGTRAP 2 /* * SIGCHLD si_codes diff --git a/include/asm-arm/siginfo.h b/include/asm-arm/siginfo.h index 2dec6e08079d..c08847d3252d 100644 --- a/include/asm-arm/siginfo.h +++ b/include/asm-arm/siginfo.h @@ -138,7 +138,7 @@ typedef struct siginfo { */ #define TRAP_BRKPT 1 /* process breakpoint */ #define TRAP_TRACE 2 /* process trace trap */ -#define NSIGTRAP +#define NSIGTRAP 2 /* * SIGCHLD si_codes diff --git a/include/asm-i386/siginfo.h b/include/asm-i386/siginfo.h index d0cae4709254..7c805525c9e5 100644 --- a/include/asm-i386/siginfo.h +++ b/include/asm-i386/siginfo.h @@ -138,7 +138,7 @@ typedef struct siginfo { */ #define TRAP_BRKPT 1 /* process breakpoint */ #define TRAP_TRACE 2 /* process trace trap */ -#define NSIGTRAP +#define NSIGTRAP 2 /* * SIGCHLD si_codes diff --git a/include/asm-mips/siginfo.h b/include/asm-mips/siginfo.h index eca5b65ddc2a..3e19a3a55b1b 100644 --- a/include/asm-mips/siginfo.h +++ b/include/asm-mips/siginfo.h @@ -146,7 +146,7 @@ typedef struct siginfo { */ #define TRAP_BRKPT 1 /* process breakpoint */ #define TRAP_TRACE 2 /* process trace trap */ -#define NSIGTRAP +#define NSIGTRAP 2 /* * SIGCHLD si_codes diff --git a/include/asm-ppc/siginfo.h b/include/asm-ppc/siginfo.h index c3a46ceffa48..f838fcc82adb 100644 --- a/include/asm-ppc/siginfo.h +++ b/include/asm-ppc/siginfo.h @@ -138,7 +138,7 @@ typedef struct siginfo { */ #define TRAP_BRKPT 1 /* process breakpoint */ #define TRAP_TRACE 2 /* process trace trap */ -#define NSIGTRAP +#define NSIGTRAP 2 /* * SIGCHLD si_codes diff --git a/include/asm-sparc/asmmacro.h b/include/asm-sparc/asmmacro.h index ed49f6ea033c..553495c08638 100644 --- a/include/asm-sparc/asmmacro.h +++ b/include/asm-sparc/asmmacro.h @@ -26,7 +26,7 @@ #define GET_PROCESSOR_MID(reg, tmp) \ rd %tbr, %reg; \ - sethi C_LABEL(mid_xlate), %tmp; \ + sethi %hi(C_LABEL(mid_xlate)), %tmp; \ srl %reg, 12, %reg; \ or %tmp, %lo(C_LABEL(mid_xlate)), %tmp; \ and %reg, 3, %reg; \ @@ -34,7 +34,7 @@ #define GET_PROCESSOR_OFFSET(reg, tmp) \ GET_PROCESSOR_ID(reg) \ - sethi C_LABEL(cpu_offset), %tmp; \ + sethi %hi(C_LABEL(cpu_offset)), %tmp; \ sll %reg, 2, %reg; \ or %tmp, %lo(C_LABEL(cpu_offset)), %tmp; \ ld [%tmp + %reg], %reg; diff --git a/include/asm-sparc/keyboard.h b/include/asm-sparc/keyboard.h index 9821385fab8c..7b1cbb0be79c 100644 --- a/include/asm-sparc/keyboard.h +++ b/include/asm-sparc/keyboard.h @@ -1,4 +1,4 @@ -/* $Id: keyboard.h,v 1.1 1998/09/22 05:54:42 jj Exp $ +/* $Id: keyboard.h,v 1.2 1999/04/28 11:59:07 davem Exp $ * linux/include/asm-sparc/keyboard.h * * sparc64 Created Aug 29 1997 by Eddie C. Dost (ecd@skynet.be) diff --git a/include/asm-sparc/siginfo.h b/include/asm-sparc/siginfo.h index f20a5a81cb16..194aa6019451 100644 --- a/include/asm-sparc/siginfo.h +++ b/include/asm-sparc/siginfo.h @@ -142,7 +142,7 @@ typedef struct siginfo { */ #define TRAP_BRKPT 1 /* process breakpoint */ #define TRAP_TRACE 2 /* process trace trap */ -#define NSIGTRAP +#define NSIGTRAP 2 /* * SIGCHLD si_codes diff --git a/include/asm-sparc64/keyboard.h b/include/asm-sparc64/keyboard.h index d7b5bc400d90..15f24c33f5a4 100644 --- a/include/asm-sparc64/keyboard.h +++ b/include/asm-sparc64/keyboard.h @@ -1,4 +1,4 @@ -/* $Id: keyboard.h,v 1.2 1997/09/07 15:40:49 ecd Exp $ +/* $Id: keyboard.h,v 1.3 1999/04/28 11:59:12 davem Exp $ * linux/include/asm-sparc64/keyboard.h * * Created Aug 29 1997 by Eddie C. Dost (ecd@skynet.be) diff --git a/include/asm-sparc64/siginfo.h b/include/asm-sparc64/siginfo.h index b3ccd57a9bb1..a23240e6623b 100644 --- a/include/asm-sparc64/siginfo.h +++ b/include/asm-sparc64/siginfo.h @@ -201,7 +201,7 @@ typedef struct siginfo32 { */ #define TRAP_BRKPT 1 /* process breakpoint */ #define TRAP_TRACE 2 /* process trace trap */ -#define NSIGTRAP +#define NSIGTRAP 2 /* * SIGCHLD si_codes diff --git a/include/linux/if_ppp.h b/include/linux/if_ppp.h index bb7a98db3f0e..1d103bdca331 100644 --- a/include/linux/if_ppp.h +++ b/include/linux/if_ppp.h @@ -1,4 +1,4 @@ -/* $Id: if_ppp.h,v 1.14 1998/07/07 04:27:33 paulus Exp $ */ +/* $Id: if_ppp.h,v 1.19 1999/03/31 06:07:57 paulus Exp $ */ /* * if_ppp.h - Point-to-Point Protocol definitions. @@ -21,7 +21,7 @@ */ /* - * ==FILEVERSION 980704== + * ==FILEVERSION 990331== * * NOTE TO MAINTAINERS: * If you modify this file at all, please set the above date. @@ -35,19 +35,13 @@ #ifndef _IF_PPP_H_ #define _IF_PPP_H_ -#if defined(__linux__) -#include -#include -#include -#endif - /* * Packet sizes */ #define PPP_MTU 1500 /* Default MTU (size of Info field) */ #define PPP_MAXMRU 65000 /* Largest MRU we allow */ -#define PPP_VERSION "2.3.3" +#define PPP_VERSION "2.3.7" #define PPP_MAGIC 0x5002 /* Magic value for the ppp structure */ #define PROTO_IPX 0x002b /* protocol numbers */ #define PROTO_DNA_RT 0x0027 /* DNA Routing */ @@ -73,7 +67,8 @@ #define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */ #define SC_LOG_RAWIN 0x00080000 /* log all chars received */ #define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */ -#define SC_MASK 0x0f0000ff /* bits that user can change */ +#define SC_SYNC 0x00200000 /* synchronous serial mode */ +#define SC_MASK 0x0f2000ff /* bits that user can change */ /* state bits */ #define SC_XMIT_BUSY 0x10000000 /* (used by isdn_ppp?) */ diff --git a/include/linux/if_pppvar.h b/include/linux/if_pppvar.h index 6fae4b94bda0..d6cd0c25bb17 100644 --- a/include/linux/if_pppvar.h +++ b/include/linux/if_pppvar.h @@ -42,7 +42,7 @@ */ /* - * ==FILEVERSION 990114== + * ==FILEVERSION 990325== * * NOTE TO MAINTAINERS: * If you modify this file at all, please set the above date. @@ -89,6 +89,7 @@ struct ppp { __u8 escape; /* 0x20 if prev char was PPP_ESC */ __u8 toss; /* toss this frame */ volatile __u8 tty_pushing; /* internal state flag */ + volatile __u8 woke_up; /* internal state flag */ __u32 xmit_async_map[8]; /* 1 bit means that given control character is quoted on output*/ __u32 recv_async_map; /* 1 bit means that given control diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index c8b5731df72e..5158cbd1c233 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -394,7 +394,7 @@ struct openpromfs_dev { }; extern struct inode_operations * proc_openprom_register(int (*readdir)(struct file *, void *, filldir_t), - int (*lookup)(struct inode *, struct dentry *), + struct dentry * (*lookup)(struct inode *, struct dentry *), void (*use)(struct inode *, int), struct openpromfs_dev ***); extern void proc_openprom_deregister(void); diff --git a/include/net/tcp.h b/include/net/tcp.h index 468ebd56f912..94fd65b7bd44 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -716,6 +716,14 @@ extern __inline__ int tcp_raise_window(struct sock *sk) return (new_win && (new_win > (cur_win << 1))); } +/* TCP timestamps are only 32-bits, this causes a slight + * complication on 64-bit systems since we store a snapshot + * of jiffies in the buffer control blocks below. We decidely + * only use of the low 32-bits of jiffies and hide the ugly + * casts with the following macro. + */ +#define tcp_time_stamp ((__u32)(jiffies)) + /* This is what the send packet queueing engine uses to pass * TCP per-packet control information to the transmission * code. We also store the host-order sequence numbers in @@ -732,7 +740,7 @@ struct tcp_skb_cb { } header; /* For incoming frames */ __u32 seq; /* Starting sequence number */ __u32 end_seq; /* SEQ + FIN + SYN + datalen */ - unsigned long when; /* used to compute rtt's */ + __u32 when; /* used to compute rtt's */ __u8 flags; /* TCP header flags. */ /* NOTE: These must match up to the flags byte in a diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 7016b80d5061..5744752a1984 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_input.c,v 1.162 1999/04/24 00:27:16 davem Exp $ + * Version: $Id: tcp_input.c,v 1.163 1999/04/28 16:08:05 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -97,7 +97,7 @@ static int prune_queue(struct sock *sk); static void tcp_delack_estimator(struct tcp_opt *tp) { if(tp->ato == 0) { - tp->lrcvtime = jiffies; + tp->lrcvtime = tcp_time_stamp; /* Help sender leave slow start quickly, * and also makes sure we do not take this @@ -106,9 +106,9 @@ static void tcp_delack_estimator(struct tcp_opt *tp) tp->ato = 1; tcp_enter_quickack_mode(tp); } else { - int m = jiffies - tp->lrcvtime; + int m = tcp_time_stamp - tp->lrcvtime; - tp->lrcvtime = jiffies; + tp->lrcvtime = tcp_time_stamp; if(m <= 0) m = 1; if(m > tp->rto) @@ -231,7 +231,7 @@ extern __inline__ void tcp_replace_ts_recent(struct sock *sk, struct tcp_opt *tp */ if((s32)(tp->rcv_tsval - tp->ts_recent) >= 0) { tp->ts_recent = tp->rcv_tsval; - tp->ts_recent_stamp = jiffies; + tp->ts_recent_stamp = tcp_time_stamp; } } } @@ -241,7 +241,7 @@ extern __inline__ void tcp_replace_ts_recent(struct sock *sk, struct tcp_opt *tp extern __inline__ int tcp_paws_discard(struct tcp_opt *tp, struct tcphdr *th, unsigned len) { /* ts_recent must be younger than 24 days */ - return (((s32)(jiffies - tp->ts_recent_stamp) >= PAWS_24DAYS) || + return (((s32)(tcp_time_stamp - tp->ts_recent_stamp) >= PAWS_24DAYS) || (((s32)(tp->rcv_tsval - tp->ts_recent) < 0) && /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM */ (len != (th->doff * 4)))); @@ -609,7 +609,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __u32 ack, { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); struct sk_buff *skb; - unsigned long now = jiffies; + __u32 now = tcp_time_stamp; int acked = 0; /* If we are retransmitting, and this ACK clears up to @@ -725,7 +725,7 @@ static void tcp_ack_saw_tstamp(struct sock *sk, struct tcp_opt *tp, if (!(flag & FLAG_DATA_ACKED)) return; - seq_rtt = jiffies-tp->rcv_tsecr; + seq_rtt = tcp_time_stamp - tp->rcv_tsecr; tcp_rtt_estimator(tp, seq_rtt); if (tp->retransmits) { if (tp->packets_out == 0) { @@ -749,7 +749,7 @@ static void tcp_ack_saw_tstamp(struct sock *sk, struct tcp_opt *tp, static __inline__ void tcp_ack_packets_out(struct sock *sk, struct tcp_opt *tp) { struct sk_buff *skb = skb_peek(&sk->write_queue); - long when = tp->rto - (jiffies - TCP_SKB_CB(skb)->when); + __u32 when = tp->rto - (tcp_time_stamp - TCP_SKB_CB(skb)->when); /* Some data was ACK'd, if still retransmitting (due to a * timeout), resend more of the retransmit queue. The @@ -778,7 +778,7 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th, if (tp->pending == TIME_KEEPOPEN) tp->probes_out = 0; - tp->rcv_tstamp = jiffies; + tp->rcv_tstamp = tcp_time_stamp; /* If the ack is newer than sent or older than previous acks * then we can probably ignore it. @@ -2112,7 +2112,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, tp->tcp_header_len = sizeof(struct tcphdr); if (tp->saw_tstamp) { tp->ts_recent = tp->rcv_tsval; - tp->ts_recent_stamp = jiffies; + tp->ts_recent_stamp = tcp_time_stamp; } /* Can't be earlier, doff would be wrong. */ @@ -2136,7 +2136,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, tcp_parse_options(sk, th, tp, 0); if (tp->saw_tstamp) { tp->ts_recent = tp->rcv_tsval; - tp->ts_recent_stamp = jiffies; + tp->ts_recent_stamp = tcp_time_stamp; } tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 450b85f9d5e3..f676077a421f 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_ipv4.c,v 1.173 1999/04/24 00:27:07 davem Exp $ + * Version: $Id: tcp_ipv4.c,v 1.174 1999/04/28 16:08:19 davem Exp $ * * IPv4 specific functions * @@ -1430,7 +1430,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, } if (newtp->tstamp_ok) { newtp->ts_recent = req->ts_recent; - newtp->ts_recent_stamp = jiffies; + newtp->ts_recent_stamp = tcp_time_stamp; newtp->tcp_header_len = sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED; } else { newtp->tcp_header_len = sizeof(struct tcphdr); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index e0760edad00d..a73db21a5e9a 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_output.c,v 1.106 1999/03/12 03:43:51 davem Exp $ + * Version: $Id: tcp_output.c,v 1.107 1999/04/28 16:08:12 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -167,7 +167,7 @@ void tcp_send_skb(struct sock *sk, struct sk_buff *skb, int force_queue) if (!force_queue && tp->send_head == NULL && tcp_snd_test(sk, skb)) { /* Send it out now. */ - TCP_SKB_CB(skb)->when = jiffies; + TCP_SKB_CB(skb)->when = tcp_time_stamp; tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; tp->packets_out++; tcp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)); @@ -344,7 +344,7 @@ void tcp_write_xmit(struct sock *sk) /* Advance the send_head. This one is going out. */ update_send_head(sk); - TCP_SKB_CB(skb)->when = jiffies; + TCP_SKB_CB(skb)->when = tcp_time_stamp; tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; tp->packets_out++; tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); @@ -600,7 +600,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) /* Make a copy, if the first transmission SKB clone we made * is still in somebody's hands, else make a clone. */ - TCP_SKB_CB(skb)->when = jiffies; + TCP_SKB_CB(skb)->when = tcp_time_stamp; if(skb_cloned(skb)) skb = skb_copy(skb, GFP_ATOMIC); else @@ -723,7 +723,7 @@ void tcp_send_fin(struct sock *sk) tp->packets_out && !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG)) { update_send_head(sk); - TCP_SKB_CB(skb)->when = jiffies; + TCP_SKB_CB(skb)->when = tcp_time_stamp; tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; tp->packets_out++; tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); @@ -778,7 +778,7 @@ void tcp_send_active_reset(struct sock *sk) /* Send it off. */ TCP_SKB_CB(skb)->seq = tp->write_seq; TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq; - TCP_SKB_CB(skb)->when = jiffies; + TCP_SKB_CB(skb)->when = tcp_time_stamp; tcp_transmit_skb(sk, skb); } @@ -808,7 +808,7 @@ int tcp_send_synack(struct sock *sk) TCP_SKB_CB(skb)->seq = tp->snd_una; TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1; __skb_queue_tail(&sk->write_queue, skb); - TCP_SKB_CB(skb)->when = jiffies; + TCP_SKB_CB(skb)->when = tcp_time_stamp; tp->packets_out++; tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); return 0; @@ -875,7 +875,7 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ th->window = htons(req->rcv_wnd); - TCP_SKB_CB(skb)->when = jiffies; + TCP_SKB_CB(skb)->when = tcp_time_stamp; tcp_syn_build_options((__u32 *)(th + 1), req->mss, req->tstamp_ok, req->sack_ok, req->wscale_ok, req->rcv_wscale, TCP_SKB_CB(skb)->when, @@ -963,7 +963,7 @@ void tcp_connect(struct sock *sk, struct sk_buff *buff, int mtu) /* Send it off. */ __skb_queue_tail(&sk->write_queue, buff); - TCP_SKB_CB(buff)->when = jiffies; + TCP_SKB_CB(buff)->when = tcp_time_stamp; tp->packets_out++; tcp_transmit_skb(sk, skb_clone(buff, GFP_KERNEL)); tcp_statistics.TcpActiveOpens++; @@ -1037,7 +1037,7 @@ void tcp_send_ack(struct sock *sk) /* Send it off, this clears delayed acks for us. */ TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tp->snd_nxt; - TCP_SKB_CB(buff)->when = jiffies; + TCP_SKB_CB(buff)->when = tcp_time_stamp; tcp_transmit_skb(sk, buff); } } @@ -1075,7 +1075,7 @@ void tcp_write_wakeup(struct sock *sk) return; /* Let a retransmit get it. */ } update_send_head(sk); - TCP_SKB_CB(skb)->when = jiffies; + TCP_SKB_CB(skb)->when = tcp_time_stamp; tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; tp->packets_out++; tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); @@ -1101,7 +1101,7 @@ void tcp_write_wakeup(struct sock *sk) */ TCP_SKB_CB(skb)->seq = tp->snd_nxt - 1; TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq; - TCP_SKB_CB(skb)->when = jiffies; + TCP_SKB_CB(skb)->when = tcp_time_stamp; tcp_transmit_skb(sk, skb); } } diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 2a4c4ae9774f..00ac053763dc 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_timer.c,v 1.59 1999/03/23 21:21:09 davem Exp $ + * Version: $Id: tcp_timer.c,v 1.60 1999/04/28 16:08:21 davem Exp $ * * Authors: Ross Biro, * Fred N. van Kempen, @@ -224,7 +224,7 @@ static __inline__ int tcp_keepopen_proc(struct sock *sk) if ((1<state) & (TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT2)) { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; - __u32 elapsed = jiffies - tp->rcv_tstamp; + __u32 elapsed = tcp_time_stamp - tp->rcv_tstamp; if (elapsed >= sysctl_tcp_keepalive_time) { if (tp->probes_out > sysctl_tcp_keepalive_probes) { @@ -561,7 +561,7 @@ static void tcp_syn_recv_timer(unsigned long data) if (!tp->syn_wait_queue) break; } else { - __u32 timeo; + unsigned long timeo; struct open_request *op; (*conn->class->rtx_syn_ack)(sk, conn);