@@ -141,7+141,7 @@ For such memory, you can do things like * read first 32 bits from ISA memory at 0xC0000, aka
* C000:0000 in DOS terms
*/
- unsigned int signature = readl(0xC0000);
+ unsigned int signature = isa_readl(0xC0000);
- remapping and writing:
/*
@@ -341,11+341,6 @@ architecture-specific values.
# arch/i386/Makefile
- # only work around strength reduction bug(s) on older gcc versions
- CFLAGS += $(shell if ! $(CC) -march=i486 -S -o /dev/null \
- -xc /dev/null >/dev/null 2>&1; \
- then echo "-fno-strength-reduce"; fi)
-
# prevent gcc from keeping the stack 16 byte aligned
CFLAGS += $(shell if $(CC) -mpreferred-stack-boundary=2 \
-S -o /dev/null -xc /dev/null >/dev/null 2>&1; \
@@ -356,21+351,15 @@ architecture-specific values. # arch/i386/Makefile
ifdef CONFIG_M386
- CFLAGS += $(shell if $(CC) -march=i386 -S -o /dev/null \
- -xc /dev/null >/dev/null 2>&1; \
- then echo "-march=i386"; else echo "-m386"; fi)
+ CFLAGS += -march=i386
endif
ifdef CONFIG_M486
- CFLAGS += $(shell if $(CC) -march=i486 -S -o /dev/null \
- -xc /dev/null >/dev/null 2>&1; \
- then echo "-march=i486"; else echo "-m486"; fi)
+ CFLAGS += -march=i486
endif
ifdef CONFIG_M586
- CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null \
- -xc /dev/null >/dev/null 2>&1; \
- then echo "-march=i586"; fi)
+ CFLAGS += -march=i586
endif
Some arch Makefiles redefine the compilation commands in order
@@ -87,7+87,7 @@ export MODLIB
CPPFLAGS := -D__KERNEL__ -I$(HPATH)
-CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
+CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing
AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
#
@@ -182,9+182,6 @@ DRIVERS += $(DRIVERS-y)
include arch/$(ARCH)/Makefile
-# use '-fno-strict-aliasing', but only if the compiler can take it
-CFLAGS += $(shell if $(CC) -fno-strict-aliasing -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strict-aliasing"; fi)
-
export CPPFLAGS CFLAGS AFLAGS
export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
@@ -291,7+288,7 @@ TAGS: dummy
# Exuberant ctags works better with -I
tags: dummy
- CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__initlocaldata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; \
+ CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; \
ctags $$CTAGSF `find include/asm-$(ARCH) -name '*.h'` && \
find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print | xargs ctags $$CTAGSF -a && \
find $(SUBDIRS) init -name '*.c' | xargs ctags $$CTAGSF -a
@@ -399,7+399,7 @@ verify_tb_operation(void) {
static int page[PAGE_SIZE/4]
__attribute__((aligned(PAGE_SIZE)))
- __initlocaldata = { 0 };
+ __initdata = { 0 };
struct pci_iommu_arena *arena = pci_isa_hose->sg_isa;
int ctrl, addr0, tag0, pte0, data0;
@@ -679,7+679,7 @@ static int tsunami_indices[] = {0,1,2,3,4,5,6,7,8}; static struct alpha_machine_vector * __init
get_sysvec(long type, long variation, long cpu)
{
- static struct alpha_machine_vector *systype_vecs[] __initlocaldata =
+ static struct alpha_machine_vector *systype_vecs[] __initdata =
{
NULL, /* 0 */
NULL, /* ADU */
@@ -722,48+722,48 @@ get_sysvec(long type, long variation, long cpu) NULL, /* Titan */
};
- static struct alpha_machine_vector *unofficial_vecs[] __initlocaldata =
+ static struct alpha_machine_vector *unofficial_vecs[] __initdata =
{
NULL, /* 100 */
&ruffian_mv,
};
- static struct alpha_machine_vector *api_vecs[] __initlocaldata =
+ static struct alpha_machine_vector *api_vecs[] __initdata =
{
NULL, /* 200 */
&nautilus_mv,
};
- static struct alpha_machine_vector *alcor_vecs[] __initlocaldata =
+ static struct alpha_machine_vector *alcor_vecs[] __initdata =
{
&alcor_mv, &xlt_mv, &xlt_mv
};
- static struct alpha_machine_vector *eb164_vecs[] __initlocaldata =
+ static struct alpha_machine_vector *eb164_vecs[] __initdata =
{
&eb164_mv, &pc164_mv, &lx164_mv, &sx164_mv, &rx164_mv
};
- static struct alpha_machine_vector *eb64p_vecs[] __initlocaldata =
+ static struct alpha_machine_vector *eb64p_vecs[] __initdata =
{
&eb64p_mv,
&cabriolet_mv,
&cabriolet_mv /* AlphaPCI64 */
};
- static struct alpha_machine_vector *eb66_vecs[] __initlocaldata =
+ static struct alpha_machine_vector *eb66_vecs[] __initdata =
{
&eb66_mv,
&eb66p_mv
};
- static struct alpha_machine_vector *titan_vecs[] __initlocaldata =
+ static struct alpha_machine_vector *titan_vecs[] __initdata =
{
NULL,
&privateer_mv, /* privateer */
};
- static struct alpha_machine_vector *tsunami_vecs[] __initlocaldata =
+ static struct alpha_machine_vector *tsunami_vecs[] __initdata =
{
NULL,
&dp264_mv, /* dp264 */
@@ -856,7+856,7 @@ get_sysvec(long type, long variation, long cpu) static struct alpha_machine_vector * __init
get_sysvec_byname(const char *name)
{
- static struct alpha_machine_vector *all_vecs[] __initlocaldata =
+ static struct alpha_machine_vector *all_vecs[] __initdata =
{
&alcor_mv,
&alphabook1_mv,
@@ -201,7+201,7 @@ alcor_init_irq(void) static int __init
alcor_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[7][5] __initlocaldata = {
+ static char irq_tab[7][5] __initdata = {
/*INT INTA INTB INTC INTD */
/* note: IDSEL 17 is XLT only */
{16+13, 16+13, 16+13, 16+13, 16+13}, /* IdSel 17, TULIP */
@@ -173,7+173,7 @@ pc164_device_interrupt(unsigned long v, struct pt_regs *r) static inline int __init
eb66p_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[5][5] __initlocaldata = {
+ static char irq_tab[5][5] __initdata = {
/*INT INTA INTB INTC INTD */
{16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J25 */
{16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7, slot 1, J26 */
@@ -203,7+203,7 @@ eb66p_map_irq(struct pci_dev *dev, u8 slot, u8 pin) static inline int __init
cabriolet_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[5][5] __initlocaldata = {
+ static char irq_tab[5][5] __initdata = {
/*INT INTA INTB INTC INTD */
{ 16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 5, slot 2, J21 */
{ 16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J19 */
@@ -274,7+274,7 @@ cia_cab_init_pci(void) static inline int __init
alphapc164_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[7][5] __initlocaldata = {
+ static char irq_tab[7][5] __initdata = {
/*INT INTA INTB INTC INTD */
{ 16+2, 16+2, 16+9, 16+13, 16+17}, /* IdSel 5, slot 2, J20 */
{ 16+0, 16+0, 16+7, 16+11, 16+15}, /* IdSel 6, slot 0, J29 */
@@ -393,7+393,7 @@ clipper_init_irq(void) static int __init
dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[6][5] __initlocaldata = {
+ static char irq_tab[6][5] __initdata = {
/*INT INTA INTB INTC INTD */
{ -1, -1, -1, -1, -1}, /* IdSel 5 ISA Bridge */
{ 16+ 3, 16+ 3, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin*/
@@ -427,7+427,7 @@ dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin) static int __init
monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[13][5] __initlocaldata = {
+ static char irq_tab[13][5] __initdata = {
/*INT INTA INTB INTC INTD */
{ 45, 45, 45, 45, 45}, /* IdSel 3 21143 PCI1 */
{ -1, -1, -1, -1, -1}, /* IdSel 4 unused */
@@ -488,7+488,7 @@ monet_swizzle(struct pci_dev *dev, u8 *pinp) static int __init
webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[13][5] __initlocaldata = {
+ static char irq_tab[13][5] __initdata = {
/*INT INTA INTB INTC INTD */
{ -1, -1, -1, -1, -1}, /* IdSel 7 ISA Bridge */
{ -1, -1, -1, -1, -1}, /* IdSel 8 unused */
@@ -509,7+509,7 @@ webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin) static int __init
clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[7][5] __initlocaldata = {
+ static char irq_tab[7][5] __initdata = {
/*INT INTA INTB INTC INTD */
{ 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 1 slot 1 */
{ 16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 2 slot 2 */
@@ -188,7+188,7 @@ eb64p_init_irq(void) static int __init
eb64p_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[5][5] __initlocaldata = {
+ static char irq_tab[5][5] __initdata = {
/*INT INTA INTB INTC INTD */
{16+7, 16+7, 16+7, 16+7, 16+7}, /* IdSel 5, slot ?, ?? */
{16+0, 16+0, 16+2, 16+4, 16+9}, /* IdSel 6, slot ?, ?? */
@@ -151,7+151,7 @@ miata_init_irq(void) static int __init
miata_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[18][5] __initlocaldata = {
+ static char irq_tab[18][5] __initdata = {
/*INT INTA INTB INTC INTD */
{16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8}, /* IdSel 14, DC21142 */
{ -1, -1, -1, -1, -1}, /* IdSel 15, EIDE */
@@ -164,7+164,7 @@ mikasa_init_irq(void) static int __init
mikasa_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[8][5] __initlocaldata = {
+ static char irq_tab[8][5] __initdata = {
/*INT INTA INTB INTC INTD */
{16+12, 16+12, 16+12, 16+12, 16+12}, /* IdSel 17, SCSI */
{ -1, -1, -1, -1, -1}, /* IdSel 18, PCEB */
@@ -205,7+205,7 @@ noritake_init_irq(void) static int __init
noritake_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[15][5] __initlocaldata = {
+ static char irq_tab[15][5] __initdata = {
/*INT INTA INTB INTC INTD */
/* note: IDSELs 16, 17, and 25 are CORELLE only */
{ 16+1, 16+1, 16+1, 16+1, 16+1}, /* IdSel 16, QLOGIC */
@@ -194,7+194,7 @@ rawhide_init_irq(void) static int __init
rawhide_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[5][5] __initlocaldata = {
+ static char irq_tab[5][5] __initdata = {
/*INT INTA INTB INTC INTD */
{ 16+16, 16+16, 16+16, 16+16, 16+16}, /* IdSel 1 SCSI PCI 1 */
{ 16+ 0, 16+ 0, 16+ 1, 16+ 2, 16+ 3}, /* IdSel 2 slot 2 */
@@ -119,7+119,7 @@ ruffian_get_bank_size(unsigned long offset)
/* Check BANK_ENABLE */
if (bank & 0x01) {
- static unsigned long size[] __initlocaldata = {
+ static unsigned long size[] __initdata = {
0x40000000UL, /* 0x00, 1G */
0x20000000UL, /* 0x02, 512M */
0x10000000UL, /* 0x04, 256M */
@@ -164,7+164,7 @@ static int __init rx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
#if 0
- static char irq_tab_pass1[6][5] __initlocaldata = {
+ static char irq_tab_pass1[6][5] __initdata = {
/*INT INTA INTB INTC INTD */
{ 16+3, 16+3, 16+8, 16+13, 16+18}, /* IdSel 5, slot 2 */
{ 16+5, 16+5, 16+10, 16+15, 16+20}, /* IdSel 6, slot 0 */
@@ -174,7+174,7 @@ rx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { 16+1, 16+1, 16+6, 16+11, 16+16}, /* IdSel 10, slot 4 */
};
#else
- static char irq_tab[6][5] __initlocaldata = {
+ static char irq_tab[6][5] __initdata = {
/*INT INTA INTB INTC INTD */
{ 16+0, 16+0, 16+6, 16+11, 16+16}, /* IdSel 5, slot 0 */
{ 16+1, 16+1, 16+7, 16+12, 16+17}, /* IdSel 6, slot 1 */
@@ -255,7+255,7 @@ sable_init_irq(void) static int __init
sable_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[9][5] __initlocaldata = {
+ static char irq_tab[9][5] __initdata = {
/*INT INTA INTB INTC INTD */
{ 32+0, 32+0, 32+0, 32+0, 32+0}, /* IdSel 0, TULIP */
{ 32+1, 32+1, 32+1, 32+1, 32+1}, /* IdSel 1, SCSI */
@@ -143,7+143,7 @@ noname_map_irq(struct pci_dev *dev, u8 slot, u8 pin) * that they use the default INTA line, if they are interrupt
* driven at all).
*/
- static char irq_tab[][5] __initlocaldata = {
+ static char irq_tab[][5] __initdata = {
/*INT A B C D */
{ 3, 3, 3, 3, 3}, /* idsel 6 (53c810) */
{-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */
@@ -164,7+164,7 @@ noname_map_irq(struct pci_dev *dev, u8 slot, u8 pin) static inline int __init
p2k_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[][5] __initlocaldata = {
+ static char irq_tab[][5] __initdata = {
/*INT A B C D */
{ 0, 0, -1, -1, -1}, /* idsel 6 (53c810) */
{-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */
@@ -96,7+96,7 @@ sx164_init_irq(void) static int __init
sx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[5][5] __initlocaldata = {
+ static char irq_tab[5][5] __initdata = {
/*INT INTA INTB INTC INTD */
{ 16+ 9, 16+ 9, 16+13, 16+17, 16+21}, /* IdSel 5 slot 2 J17 */
{ 16+11, 16+11, 16+15, 16+19, 16+23}, /* IdSel 6 slot 0 J19 */
@@ -172,7+172,7 @@ takara_init_irq(void) static int __init
takara_map_irq_srm(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[15][5] __initlocaldata = {
+ static char irq_tab[15][5] __initdata = {
{ 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */
{ 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 7 == device 2 */
{ 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 8 == device 1 */
@@ -203,7+203,7 @@ takara_map_irq_srm(struct pci_dev *dev, u8 slot, u8 pin) static int __init
takara_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[15][5] __initlocaldata = {
+ static char irq_tab[15][5] __initdata = {
{ 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */
{ 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 7 == device 2 */
{ 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 8 == device 1 */
@@ -302,7+302,7 @@ wildfire_device_interrupt(unsigned long vector, struct pt_regs * regs) static int __init
wildfire_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- static char irq_tab[8][5] __initlocaldata = {
+ static char irq_tab[8][5] __initdata = {
/*INT INTA INTB INTC INTD */
{ -1, -1, -1, -1, -1}, /* IdSel 0 ISA Bridge */
{ 36, 36, 36+1, 36+2, 36+3}, /* IdSel 1 SCSI builtin */
@@ -23,62+23,59 @@ LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS)
CFLAGS += -pipe
-# only work around strength reduction bug(s) on older gcc versions
-CFLAGS += $(shell if ! $(CC) -march=i486 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strength-reduce"; fi)
-
# prevent gcc from keeping the stack 16 byte aligned
CFLAGS += $(shell if $(CC) -mpreferred-stack-boundary=2 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mpreferred-stack-boundary=2"; fi)
ifdef CONFIG_M386
-CFLAGS += $(shell if $(CC) -march=i386 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i386"; else echo "-m386"; fi)
+CFLAGS += -march=i386
endif
ifdef CONFIG_M486
-CFLAGS += $(shell if $(CC) -march=i486 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i486"; else echo "-m486"; fi)
+CFLAGS += -march=i486
endif
ifdef CONFIG_M586
-CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi)
+CFLAGS += -march=i586
endif
ifdef CONFIG_M586TSC
-CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi)
+CFLAGS += -march=i586
endif
ifdef CONFIG_M586MMX
-CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi)
+CFLAGS += -march=i586
endif
ifdef CONFIG_M686
-CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi)
+CFLAGS += -march=i686
endif
ifdef CONFIG_M686FXSR
-CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi)
+CFLAGS += -march=i686
endif
ifdef CONFIG_MK6
-CFLAGS += $(shell if $(CC) -march=k6 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=k6"; fi)
+CFLAGS += $(shell if $(CC) -march=k6 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=k6"; else echo "-march=i586"; fi)
endif
ifdef CONFIG_MK7
-CFLAGS += $(shell if $(CC) -march=athlon -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=athlon"; else if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686 -malign-functions=4"; fi fi)
+CFLAGS += $(shell if $(CC) -march=athlon -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=athlon"; else echo "-march=i686 -malign-functions=4"; fi)
endif
ifdef CONFIG_MCRUSOE
-CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi)
+CFLAGS += -march=i586
endif
ifdef CONFIG_MWINCHIPC6
-CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi)
+CFLAGS += -march=i586
endif
ifdef CONFIG_MWINCHIP2
-CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi)
+CFLAGS += -march=i586
endif
ifdef CONFIG_MWINCHIP3D
-CFLAGS += $(shell if $(CC) -march=i586 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i586"; fi)
+CFLAGS += -march=i586
endif
HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
@@ -230,6+230,7 @@ CONFIG_IDEPCI_SHARE_IRQ=y # CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_PDC202XX is not set
# CONFIG_PDC202XX_BURST is not set
+# CONFIG_BLK_DEV_OSB4 is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
@@ -262,9+262,7 @@ EXPORT_SYMBOL(__prom_getsibling);
/* sparc library symbols */
EXPORT_SYMBOL(__strlen);
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
EXPORT_SYMBOL(strlen);
-#endif
EXPORT_SYMBOL(strnlen);
EXPORT_SYMBOL(strcpy);
EXPORT_SYMBOL(strncpy);
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/netlink.h>
-#include <net/divert.h>
+#include <linux/divert.h>
#define NEXT_DEV NULL
@@ -1506,7+1506,7 @@ module_exit(cleanup_baycomepp);
static int __init baycom_epp_setup(char *str)
{
- static unsigned __initlocaldata nr_dev = 0;
+ static unsigned __initdata nr_dev = 0;
int ints[2];
if (nr_dev >= NR_PORTS)
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * $Id: tun.c,v 1.2 2000/09/22 12:40:31 maxk Exp $
+ * $Id: tun.c,v 1.3 2000/10/23 10:01:25 maxk Exp $
*/
/*
* Modifications for 2.3.99-pre5 kernel.
*/
-#define TUN_VER "1.2"
+#define TUN_VER "1.3"
#include <linux/module.h>
#include <asm/system.h>
#include <asm/uaccess.h>
-
#ifdef TUN_DEBUG
static int debug=0;
#endif
@@ -89,12+88,6 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->name, skb->len);
-
- if (netif_queue_stopped(dev))
- return 1;
-
- tun->stats.tx_packets++;
-
/* Queue frame */
skb_queue_tail(&tun->txq, skb);
if (skb_queue_len(&tun->txq) >= TUN_TXQ_SIZE)
@@ -233,6+226,8 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, const char *buf, netif_rx(skb);
tun->stats.rx_packets++;
+ tun->stats.rx_bytes += len;
+
return count;
}
@@ -281,6+276,9 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, copy_to_user(ptr, skb->data, len);
total += len;
+ tun->stats.tx_packets++;
+ tun->stats.tx_bytes += len;
+
return total;
}
@@ -1836,7+1836,7 @@ int pcmcia_request_io(client_handle_t handle, io_req_t *req)
======================================================================*/
-static int cs_request_irq(client_handle_t handle, irq_req_t *req)
+int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
{
socket_info_t *s;
config_t *c;
@@ -1902,7+1902,7 @@ static int cs_request_irq(client_handle_t handle, irq_req_t *req) c->state |= CONFIG_IRQ_REQ;
handle->state |= CLIENT_IRQ_REQ;
return CS_SUCCESS;
-} /* cs_request_irq */
+} /* pcmcia_request_irq */
/*======================================================================
* 12.08.1999 0.27 module_init/__setup fixes
* 19.08.1999 0.28 SOUND_MIXER_IMIX fixes, reported by Gianluca <gialluca@mail.tiscalinet.it>
* 31.08.1999 0.29 add spin_lock_init
- * __initlocaldata to fix gcc 2.7.x problems
* replaced current->state = x with set_current_state(x)
* 03.09.1999 0.30 change read semantics for MIDI to match
* OSS more closely; remove possible wakeup race
@@ -2677,7+2676,7 @@ module_exit(cleanup_es1370);
static int __init es1370_setup(char *str)
{
- static unsigned __initlocaldata nr_dev = 0;
+ static unsigned __initdata nr_dev = 0;
if (nr_dev >= NR_DEVICE)
return 0;
* updated SRC and CODEC w/r functions to accomodate bugs
* in some versions of the ES137x chips.
* 31.08.1999 0.17 add spin_lock_init
- * __initlocaldata to fix gcc 2.7.x problems
* replaced current->state = x with set_current_state(x)
* 03.09.1999 0.18 change read semantics for MIDI to match
* OSS more closely; remove possible wakeup race
@@ -2949,7+2948,7 @@ module_exit(cleanup_es1371);
static int __init es1371_setup(char *str)
{
- static unsigned __initlocaldata nr_dev = 0;
+ static unsigned __initdata nr_dev = 0;
if (nr_dev >= NR_DEVICE)
return 0;
* 12.08.1999 0.18 module_init/__setup fixes
* 24.08.1999 0.19 get rid of the dmaio kludge, replace with allocate_resource
* 31.08.1999 0.20 add spin_lock_init
- * __initlocaldata to fix gcc 2.7.x problems
* use new resource allocation to allocate DDMA IO space
* replaced current->state = x with set_current_state(x)
* 03.09.1999 0.21 change read semantics for MIDI to match
@@ -2451,7+2450,7 @@ static struct initvol {
static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
{
- static const char __initlocaldata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
+ static const char __initdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
struct sv_state *s;
mm_segment_t fs;
int i, val;
@@ -2694,7+2693,7 @@ module_exit(cleanup_sonicvibes);
static int __init sonicvibes_setup(char *str)
{
- static unsigned __initlocaldata nr_dev = 0;
+ static unsigned __initdata nr_dev = 0;
if (nr_dev >= NR_DEVICE)
return 0;
#include <linux/pm.h>
#define DRIVER_VERSION "0.14.6"
-//#define DEBUG
/* magic numbers to protect our data structures */
#define TRIDENT_CARD_MAGIC 0x5072696E /* "Prin" */
/* minor number of /dev/swmodem (temporary, experimental) */
#define SND_DEV_SWMODEM 7
-#define seek_offset(dma_ptr, buffer, dma_count, cnt, offset) (dma_ptr) += (offset); \
- (buffer) += (offset); \
- (dma_count) += (offset); \
- (cnt) -= (offset);
-
static const unsigned ali_multi_channels[] = { ALI_SURR_LEFT_CHANNEL, ALI_SURR_RIGHT_CHANNEL,ALI_CENTER_CHANNEL, ALI_LEF_CHANNEL/*, ALI_SURR_LEFT_CHANNEL, ALI_SURR_RIGHT_CHANNEL*/};
static const unsigned sample_size[] = { 1, 2, 2, 4 };
@@ -340,21+334,23 @@ static loff_t trident_llseek(struct file *file, loff_t offset, int origin);
static void ali_ac97_set(struct ac97_codec *codec, u8 reg, u16 val);
static u16 ali_ac97_get(struct ac97_codec *codec, u8 reg);
-void ali_set_spdif_out_rate(struct trident_card *card, unsigned int rate);
-void ali_enable_special_channel(struct trident_state *stat);
+static void ali_set_spdif_out_rate(struct trident_card *card, unsigned int rate);
+static void ali_enable_special_channel(struct trident_state *stat);
static struct trident_channel *ali_alloc_rec_pcm_channel(struct trident_card *card);
static struct trident_channel *ali_alloc_pcm_channel(struct trident_card *card);
static int ali_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data);
-void ali_restore_regs(struct trident_card *card);
-void ali_save_regs(struct trident_card *card);
+static void ali_restore_regs(struct trident_card *card);
+static void ali_save_regs(struct trident_card *card);
static int ali_allocate_multi_channels(struct trident_state *state, int chan_nums);
static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel);
static int ali_setup_multi_channels(struct trident_card *card, int chan_nums);
-unsigned int ali_get_spdif_in_rate(struct trident_card *card);
-void ali_setup_spdif_in(struct trident_card *card);
-void ali_disable_spdif_in(struct trident_card *card);
-void ali_disable_special_channel(struct trident_card *card, int ch);
-void ali_setup_spdif_out(struct trident_card *card, int flag);
+static unsigned int ali_get_spdif_in_rate(struct trident_card *card);
+static void ali_setup_spdif_in(struct trident_card *card);
+static void ali_disable_spdif_in(struct trident_card *card);
+static void ali_disable_special_channel(struct trident_card *card, int ch);
+static void ali_setup_spdif_out(struct trident_card *card, int flag);
+static unsigned int ali_write_5_1(struct trident_state *state, const char *buffer,int cnt_for_multi_channel);
+
/* save registers for ALi Power Management */
static struct ali_saved_registers {
@@ -363,10+359,9 @@ static struct ali_saved_registers { unsigned mixer_regs[ALI_MIXER_REGS];
} ali_registers;
-#define seek_offset(dma_ptr, buffer, dma_count, cnt, offset) (dma_ptr) += (offset); \
- (buffer) += (offset); \
- (dma_count) += (offset); \
- (cnt) -= (offset);
+#define seek_offset(dma_ptr, buffer, cnt, offset) (dma_ptr) += (offset); \
+ (buffer) += (offset); \
+ (cnt) -= (offset);
static int trident_enable_loop_interrupts(struct trident_card * card)
{
@@ -482,7+477,6 @@ static void trident_stop_voice(struct trident_card * card, unsigned int channel)
#ifdef DEBUG
reg = inl(TRID_REG(card, T4D_STOP_B));
- printk("ali:F0h=%lxh\n", inl(TRID_REG(card, 0xf0)));
printk("trident: stop voice on channel %d, STOP_B = 0x%08x\n",
channel, reg);
#endif
@@ -930,13+924,9 @@ static void start_dac(struct trident_state *state) trident_enable_voice_irq(card, chan_num);
trident_start_voice(card, chan_num);
if (state->chans_num == 6) {
- trident_enable_voice_irq(card, state->other_states[0]->dmabuf.channel->num);
trident_start_voice(card, state->other_states[0]->dmabuf.channel->num);
- trident_enable_voice_irq(card, state->other_states[1]->dmabuf.channel->num);
trident_start_voice(card, state->other_states[1]->dmabuf.channel->num);
- trident_enable_voice_irq(card, state->other_states[2]->dmabuf.channel->num);
trident_start_voice(card, state->other_states[2]->dmabuf.channel->num);
- trident_enable_voice_irq(card, state->other_states[3]->dmabuf.channel->num);
trident_start_voice(card, state->other_states[3]->dmabuf.channel->num);
}
}
@@ -1456,11+1446,11 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count {
struct trident_state *state = (struct trident_state *)file->private_data;
struct dmabuf *dmabuf = &state->dmabuf;
- struct dmabuf *dmabuf_temp;
ssize_t ret;
unsigned long flags;
- unsigned swptr, sample_s;
- int cnt, i, other_dma_nums, loop, cnt_for_multi_channel;
+ unsigned swptr;
+ int cnt;
+ unsigned int state_cnt;
#ifdef DEBUG
printk("trident: trident_write called, count = %d\n", count);
@@ -1476,12+1466,6 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count return -EFAULT;
ret = 0;
- if (state->chans_num == 6) {
- outl(ALI_MULTI_CHANNELS_START_STOP, TRID_REG(state->card, T4D_AINT_A));
- other_dma_nums = 4;
- sample_s = sample_size[state->dmabuf.fmt] >> 1;
- }
-
while (count > 0) {
spin_lock_irqsave(&state->card->lock, flags);
if (dmabuf->count < 0) {
@@ -1534,100+1518,28 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count }
continue;
}
- spin_lock_irqsave(&state->card->lock, flags);
+
if (state->chans_num == 6) {
- cnt_for_multi_channel = cnt;
- if ((i = state->multi_channels_adjust_count) > 0) {
- if (i == 1) {
- copy_from_user(dmabuf->rawbuf + dmabuf->swptr, buffer, sample_s);
- seek_offset(dmabuf->swptr, buffer, dmabuf->count, cnt_for_multi_channel, sample_s);
- dmabuf->swptr = dmabuf->swptr % dmabuf->dmasize;
- i--;
- state->multi_channels_adjust_count++;
- }
- else i = i - (state->chans_num - other_dma_nums);
- for (; (i < other_dma_nums) && (cnt_for_multi_channel > 0); i++) {
- dmabuf_temp = &state->other_states[i]->dmabuf;
- copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s);
- seek_offset(dmabuf_temp->swptr, buffer, dmabuf_temp->count, cnt_for_multi_channel, sample_s);
- dmabuf_temp->swptr = dmabuf_temp->swptr % dmabuf_temp->dmasize;
- }
- if (cnt_for_multi_channel == 0)
- state->multi_channels_adjust_count += i;
- }
- if (cnt_for_multi_channel > 0) {
- loop = cnt_for_multi_channel / (state->chans_num * sample_s);
- for (i = 0; i < loop; i++) {
- copy_from_user(dmabuf->rawbuf + dmabuf->swptr, buffer, sample_s * 2);
- seek_offset(dmabuf->swptr, buffer, dmabuf->count, cnt_for_multi_channel, sample_s * 2);
- dmabuf->swptr = dmabuf->swptr % dmabuf->dmasize;
-
- dmabuf_temp = &state->other_states[0]->dmabuf;
- copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s);
- seek_offset(dmabuf_temp->swptr, buffer, dmabuf_temp->count, cnt_for_multi_channel, sample_s);
- dmabuf_temp->swptr = dmabuf_temp->swptr % dmabuf_temp->dmasize;
-
- dmabuf_temp = &state->other_states[1]->dmabuf;
- copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s);
-
- seek_offset(dmabuf_temp->swptr, buffer, dmabuf_temp->count, cnt_for_multi_channel, sample_s);
- dmabuf_temp->swptr = dmabuf_temp->swptr % dmabuf_temp->dmasize;
-
- dmabuf_temp = &state->other_states[2]->dmabuf;
- copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s);
-
- seek_offset(dmabuf_temp->swptr, buffer, dmabuf_temp->count, cnt_for_multi_channel, sample_s);
- dmabuf_temp->swptr = dmabuf_temp->swptr % dmabuf_temp->dmasize;
-
- dmabuf_temp = &state->other_states[3]->dmabuf;
- copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s);
-
- seek_offset(dmabuf_temp->swptr, buffer, dmabuf_temp->count, cnt_for_multi_channel, sample_s);
- dmabuf_temp->swptr = dmabuf_temp->swptr % dmabuf_temp->dmasize;
- }
-
- if (cnt_for_multi_channel > 0) {
- state->multi_channels_adjust_count = cnt_for_multi_channel / sample_s;
-
- copy_from_user(dmabuf->rawbuf + dmabuf->swptr, buffer, sample_s);
- seek_offset(dmabuf->swptr, buffer, dmabuf->count, cnt_for_multi_channel, sample_s);
- dmabuf->swptr = dmabuf->swptr % dmabuf->dmasize;
-
- if (cnt_for_multi_channel > 0) {
- copy_from_user(dmabuf->rawbuf + dmabuf->swptr, buffer, sample_s);
- seek_offset(dmabuf->swptr, buffer, dmabuf->count, cnt_for_multi_channel, sample_s);
- dmabuf->swptr = dmabuf->swptr % dmabuf->dmasize;
-
- if (cnt_for_multi_channel > 0) {
- loop = state->multi_channels_adjust_count - (state->chans_num - other_dma_nums);
- for (i = 0; i < loop; i++) {
- dmabuf_temp = &state->other_states[i]->dmabuf;
- copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s);
- seek_offset(dmabuf_temp->swptr, buffer, dmabuf_temp->count, cnt_for_multi_channel, sample_s);
- dmabuf_temp->swptr = dmabuf_temp->swptr % dmabuf_temp->dmasize;
- }
- }
- }
- }
- else
- state->multi_channels_adjust_count = 0;
- }
+ state_cnt = ali_write_5_1(state, buffer, cnt);
}
else {
if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) {
if (!ret) ret = -EFAULT;
return ret;
}
- swptr = (swptr + cnt) % dmabuf->dmasize;
- dmabuf->swptr = swptr;
- dmabuf->count += cnt;
- buffer += cnt;
+ state_cnt = cnt;
}
+ swptr = (swptr + state_cnt) % dmabuf->dmasize;
+
+ spin_lock_irqsave(&state->card->lock, flags);
+ dmabuf->swptr = swptr;
+ dmabuf->count += state_cnt;
dmabuf->endcleared = 0;
spin_unlock_irqrestore(&state->card->lock, flags);
count -= cnt;
+ buffer += cnt;
ret += cnt;
start_dac(state);
}
@@ -2412,7+2324,7 @@ static u16 ali_ac97_get(struct ac97_codec *codec, u8 reg) return 0;
}
-void ali_enable_special_channel(struct trident_state *stat)
+static void ali_enable_special_channel(struct trident_state *stat)
{
struct trident_card *card = stat->card;
unsigned long s_channels;
@@ -2426,7+2338,7 @@ void ali_enable_special_channel(struct trident_state *stat) flag: ALI_SPDIF_OUT_TO_SPDIF_OUT
ALI_PCM_TO_SPDIF_OUT
*/
-void ali_setup_spdif_out(struct trident_card *card, int flag)
+static void ali_setup_spdif_out(struct trident_card *card, int flag)
{
unsigned long spdif;
unsigned char ch;
@@ -2454,7+2366,7 @@ void ali_setup_spdif_out(struct trident_card *card, int flag) }
}
-void ali_disable_special_channel(struct trident_card *card, int ch)
+static void ali_disable_special_channel(struct trident_card *card, int ch)
{
unsigned long sc;
@@ -2463,7+2375,7 @@ void ali_disable_special_channel(struct trident_card *card, int ch) outl(sc, TRID_REG(card, ALI_GLOBAL_CONTROL));
}
-void ali_disable_spdif_in(struct trident_card *card)
+static void ali_disable_spdif_in(struct trident_card *card)
{
unsigned long spdif;
@@ -2474,7+2386,7 @@ void ali_disable_spdif_in(struct trident_card *card) ali_disable_special_channel(card, ALI_SPDIF_IN_CHANNEL);
}
-void ali_setup_spdif_in(struct trident_card *card)
+static void ali_setup_spdif_in(struct trident_card *card)
{
unsigned long spdif;
@@ -2497,7+2409,7 @@ void ali_setup_spdif_in(struct trident_card *card) outb(spdif, TRID_REG(card, ALI_SPDIF_CTRL));
}
-unsigned int ali_get_spdif_in_rate(struct trident_card *card)
+static unsigned int ali_get_spdif_in_rate(struct trident_card *card)
{
unsigned long spdif, time1, time2;
unsigned count1, count2, count3;
@@ -2583,10+2495,6 @@ unsigned int ali_get_spdif_in_rate(struct trident_card *card) static int ali_setup_multi_channels(struct trident_card *card, int chan_nums)
{
unsigned long dwValue;
- char temp;
- unsigned short codec_value;
- struct pci_dev *pci_dev = NULL;
-
if (chan_nums == 6) {
dwValue = inl(TRID_REG(card, ALI_SCTRL)) | 0x000f0000;
outl(dwValue, TRID_REG(card, ALI_SCTRL));
@@ -2671,7+2579,7 @@ static int ali_allocate_multi_channels(struct trident_state *state, int chan_num return 0;
}
-void ali_save_regs(struct trident_card *card)
+static void ali_save_regs(struct trident_card *card)
{
unsigned long flags;
int i, j;
@@ -2709,7+2617,7 @@ void ali_save_regs(struct trident_card *card) restore_flags(flags);
}
-void ali_restore_regs(struct trident_card *card)
+static void ali_restore_regs(struct trident_card *card)
{
unsigned long flags;
int i, j;
@@ -2813,7+2721,7 @@ static struct trident_channel *ali_alloc_rec_pcm_channel(struct trident_card *ca return NULL;
}
-void ali_set_spdif_out_rate(struct trident_card *card, unsigned int rate)
+static void ali_set_spdif_out_rate(struct trident_card *card, unsigned int rate)
{
unsigned char ch_st_sel;
unsigned short status_rate;
@@ -2878,6+2786,98 @@ static void ali_address_interrupt(struct trident_card *card) }
}
+/* Updating the values of counters of other_states' DMAs without lock
+protection is no harm because all DMAs of multi-channels and interrupt
+depend on a master state's DMA, and changing the counters of the master
+state DMA is protected by a spinlock.
+*/
+static unsigned int ali_write_5_1(struct trident_state *state, const char *buf, int cnt_for_multi_channel)
+{
+
+ struct dmabuf *dmabuf = &state->dmabuf;
+ struct dmabuf *dmabuf_temp;
+ const char *buffer = buf;
+ unsigned swptr, other_dma_nums, sample_s;
+ unsigned int i, loop, state_cnt = 0;
+
+ other_dma_nums = 4;
+ sample_s = sample_size[dmabuf->fmt] >> 1;
+ swptr = dmabuf->swptr;
+
+ if ((i = state->multi_channels_adjust_count) > 0) {
+ if (i == 1) {
+ copy_from_user(dmabuf->rawbuf + swptr, buffer, sample_s);
+ seek_offset(swptr, buffer, cnt_for_multi_channel, sample_s);
+ i--;
+ state_cnt += sample_s;
+ state->multi_channels_adjust_count++;
+ }
+ else i = i - (state->chans_num - other_dma_nums);
+ for (; (i < other_dma_nums) && (cnt_for_multi_channel > 0); i++) {
+ dmabuf_temp = &state->other_states[i]->dmabuf;
+ copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s);
+ seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s);
+ }
+ if (cnt_for_multi_channel == 0)
+ state->multi_channels_adjust_count += i;
+ }
+ if (cnt_for_multi_channel > 0) {
+ loop = cnt_for_multi_channel / (state->chans_num * sample_s);
+ for (i = 0; i < loop; i++) {
+ copy_from_user(dmabuf->rawbuf + swptr, buffer, sample_s * 2);
+ seek_offset(swptr, buffer, cnt_for_multi_channel, sample_s * 2);
+
+ dmabuf_temp = &state->other_states[0]->dmabuf;
+ copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s);
+ seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s);
+
+ dmabuf_temp = &state->other_states[1]->dmabuf;
+ copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s);
+ seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s);
+
+ dmabuf_temp = &state->other_states[2]->dmabuf;
+ copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s);
+ seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s);
+
+ dmabuf_temp = &state->other_states[3]->dmabuf;
+ copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s);
+ seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s);
+ }
+
+ state_cnt += (sample_s * 2 * loop);
+
+ if (cnt_for_multi_channel > 0) {
+ state->multi_channels_adjust_count = cnt_for_multi_channel / sample_s;
+
+ copy_from_user(dmabuf->rawbuf + swptr, buffer, sample_s);
+ seek_offset(swptr, buffer, cnt_for_multi_channel, sample_s);
+ state_cnt += sample_s;
+
+ if (cnt_for_multi_channel > 0) {
+ copy_from_user(dmabuf->rawbuf + swptr, buffer, sample_s);
+ seek_offset(swptr, buffer, cnt_for_multi_channel, sample_s);
+ state_cnt += sample_s;
+
+ if (cnt_for_multi_channel > 0) {
+ loop = state->multi_channels_adjust_count - (state->chans_num - other_dma_nums);
+ for (i = 0; i < loop; i++) {
+ dmabuf_temp = &state->other_states[i]->dmabuf;
+ copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s);
+ seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s);
+ }
+ }
+ }
+ }
+ else
+ state->multi_channels_adjust_count = 0;
+ }
+ for (i = 0; i < other_dma_nums; i++) {
+ dmabuf_temp = &state->other_states[i]->dmabuf;
+ dmabuf_temp->swptr = dmabuf_temp->swptr % dmabuf_temp->dmasize;
+ }
+ return state_cnt;
+}
+
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *res = NULL;
static int ali_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
/* current USB framework handles max of 16 USB devices per driver */
-#define MAX_CAMERAS 8
+#define MAX_CAMERAS 16
/* USB char devs use USB_MAJOR and from USB_CAMERA_MINOR_BASE up */
#define USB_CAMERA_MINOR_BASE 80
/* table of cameras that work through this driver */
-static const struct camera {
- unsigned short idVendor;
- unsigned short idProduct;
- /* plus hooks for camera-specific info if needed */
-} cameras [] = {
+static __devinitdata struct usb_device_id camera_table [] = {
+
/* These have the same application level protocol */
- { 0x040a, 0x0120 }, // Kodak DC-240
- { 0x040a, 0x0130 }, // Kodak DC-280
- { 0x040a, 0x0132 }, // Kodak DC-3400
+ { idVendor: 0x040a, idProduct: 0x0120 }, // Kodak DC-240
+ { idVendor: 0x040a, idProduct: 0x0130 }, // Kodak DC-280
+ { idVendor: 0x040a, idProduct: 0x0132 }, // Kodak DC-3400
+ // { idVendor: 0x040a, idProduct: 0xXXXX }, // Kodak DC-5000
/* These have a different application level protocol which
* is part of the Flashpoint "DigitaOS". That supports some
* non-camera devices, and some non-Kodak cameras.
*/
- { 0x040a, 0x0100 }, // Kodak DC-220
- { 0x040a, 0x0110 }, // Kodak DC-260
- { 0x040a, 0x0111 }, // Kodak DC-265
- { 0x040a, 0x0112 }, // Kodak DC-290
- { 0xf003, 0x6002 }, // HP PhotoSmart C500
+ { idVendor: 0x040a, idProduct: 0x0100 }, // Kodak DC-220
+ { idVendor: 0x040a, idProduct: 0x0110 }, // Kodak DC-260
+ { idVendor: 0x040a, idProduct: 0x0111 }, // Kodak DC-265
+ { idVendor: 0x040a, idProduct: 0x0112 }, // Kodak DC-290
+ { idVendor: 0xf003, idProduct: 0x6002 }, // HP PhotoSmart C500
/* Other USB devices may well work here too, so long as they
* just stick to half duplex bulk packet exchanges. That
* means, among other things, no iso or interrupt endpoints.
*/
+
+ { } // TERMINATING ENTRY
};
+MODULE_DEVICE_TABLE (usb, camera_table);
+
struct camera_state {
struct usb_device *dev; /* USB device handle */
int inEP; /* read endpoint */
int outEP; /* write endpoint */
- const struct camera *info; /* DC-240, etc */
+ const struct usb_device_id *info; /* DC-240, etc */
int subminor; /* which minor dev #? */
struct semaphore sem; /* locks this struct */
@@ -343,27+345,15 @@ static /* const */ struct file_operations usb_camera_fops = {
-static void * camera_probe(struct usb_device *dev, unsigned int ifnum)
+static void * __devinit
+camera_bind (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *camera_info)
{
int i;
- const struct camera *camera_info = NULL;
struct usb_interface_descriptor *interface;
struct usb_endpoint_descriptor *endpoint;
int direction, ep;
struct camera_state *camera = NULL;
- /* Is it a supported camera? */
- for (i = 0; i < sizeof (cameras) / sizeof (struct camera); i++) {
- if (cameras [i].idVendor != dev->descriptor.idVendor)
- continue;
- if (cameras [i].idProduct != dev->descriptor.idProduct)
- continue;
- camera_info = &cameras [i];
- break;
- }
- if (camera_info == NULL)
- return NULL;
-
/* these have one config, one interface */
if (dev->descriptor.bNumConfigurations != 1
|| dev->config[0].bNumInterfaces != 1) {
@@ -437,7+427,8 @@ static void * camera_probe(struct usb_device *dev, unsigned int ifnum) goto error;
}
- info ("USB Camera #%d connected", camera->subminor);
+ info ("USB Camera #%d connected, major/minor %d/%d", camera->subminor,
+ USB_MAJOR, USB_CAMERA_MINOR_BASE + camera->subminor);
camera->dev = dev;
usb_inc_dev_use (dev);
return camera;
}
-static void camera_disconnect(struct usb_device *dev, void *ptr)
+static void __devexit camera_disconnect(struct usb_device *dev, void *ptr)
{
struct camera_state *camera = (struct camera_state *) ptr;
int subminor = camera->subminor;
@@ -477,12+468,14 @@ static void camera_disconnect(struct usb_device *dev, void *ptr) }
static /* const */ struct usb_driver camera_driver = {
- "dc2xx",
- camera_probe,
- camera_disconnect,
- { NULL, NULL },
- &usb_camera_fops,
- USB_CAMERA_MINOR_BASE
+ name: "dc2xx",
+
+ id_table: camera_table,
+ bind: camera_bind,
+ disconnect: camera_disconnect,
+
+ fops: &usb_camera_fops,
+ minor: USB_CAMERA_MINOR_BASE
};
@@ -142,6+142,7 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor * the hub can/will return fewer bytes here. */
if (ret < 0) {
err("Unable to get hub descriptor (err = %d)", ret);
+ kfree(hub->descriptor);
return -1;
}
@@ -191,6+192,7 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor ret = usb_get_hub_status(dev, &hubstatus);
if (ret < 0) {
err("Unable to get hub status (err = %d)", ret);
+ kfree(hub->descriptor);
return -1;
}
@@ -212,6+214,7 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor hub->urb = usb_alloc_urb(0);
if (!hub->urb) {
err("couldn't allocate interrupt urb");
+ kfree(hub->descriptor);
return -1;
}
@@ -220,6+223,7 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor ret = usb_submit_urb(hub->urb);
if (ret) {
err("usb_submit_urb failed (%d)", ret);
+ kfree(hub->descriptor);
return -1;
}
@@ -247,24+251,32 @@ static void *hub_probe(struct usb_device *dev, unsigned int i) /* Some hubs have a subclass of 1, which AFAICT according to the */
/* specs is not defined, but it works */
if ((interface->bInterfaceSubClass != 0) &&
- (interface->bInterfaceSubClass != 1))
+ (interface->bInterfaceSubClass != 1)) {
+ err("invalid subclass (%d) for USB hub device #%d",
+ interface->bInterfaceSubClass, dev->devnum);
return NULL;
+ }
/* Multiple endpoints? What kind of mutant ninja-hub is this? */
- if (interface->bNumEndpoints != 1)
+ if (interface->bNumEndpoints != 1) {
+ err("invalid bNumEndpoints (%d) for USB hub device #%d",
+ interface->bNumEndpoints, dev->devnum);
return NULL;
+ }
endpoint = &interface->endpoint[0];
/* Output endpoint? Curiousier and curiousier.. */
if (!(endpoint->bEndpointAddress & USB_DIR_IN)) {
- err("Device is hub class, but has output endpoint?");
+ err("Device #%d is hub class, but has output endpoint?",
+ dev->devnum);
return NULL;
}
/* If it's not an interrupt endpoint, we'd better punt! */
- if ((endpoint->bmAttributes & 3) != 3) {
- err("Device is hub class, but has endpoint other than interrupt?");
+ if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
+ err("Device #%d is hub class, but has endpoint other than interrupt?",
+ dev->devnum);
return NULL;
}
@@ -291,7+303,7 @@ static void *hub_probe(struct usb_device *dev, unsigned int i) if (usb_hub_configure(hub, endpoint) >= 0)
return hub;
- err("hub configuration failed");
+ err("hub configuration failed for device #%d", dev->devnum);
/* free hub, but first clean up its list. */
spin_lock_irqsave(&hub_event_lock, flags);
@@ -788,6+800,7 @@ int usb_hub_init(void)
/* Fall through if kernel_thread failed */
usb_deregister(&hub_driver);
+ err("failed to start usb_hub_thread");
return -1;
}
#include <linux/usb.h>
-static const struct product {
- char *name;
- u16 idVendor;
- u16 idProduct;
-} products [] = {
- { "NetChip TurboCONNECT", 0x0525, 0x1080 }, // reference
+static const struct usb_device_id products [] = {
+ { // reference design
+ idProduct: 0x1080,
+ idVendor: 0x0525,
+ driver_info: "NetChip TurboCONNECT",
+ },
// Belkin, ...
- { 0, 0, 0 }, // END
+ { }, // END
};
static u8 node_id [ETH_ALEN];
@@ -132,7+132,7 @@ struct skb_data { // skb->cb is one of these struct net1080 {
// housekeeping
struct usb_device *udev;
- const struct product *prod_info;
+ const struct usb_device_id *prod_info;
struct semaphore mutex;
struct list_head dev_list;
wait_queue_head_t *wait;
@@ -422,7+422,7 @@ static int net1080_reset (struct net1080 *dev) #endif
info ("%s: %s, port %c on USB %d dev %d, peer %sconnected",
- dev->net.name, dev->prod_info->name,
+ dev->net.name, (char *) dev->prod_info->driver_info,
(status & STATUS_PORT_A) ? 'A' : 'B',
dev->udev->bus->busnum,
dev->udev->devnum,
@@ -952,7+952,7 @@ static void net1080_disconnect (struct usb_device *udev, void *ptr) info ("%s: USB %d dev %d, %s, disconnected",
dev->net.name,
udev->bus->busnum, udev->devnum,
- dev->prod_info->name);
+ (char *) dev->prod_info->driver_info);
unregister_netdev (&dev->net);
@@ -973,24+973,14 @@ static void net1080_disconnect (struct usb_device *udev, void *ptr)
// precondition: never called in_interrupt
-static void *net1080_probe (struct usb_device *udev, unsigned ifnum)
+static void *
+net1080_bind (struct usb_device *udev, unsigned ifnum, const struct usb_device_id *prod)
{
- int i;
struct net1080 *dev;
struct net_device *net;
struct usb_interface_descriptor *interface;
int retval;
- for (i = 0; products [i].idVendor != 0; i++) {
- if (products [i].idVendor != udev->descriptor.idVendor)
- continue;
- if (products [i].idProduct != udev->descriptor.idProduct)
- continue;
- break;
- }
- if (products [i].idVendor == 0)
- return 0;
-
// sanity check; expect dedicated interface/devices for now.
interface = &udev->actconfig->interface [ifnum].altsetting[0];
if (udev->descriptor.bNumConfigurations != 1
@@ -1013,7+1003,7 @@ static void *net1080_probe (struct usb_device *udev, unsigned ifnum) init_MUTEX_LOCKED (&dev->mutex);
usb_inc_dev_use (udev);
dev->udev = udev;
- dev->prod_info = &products [i];
+ dev->prod_info = prod;
INIT_LIST_HEAD (&dev->dev_list);
skb_queue_head_init (&dev->rxq);
skb_queue_head_init (&dev->txq);
@@ -1067,7+1057,8 @@ static void *net1080_probe (struct usb_device *udev, unsigned ifnum)
static struct usb_driver net1080_driver = {
name: "net1080",
- probe: net1080_probe,
+ id_table: products,
+ bind: net1080_bind,
disconnect: net1080_disconnect,
};
@@ -190,6+190,8 @@ static int usblp_open(struct inode *inode, struct file *file) retval = retval > 1 ? -EIO : -ENOSPC;
goto out;
}
+#else
+ retval = 0;
#endif
usblp->used = 1;
@@ -383,6+385,7 @@ static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t return -EFAULT;
if ((usblp->readcount += count) == usblp->readurb.actual_length) {
+ usblp->readcount = 0;
usblp->readurb.dev = usblp->dev;
usb_submit_urb(&usblp->readurb);
}
/* Driver for USB Mass Storage compliant devices
* SCSI layer glue code
*
- * $Id: scsiglue.c,v 1.13 2000/09/28 21:54:30 mdharm Exp $
+ * $Id: scsiglue.c,v 1.15 2000/10/19 18:44:11 mdharm Exp $
*
* Current development and maintenance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -168,34+168,30 @@ static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) * Error handling functions
***********************************************************************/
-/* Command abort
- *
- * Note that this is really only meaningful right now for CBI transport
- * devices which have failed to give us the command completion interrupt
- */
+/* Command abort */
static int command_abort( Scsi_Cmnd *srb )
{
struct us_data *us = (struct us_data *)srb->host->hostdata[0];
- wait_queue_head_t *wqh = (wait_queue_head_t *)us->current_urb->context;
US_DEBUGP("command_abort() called\n");
/* if we're stuck waiting for an IRQ, simulate it */
- if (us->ip_wanted) {
+ if (atomic_read(us->ip_wanted)) {
US_DEBUGP("-- simulating missing IRQ\n");
up(&(us->ip_waitq));
+ }
+
+ /* if the device has been removed, this worked */
+ if (!us->pusb_dev) {
+ US_DEBUGP("-- device removed already\n");
return SUCCESS;
}
/* if we have an urb pending, let's wake the control thread up */
if (us->current_urb->status == -EINPROGRESS) {
- /* cancel the URB */
+ /* cancel the URB -- this will automatically wake the thread */
usb_unlink_urb(us->current_urb);
- /* wake the control thread up */
- if (waitqueue_active(wqh))
- wake_up(wqh);
-
/* wait for us to be done */
down(&(us->notify));
return SUCCESS;
@@ -226,6+222,12 @@ static int bus_reset( Scsi_Cmnd *srb ) /* we use the usb_reset_device() function to handle this for us */
US_DEBUGP("bus_reset() called\n");
+ /* if the device has been removed, this worked */
+ if (!us->pusb_dev) {
+ US_DEBUGP("-- device removed already\n");
+ return SUCCESS;
+ }
+
/* attempt to reset the port */
if (usb_reset_device(us->pusb_dev) < 0)
return FAILED;
/* Driver for USB Mass Storage compliant devices
*
- * $Id: transport.c,v 1.28 2000/10/03 01:06:07 mdharm Exp $
+ * $Id: transport.c,v 1.30 2000/10/24 02:01:18 mdharm Exp $
*
* Current development and maintenance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -412,6+412,9 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, FILL_CONTROL_URB(us->current_urb, us->pusb_dev, pipe,
(unsigned char*) dr, data, size,
usb_stor_blocking_completion, &wqh);
+ us->current_urb->actual_length = 0;
+ us->current_urb->error_count = 0;
+ us->current_urb->transfer_flags = USB_ASYNC_UNLINK;
/* submit the URB */
set_current_state(TASK_UNINTERRUPTIBLE);
@@ -426,7+429,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
/* wait for the completion of the URB */
up(&(us->current_urb_sem));
- if (us->current_urb->status == -EINPROGRESS)
+ while (us->current_urb->status == -EINPROGRESS)
schedule();
down(&(us->current_urb_sem));
@@ -466,6+469,9 @@ int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe, /* fill the URB */
FILL_BULK_URB(us->current_urb, us->pusb_dev, pipe, data, len,
usb_stor_blocking_completion, &wqh);
+ us->current_urb->actual_length = 0;
+ us->current_urb->error_count = 0;
+ us->current_urb->transfer_flags = USB_ASYNC_UNLINK;
/* submit the URB */
set_current_state(TASK_UNINTERRUPTIBLE);
@@ -479,7+485,7 @@ int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe,
/* wait for the completion of the URB */
up(&(us->current_urb_sem));
- if (us->current_urb->status == -EINPROGRESS)
+ while (us->current_urb->status == -EINPROGRESS)
schedule();
down(&(us->current_urb_sem));
@@ -825,8+831,9 @@ void usb_stor_CBI_irq(struct urb *urb)
/* was this a wanted interrupt? */
- if (us->ip_wanted) {
- us->ip_wanted = 0;
+ if (atomic_read(us->ip_wanted)) {
+ atomic_set(us->ip_wanted, 0);
+ US_DEBUGP("-- Current value of ip_waitq is: %d\n", atomic_read(&us->ip_waitq.count));
up(&(us->ip_waitq));
} else
US_DEBUGP("ERROR: Unwanted interrupt received!\n");
@@ -839,7+846,11 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us) int result;
/* Set up for status notification */
- us->ip_wanted = 1;
+ atomic_set(us->ip_wanted, 1);
+
+ /* re-initialize the mutex so that we avoid any races with
+ * early/late IRQs from previous commands */
+ init_MUTEX_LOCKED(&(us->ip_waitq));
/* COMMAND STAGE */
/* let's send the command via the control pipe */
@@ -852,7+863,7 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us) US_DEBUGP("Call to usb_stor_control_msg() returned %d\n", result);
if (result < 0) {
/* Reset flag for status notification */
- us->ip_wanted = 0;
+ atomic_set(us->ip_wanted, 0);
/* if the command was aborted, indicate that */
if (result == -ENOENT)
@@ -880,9+891,6 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
/* if it was aborted, we need to indicate that */
if (srb->result == USB_STOR_TRANSPORT_ABORTED) {
- /* we need to reset the state of this semaphore */
- down(&(us->ip_waitq));
-
return USB_STOR_TRANSPORT_ABORTED;
}
}
@@ -890,12+898,13 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us) /* STATUS STAGE */
/* go to sleep until we get this interrupt */
+ US_DEBUGP("Current value of ip_waitq is: %d\n", atomic_read(&us->ip_waitq.count));
down(&(us->ip_waitq));
/* if we were woken up by an abort instead of the actual interrupt */
- if (us->ip_wanted) {
+ if (atomic_read(us->ip_wanted)) {
US_DEBUGP("Did not get interrupt on CBI\n");
- us->ip_wanted = 0;
+ atomic_set(us->ip_wanted, 0);
return USB_STOR_TRANSPORT_ABORTED;
}
@@ -1040,6+1049,10 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) int result;
int pipe;
int partial;
+
+ /* if the device was removed, then we're already reset */
+ if (!us->pusb_dev)
+ return SUCCESS;
/* set up the command wrapper */
bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN);
@@ -1183,6+1196,10 @@ int usb_stor_CB_reset(struct us_data *us)
US_DEBUGP("CB_reset() called\n");
+ /* if the device was removed, then we're already reset */
+ if (!us->pusb_dev)
+ return SUCCESS;
+
memset(cmd, 0xFF, sizeof(cmd));
cmd[0] = SEND_DIAGNOSTIC;
cmd[1] = 4;
@@ -1221,6+1238,10 @@ int usb_stor_Bulk_reset(struct us_data *us)
US_DEBUGP("Bulk reset requested\n");
+ /* if the device was removed, then we're already reset */
+ if (!us->pusb_dev)
+ return SUCCESS;
+
result = usb_control_msg(us->pusb_dev,
usb_sndctrlpipe(us->pusb_dev,0),
US_BULK_RESET_REQUEST,
/* Driver for USB Mass Storage compliant devices
*
- * $Id: usb.c,v 1.46 2000/09/25 23:25:12 mdharm Exp $
+ * $Id: usb.c,v 1.51 2000/10/19 18:49:51 mdharm Exp $
*
* Current development and maintenance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -473,21+473,27 @@ static struct us_unusual_dev us_unusual_dev_list[] = {
{ 0x0781, 0x0001, 0x0200, 0x0200,
"Sandisk",
- "ImageMate SDDR05a",
+ "ImageMate SDDR-05a",
US_SC_SCSI, US_PR_CB, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP},
+ { 0x0781, 0x0100, 0x0100, 0x0100,
+ "Sandisk",
+ "ImageMate SDDR-12",
+ US_SC_SCSI, US_PR_CB, NULL,
+ US_FL_SINGLE_LUN },
+
#ifdef CONFIG_USB_STORAGE_SDDR09
{ 0x0781, 0x0200, 0x0100, 0x0100,
"Sandisk",
- "ImageMate SDDR09",
+ "ImageMate SDDR-09",
US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
US_FL_SINGLE_LUN | US_FL_START_STOP },
#endif
{ 0x0781, 0x0002, 0x0009, 0x0009,
"Sandisk",
- "ImageMate SDDR31",
+ "ImageMate SDDR-31",
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_IGNORE_SER},
@@ -696,19+702,20 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) US_DEBUGP("Endpoints: In: 0x%p Out: 0x%p Int: 0x%p (Period %d)\n",
ep_in, ep_out, ep_int, ep_int ? ep_int->bInterval : 0);
- /* set the interface -- STALL is an acceptable response here */
#ifdef CONFIG_USB_STORAGE_SDDR09
- if (protocol == US_PR_EUSB_SDDR09)
+ if (protocol == US_PR_EUSB_SDDR09 || protocol == US_PR_DPCM_USB) {
+ /* set the configuration -- STALL is an acceptable response here */
result = usb_set_configuration(dev, 1);
- US_DEBUGP("Result from usb_set_configuration is %d\n", result);
- if (result == -EPIPE) {
- US_DEBUGP("-- clearing stall on control interface\n");
- usb_clear_halt(dev, usb_sndctrlpipe(dev, 0));
- } else if (result != 0) {
- /* it's not a stall, but another error -- time to bail */
- US_DEBUGP("-- Unknown error. Rejecting device\n");
- return NULL;
+ US_DEBUGP("Result from usb_set_configuration is %d\n", result);
+ if (result == -EPIPE) {
+ US_DEBUGP("-- clearing stall on control interface\n");
+ usb_clear_halt(dev, usb_sndctrlpipe(dev, 0));
+ } else if (result != 0) {
+ /* it's not a stall, but another error -- time to bail */
+ US_DEBUGP("-- Unknown error. Rejecting device\n");
+ return NULL;
+ }
}
#endif
@@ -759,6+766,9 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) US_DEBUGP("Found existing GUID " GUID_FORMAT "\n",
GUID_ARGS(guid));
+ /* lock the device pointers */
+ down(&(ss->dev_semaphore));
+
/* establish the connection to the new device upon reconnect */
ss->ifnum = ifnum;
ss->pusb_dev = dev;
@@ -773,13+783,15 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) ss->ep_int = ep_int;
/* allocate an IRQ callback if one is needed */
- if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss))
+ if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) {
+ usb_dec_dev_use(dev);
return NULL;
+ }
/* allocate the URB we're going to use */
ss->current_urb = usb_alloc_urb(0);
if (!ss->current_urb) {
- kfree(ss);
+ usb_dec_dev_use(dev);
return NULL;
}
@@ -787,6+799,9 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) if (unusual_dev && unusual_dev->initFunction)
(unusual_dev->initFunction)(ss);
+ /* unlock the device pointers */
+ up(&(ss->dev_semaphore));
+
} else {
/* New device -- allocate memory and initialize */
US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid));
@@ -794,6+809,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) if ((ss = (struct us_data *)kmalloc(sizeof(struct us_data),
GFP_KERNEL)) == NULL) {
printk(KERN_WARNING USB_STORAGE "Out of memory\n");
+ usb_dec_dev_use(dev);
return NULL;
}
memset(ss, 0, sizeof(struct us_data));
@@ -802,6+818,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) ss->current_urb = usb_alloc_urb(0);
if (!ss->current_urb) {
kfree(ss);
+ usb_dec_dev_use(dev);
return NULL;
}
@@ -924,6+941,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) ss->transport_name = "Unknown";
kfree(ss->current_urb);
kfree(ss);
+ usb_dec_dev_use(dev);
return NULL;
break;
}
@@ -977,8+995,10 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) US_DEBUGP("Protocol: %s\n", ss->protocol_name);
/* allocate an IRQ callback if one is needed */
- if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss))
+ if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss)) {
+ usb_dec_dev_use(dev);
return NULL;
+ }
/*
* Since this is a new device, we need to generate a scsi
@@ -1011,6+1031,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum) "Unable to start control thread\n");
kfree(ss->current_urb);
kfree(ss);
+ usb_dec_dev_use(dev);
return NULL;
}
/* Driver for USB Mass Storage compliant devices
* Main Header File
*
- * $Id: usb.h,v 1.9 2000/09/25 23:25:12 mdharm Exp $
+ * $Id: usb.h,v 1.10 2000/10/19 18:44:11 mdharm Exp $
*
* Current development and maintenance by:
* (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -160,7+160,7 @@ struct us_data {
/* interrupt info for CBI devices -- only good if attached */
struct semaphore ip_waitq; /* for CBI interrupts */
- int ip_wanted; /* is an IRQ expected? */
+ atomic_t ip_wanted[1]; /* is an IRQ expected? */
/* interrupt communications data */
struct semaphore irq_urb_sem; /* to protect irq_urb */
@@ -466,6+466,10 @@ void usb_driver_release_interface(struct usb_driver *driver, struct usb_interfac * We now walk the list of registered USB drivers,
* looking for one that will accept this interface.
*
+ * "New Style" drivers use a table describing the devices and interfaces
+ * they handle. Those tables are available to user mode tools deciding
+ * whether to load driver modules for a new device.
+ *
* The probe return value is changed to be a private pointer. This way
* the drivers don't have to dig around in our structures to set the
* private pointer if they only need one interface.
@@ -494,7+498,70 @@ static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum)
tmp = tmp->next;
down(&driver->serialize);
- private = driver->probe(dev, ifnum);
+
+ /* new style driver? */
+ if (driver->bind) {
+ const struct usb_device_id *id = driver->id_table;
+
+ if (id) {
+ /* scan device ids for a match */
+ for (;; id++) {
+ struct usb_interface_descriptor *intf = 0;
+
+ /* done? */
+ if (!id->idVendor && !id->bDeviceClass && !id->bInterfaceClass) {
+ id = 0;
+ break;
+ }
+
+ /* Vendor match, possibly product-specific? */
+ if (id->idVendor && id->idVendor == dev->descriptor.idVendor) {
+ if (id->idProduct && id->idProduct != dev->descriptor.idProduct)
+ continue;
+ break;
+ }
+
+ /* Device class match? */
+ if (id->bDeviceClass
+ && id->bDeviceClass == dev->descriptor.bDeviceClass) {
+ if (id->bDeviceSubClass && id->bDeviceSubClass
+ != dev->descriptor.bDeviceClass)
+ continue;
+ if (id->bDeviceProtocol && id->bDeviceProtocol
+ != dev->descriptor.bDeviceProtocol)
+ continue;
+ break;
+ }
+
+ /* Interface class match? */
+ if (!interface->altsetting || interface->num_altsetting < 1)
+ continue;
+ intf = &interface->altsetting [0];
+ if (id->bInterfaceClass
+ && id->bInterfaceClass == intf->bInterfaceClass) {
+ if (id->bInterfaceSubClass && id->bInterfaceSubClass
+ != intf->bInterfaceClass)
+ continue;
+ if (id->bInterfaceProtocol && id->bInterfaceProtocol
+ != intf->bInterfaceProtocol)
+ continue;
+ break;
+ }
+ }
+
+ /* is this driver interested in this interface? */
+ if (id)
+ private = driver->bind(dev, ifnum, id);
+ else
+ private = 0;
+ } else {
+ /* "old style" driver, but using new interface */
+ private = driver->bind(dev, ifnum, 0);
+ }
+
+ /* "old style" driver */
+ } else
+ private = driver->probe(dev, ifnum);
up(&driver->serialize);
if (!private)
continue;
@@ -762,6+829,7 @@ void usb_inc_dev_use(struct usb_device *dev) {
atomic_inc(&dev->refcnt);
}
+
/* -------------------------------------------------------------------------------------
* New USB Core Functions
* -------------------------------------------------------------------------------------*/
@@ -840,7+908,6 @@ static int usb_start_wait_urb(urb_t *urb, int timeout, int* actual_length) int status;
awd.wakeup = &wqh;
- awd.handler = 0;
init_waitqueue_head(&wqh);
current->state = TASK_INTERRUPTIBLE;
add_wait_queue(&wqh, &wait);
@@ -1907,12+1907,13 @@ static unsigned long fbcon_getxy(struct vc_data *conp, unsigned long pos, int *p y += softback_lines;
ret = pos + (conp->vc_cols - x) * 2;
} else if (conp->vc_num == fg_console && softback_lines) {
- unsigned long offset = (pos - softback_curr) / 2;
+ unsigned long offset = pos - softback_curr;
+ if (pos < softback_curr)
+ offset += softback_end - softback_buf;
+ offset /= 2;
x = offset % conp->vc_cols;
y = offset / conp->vc_cols;
- if (pos < softback_curr)
- y += (softback_end - softback_buf) / conp->vc_size_row;
ret = pos + (conp->vc_cols - x) * 2;
if (ret == softback_end)
ret = softback_buf;
* David Mosberger-Tang, Martin Mares
*/
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
+#include <asm/param.h>
#include <asm/pgalloc.h>
#define DLINFO_ITEMS 13
@@ -159,23+160,24 @@ create_elf_tables(char *p, int argc, int envc, sp -= 2;
NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform);
}
- sp -= 2;
+ sp -= 3*2;
NEW_AUX_ENT(0, AT_HWCAP, hwcap);
+ NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE);
+ NEW_AUX_ENT(2, AT_CLKTCK, CLOCKS_PER_SEC);
if (exec) {
- sp -= 11*2;
+ sp -= 10*2;
NEW_AUX_ENT(0, AT_PHDR, load_addr + exec->e_phoff);
NEW_AUX_ENT(1, AT_PHENT, sizeof (struct elf_phdr));
NEW_AUX_ENT(2, AT_PHNUM, exec->e_phnum);
- NEW_AUX_ENT(3, AT_PAGESZ, ELF_EXEC_PAGESIZE);
- NEW_AUX_ENT(4, AT_BASE, interp_load_addr);
- NEW_AUX_ENT(5, AT_FLAGS, 0);
- NEW_AUX_ENT(6, AT_ENTRY, load_bias + exec->e_entry);
- NEW_AUX_ENT(7, AT_UID, (elf_addr_t) current->uid);
- NEW_AUX_ENT(8, AT_EUID, (elf_addr_t) current->euid);
- NEW_AUX_ENT(9, AT_GID, (elf_addr_t) current->gid);
- NEW_AUX_ENT(10, AT_EGID, (elf_addr_t) current->egid);
+ NEW_AUX_ENT(3, AT_BASE, interp_load_addr);
+ NEW_AUX_ENT(4, AT_FLAGS, 0);
+ NEW_AUX_ENT(5, AT_ENTRY, load_bias + exec->e_entry);
+ NEW_AUX_ENT(6, AT_UID, (elf_addr_t) current->uid);
+ NEW_AUX_ENT(7, AT_EUID, (elf_addr_t) current->euid);
+ NEW_AUX_ENT(8, AT_GID, (elf_addr_t) current->gid);
+ NEW_AUX_ENT(9, AT_EGID, (elf_addr_t) current->egid);
}
#undef NEW_AUX_ENT
-#ifndef _ALPHA_BYTEORDER_H
-#define _ALPHA_BYTEORDER_H
-
-#include <asm/types.h>
-
-/* EGCS 1.1 can, without scheduling, do just as good as we do here
- with the standard macros. And since it can schedule, it does even
- better in the end. */
-
-#if defined(__GNUC__) && __GNUC_MINOR__ < 91
-
-static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
-{
- __u64 t1, t2, t3;
-
- /* Break the final or's out of the block so that gcc can
- schedule them at will. Further, use add not or so that
- we elide the sign extend gcc will put in because the
- return type is not a long. */
-
- __asm__(
- "insbl %3,3,%1 # %1 = dd000000\n\t"
- "zapnot %3,2,%2 # %2 = 0000cc00\n\t"
- "sll %2,8,%2 # %2 = 00cc0000\n\t"
- "or %2,%1,%1 # %1 = ddcc0000\n\t"
- "zapnot %3,4,%2 # %2 = 00bb0000\n\t"
- "extbl %3,3,%0 # %0 = 000000aa\n\t"
- "srl %2,8,%2 # %2 = 0000bb00"
- : "=r"(t3), "=&r"(t1), "=&r"(t2)
- : "r"(x));
-
- return t3 + t2 + t1;
-}
-
-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
-{
- __u64 t1, t2;
-
- __asm__(
- "insbl %2,1,%1 # %1 = bb00\n\t"
- "extbl %2,1,%0 # %0 = 00aa"
- : "=r"(t1), "=&r"(t2) : "r"(x));
-
- return t1 | t2;
-}
-
-#define __arch__swab32(x) ___arch__swab32(x)
-#define __arch__swab16(x) ___arch__swab16(x)
-
-#endif /* __GNUC__ */
-
-#define __BYTEORDER_HAS_U64__
-
-#include <linux/byteorder/little_endian.h>
-
-#endif /* _ALPHA_BYTEORDER_H */
+#ifndef _ALPHA_BYTEORDER_H
+#define _ALPHA_BYTEORDER_H
+
+#include <asm/types.h>
+
+#define __BYTEORDER_HAS_U64__
+
+#include <linux/byteorder/little_endian.h>
+
+#endif /* _ALPHA_BYTEORDER_H */
* these tests and macros.
*/
-/*
- * EGCS (of varying versions) does a good job of using insxl and extxl.
- */
-
-#if 0 && (__GNUC__ > 2 || __GNUC_MINOR__ >= 91)
+#if 0
#define __kernel_insbl(val, shift) \
(((unsigned long)(val) & 0xfful) << ((shift) * 8))
#define __kernel_inswl(val, shift) \
@@ -18,28+18,19 @@ extern void * memmove(void *, const void *, size_t); /* For backward compatibility with modules. Unused otherwise. */
extern void * __memcpy(void *, const void *, size_t);
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
#define memcpy __builtin_memcpy
-#endif
#define __HAVE_ARCH_MEMSET
extern void * __constant_c_memset(void *, unsigned long, size_t);
extern void * __memset(void *, int, size_t);
extern void * memset(void *, int, size_t);
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
#define memset(s, c, n) \
(__builtin_constant_p(c) \
? (__builtin_constant_p(n) && (c) == 0 \
? __builtin_memset((s),0,(n)) \
: __constant_c_memset((s),0x0101010101010101UL*(unsigned char)(c),(n))) \
: __memset((s),(c),(n)))
-#else
-#define memset(s, c, n) \
-(__builtin_constant_p(c) \
- ? __constant_c_memset((s),0x0101010101010101UL*(unsigned char)(c),(n)) \
- : __memset((s),(c),(n)))
-#endif
#define __HAVE_ARCH_STRCPY
extern char * strcpy(char *,const char *);
-#ifndef __ASM_ARM_BYTEORDER_H
-#define __ASM_ARM_BYTEORDER_H
-
-#include <asm/types.h>
-
-#if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ < 8
-
-/* Recent versions of GCC can open code the swaps at least as well
- as we can write them by hand, so the "optimisations" here only
- make sense for older compilers. Worse, some versions of GCC
- actually go wrong in the presence of the assembler versions.
- We play it safe and only turn them on for compilers older than
- GCC 2.8.0. */
-
-static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
-{
- unsigned long xx;
- __asm__("eor\t%1, %0, %0, ror #16\n\t"
- "bic\t%1, %1, #0xff0000\n\t"
- "mov\t%0, %0, ror #8\n\t"
- "eor\t%0, %0, %1, lsr #8\n\t"
- : "=r" (x), "=&r" (xx)
- : "0" (x));
- return x;
-}
-
-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
-{
- __asm__("eor\t%0, %0, %0, lsr #8\n\t"
- "eor\t%0, %0, %0, lsl #8\n\t"
- "bic\t%0, %0, #0xff0000\n\t"
- "eor\t%0, %0, %0, lsr #8\n\t"
- : "=r" (x)
- : "0" (x));
- return x;
-}
-
-#define __arch__swab32(x) ___arch__swab32(x)
-#define __arch__swab16(x) ___arch__swab16(x)
-
-#endif /* __GNUC__ */
-
-#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
-# define __BYTEORDER_HAS_U64__
-# define __SWAB_64_THRU_32__
-#endif
-
-#include <linux/byteorder/little_endian.h>
-
-#endif
-
+#ifndef __ASM_ARM_BYTEORDER_H
+#define __ASM_ARM_BYTEORDER_H
+
+#include <asm/types.h>
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+# define __BYTEORDER_HAS_U64__
+# define __SWAB_64_THRU_32__
+#endif
+
+#include <linux/byteorder/little_endian.h>
+
+#endif
+
#ifndef _ASMARM_CURRENT_H
#define _ASMARM_CURRENT_H
-/* Old compilers seem to generate bad code if we allow `current' to be
- non volatile. */
-#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 90)
static inline struct task_struct *get_current(void) __attribute__ (( __const__ ));
-#endif
static inline struct task_struct *get_current(void)
{
#define MAXHOSTNAMELEN 64 /* max length of hostname */
+#ifdef __KERNEL__
+# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */
+#endif
+
#endif
#define MAXHOSTNAMELEN 64 /* max length of hostname */
+#ifdef __KERNEL__
+# define CLOCKS_PER_SEC HZ /* frequency at which times() counts */
+#endif
+
#endif /* _ASM_IA64_PARAM_H */
@@ -249,21+249,11 @@ unsigned long get_wchan(struct task_struct *p); * Note that __builtin_return_address(x>=1) is forbidden because GCC
* aborts compilation on some CPUs. It's simply not possible to unwind
* some CPU's stackframes.
- */
-#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
-/*
+ *
* __builtin_return_address works only for non-leaf functions. We avoid the
* overhead of a function call by forcing the compiler to save the return
* address register on the stack.
*/
#define return_address() ({__asm__ __volatile__("":::"$31");__builtin_return_address(0);})
-#else
-/*
- * __builtin_return_address is not implemented at all. Calling it
- * will return senseless values. Return NULL which at least is an obviously
- * senseless value.
- */
-#define return_address() NULL
-#endif
#endif /* _ASM_PROCESSOR_H */
__arginit __init; \
__arginit
-#define __initlocaldata __initdata
-
/* For assembly routines */
#define __INIT .section .text.init,"ax"
#define __FINIT .previous
@@ -38,11+38,7 @@ extern __inline__ void st_le32(volatile unsigned *addr, const unsigned val) /* alas, egcs sounds like it has a bug in this code that doesn't use the
inline asm correctly, and can cause file corruption. Until I hear that
it's fixed, I can live without the extra speed. I hope. */
-#if !(__GNUC__ >= 2 && __GNUC_MINOR__ >= 90)
#if 0
-# define __arch_swab16(x) ld_le16(&x)
-# define __arch_swab32(x) ld_le32(&x)
-#else
static __inline__ __const__ __u16 ___arch__swab16(__u16 value)
{
__u16 result;
@@ -68,8+64,6 @@ static __inline__ __const__ __u32 ___arch__swab32(__u32 value) #define __arch__swab16(x) ___arch__swab16(x)
#endif /* 0 */
-#endif
-
/* The same, but returns converted value from the location pointer by addr. */
#define __arch__swab16p(addr) ld_le16(addr)
#define __arch__swab32p(addr) ld_le32(addr)
#include <linux/init.h>
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 90 /* egcs */
#define __pmac __attribute__ ((__section__ (".text.pmac")))
#define __pmacdata __attribute__ ((__section__ (".data.pmac")))
#define __pmacfunc(__argpmac) \
__argopenfirmware __openfirmware; \
__argopenfirmware
-#else /* not egcs */
-
-#define __pmac
-#define __pmacdata
-#define __pmacfunc(x) x
-
-#define __prep
-#define __prepdata
-#define __prepfunc(x) x
-
-#define __apus
-#define __apusdata
-#define __apusfunc(x) x
-
-#define __openfirmware
-#define __openfirmwaredata
-#define __openfirmwarefunc(x) x
-
-#endif /* egcs */
-
#endif /* _PPC_INIT_H */
* this so lets disable it. - Anton
*/
#if 0
-/* #if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) */
/* We need the mb()'s so we don't trigger a compiler bug - Anton */
#define BUG() do { \
mb(); \
@@ -88,18+88,9 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
#define pte_ERROR(e) __builtin_trap()
#define pmd_ERROR(e) __builtin_trap()
#define pgd_ERROR(e) __builtin_trap()
-#else
-#define pte_ERROR(e) \
- printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
-#define pmd_ERROR(e) \
- printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
-#define pgd_ERROR(e) \
- printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
-#endif
BTFIXUPDEF_INT(page_none)
BTFIXUPDEF_INT(page_shared)
* assume GCC is being used.
*/
-#if (__GNUC__ > 2) || (__GNUC_MINOR__ >= 8)
-typedef unsigned long int __kernel_size_t;
-typedef long int __kernel_ssize_t;
-#else
-typedef unsigned long long __kernel_size_t;
-typedef long long __kernel_ssize_t;
-#endif
-
+typedef unsigned long __kernel_size_t;
+typedef long __kernel_ssize_t;
typedef long __kernel_ptrdiff_t;
typedef long __kernel_time_t;
typedef long __kernel_clock_t;
@@ -110,18+110,7 @@ static inline void *__constant_memset(void *s, int c, __kernel_size_t count) #define __HAVE_ARCH_STRLEN
extern __kernel_size_t __strlen(const char *);
-
-#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)
extern __kernel_size_t strlen(const char *);
-#else /* !EGCS */
-/* Ugly but it works around a bug in our original sparc64-linux-gcc. */
-#undef strlen
-#define strlen(__arg0) \
-({ int __strlen_res = __strlen(__arg0) + 1; \
- __strlen_res -= 1; \
- __strlen_res; \
-})
-#endif /* !EGCS */
#define __HAVE_ARCH_STRNCMP
@@ -165,6+165,7 @@ typedef __u64 Elf64_Word; #define AT_EGID 14 /* effective gid */
#define AT_PLATFORM 15 /* string identifying CPU for optimizations */
#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
+#define AT_CLKTCK 17 /* frequency at which times() increments */
typedef struct dynamic{
Elf32_Sword d_tag;
#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */
#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */
+#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */
+#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport
+ * over Ethernet
+ */
/*
* Non DIX types. Won't clash for 1500 types.
* static int init_variable __initdata = 0;
* static char linux_logo[] __initdata = { 0x32, 0x36, ... };
*
- * For initialized data not at file scope, i.e. within a function,
- * you should use __initlocaldata instead, due to a bug in GCC 2.7.
- * Don't forget to initialize the data, as gcc otherwise puts the
- * data into the bss section and not into the init section.
+ * Don't forget to initialize data not at file scope, i.e. within a function,
+ * as gcc otherwise puts the data into the bss section and not into the init
+ * section.
*/
#ifndef MODULE
@@ -122,8+121,6 @@ typedef void (*__cleanup_module_func_t)(void);
#endif
-#define __initlocaldata __initdata
-
#ifdef CONFIG_HOTPLUG
#define __devinit
#define __devinitdata
@@ -207,6+207,7 @@ __attribute__((section(".modinfo"))) = \ * and the C types which are to be passed as arg 2.
* pci - struct pci_device_id - List of PCI ids supported by this module
* isapnp - struct isapnp_device_id - List of ISA PnP ids supported by this module
+ * usb - struct usb_device_id - List of USB ids supported by this module
*/
#define MODULE_GENERIC_TABLE(gtype,name) \
static const unsigned long __module_##gtype##_size \
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
-#include <net/divert.h>
#include <asm/atomic.h>
#include <asm/cache.h>
#include <net/profile.h>
#endif
+struct divert_blk;
+
#define NET_XMIT_SUCCESS 0
#define NET_XMIT_DROP 1 /* skb dropped */
#define NET_XMIT_CN 2 /* congestion notification */
@@ -67,10+67,6 @@ extern inline unsigned long _page_hashfn(struct address_space * mapping, unsigne
#define page_hash(mapping,index) (page_hash_table+_page_hashfn(mapping,index))
-extern struct page * __find_get_page (struct address_space *mapping,
- unsigned long index, struct page **hash);
-#define find_get_page(mapping, index) \
- __find_get_page(mapping, index, page_hash(mapping, index))
extern struct page * __find_lock_page (struct address_space * mapping,
unsigned long index, struct page **hash);
extern void lock_page(struct page *page);
@@ -303,6+303,50 @@ struct usb_string_descriptor {
struct usb_device;
+/*
+ * Device table entry for "new style" table-driven USB drivers.
+ * User mode code can read these tables to choose which modules to load.
+ * Declare the table as __devinitdata, and as a MODULE_DEVICE_TABLE.
+ *
+ * With a device table provide bind() instead of probe(). Then the
+ * third bind() parameter will point to a matching entry from this
+ * table. (Null value reserved.)
+ *
+ * Terminate the driver's table with an all-zeroes entry.
+ * Init the fields you care about; zeroes are not used in comparisons.
+ */
+struct usb_device_id {
+ /*
+ * vendor/product codes are checked, if vendor is nonzero
+ * Range is for device revision (bcdDevice), inclusive;
+ * zero values here mean range isn't considered
+ */
+ __u16 idVendor;
+ __u16 idProduct;
+ __u16 bcdDevice_lo, bcdDevice_hi;
+
+ /*
+ * if device class != 0, these can be match criteria;
+ * but only if this bDeviceClass value is nonzero
+ */
+ __u8 bDeviceClass;
+ __u8 bDeviceSubClass;
+ __u8 bDeviceProtocol;
+
+ /*
+ * if interface class != 0, these can be match criteria;
+ * but only if this bInterfaceClass value is nonzero
+ */
+ __u8 bInterfaceClass;
+ __u8 bInterfaceSubClass;
+ __u8 bInterfaceProtocol;
+
+ /*
+ * for driver's use; not involved in driver matching.
+ */
+ unsigned long driver_info;
+};
+
struct usb_driver {
const char *name;
@@ -316,27+360,25 @@ struct usb_driver {
struct semaphore serialize;
+ /* ioctl -- userspace apps can talk to drivers through usbdevfs */
int (*ioctl)(struct usb_device *dev, unsigned int code, void *buf);
-};
-
-/*
- * Pointer to a device endpoint interrupt function -greg
- * Parameters:
- * int status - This needs to be defined. Right now each HCD
- * passes different transfer status bits back. Don't use it
- * until we come up with a common meaning.
- * void *buffer - This is a pointer to the data used in this
- * USB transfer.
- * int length - This is the number of bytes transferred in or out
- * of the buffer by this transfer. (-1 = unknown/unsupported)
- * void *dev_id - This is a user defined pointer set when the IRQ
- * is requested that is passed back.
- *
- * Special Cases:
- * if (status == USB_ST_REMOVED), don't trust buffer or len.
- */
-typedef int (*usb_device_irq)(int, void *, int, void *);
+ /* support for "new-style" USB hotplugging
+ * binding policy can be driven from user mode too
+ */
+ const struct usb_device_id *id_table;
+ void *(*bind)(
+ struct usb_device *dev, /* the device */
+ unsigned intf, /* what interface */
+ const struct usb_device_id *id /* from id_table */
+ );
+
+ /* suspend before the bus suspends;
+ * disconnect or resume when the bus resumes */
+ // void (*suspend)(struct usb_device *dev);
+ // void (*resume)(struct usb_device *dev);
+};
+
/*----------------------------------------------------------------------------*
* New USB Structures *
*----------------------------------------------------------------------------*/
@@ -459,22+501,17 @@ int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, devr int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout);
/*-------------------------------------------------------------------*
- * COMPATIBILITY STUFF *
+ * SYNCHRONOUS CALL SUPPORT *
*-------------------------------------------------------------------*/
+
typedef struct
{
wait_queue_head_t *wakeup;
- usb_device_irq handler;
void* stuff;
/* more to follow */
} api_wrapper_data;
-struct irq_wrapper_data {
- void *context;
- usb_device_irq handler;
-};
-
/* -------------------------------------------------------------------------- */
struct usb_operations {
@@ -246,7+246,6 @@ EXPORT_SYMBOL(generic_read_dir); EXPORT_SYMBOL(__pollwait);
EXPORT_SYMBOL(poll_freewait);
EXPORT_SYMBOL(ROOT_DEV);
-EXPORT_SYMBOL(__find_get_page);
EXPORT_SYMBOL(__find_lock_page);
EXPORT_SYMBOL(grab_cache_page);
EXPORT_SYMBOL(read_cache_page);
@@ -503,20+503,46 @@ void ___wait_on_page(struct page *page) }
/*
- * Get an exclusive lock on the page..
+ * Get a lock on the page, assuming we need to sleep
+ * to get it..
*/
-void lock_page(struct page *page)
+static void __lock_page(struct page *page)
{
- while (TryLockPage(page))
- ___wait_on_page(page);
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+ add_wait_queue_exclusive(&page->wait, &wait);
+ for (;;) {
+ sync_page(page);
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ if (PageLocked(page)) {
+ run_task_queue(&tq_disk);
+ schedule();
+ continue;
+ }
+ if (!TryLockPage(page))
+ break;
+ }
+ tsk->state = TASK_RUNNING;
+ remove_wait_queue(&page->wait, &wait);
}
+
+/*
+ * Get an exclusive lock on the page, optimistically
+ * assuming it's not locked..
+ */
+void lock_page(struct page *page)
+{
+ if (TryLockPage(page))
+ __lock_page(page);
+}
/*
* a rather lightweight function, finding and getting a reference to a
* hashed page atomically, waiting for it if it's locked.
*/
-struct page * __find_get_page (struct address_space *mapping,
+static struct page * __find_get_page(struct address_space *mapping,
unsigned long offset, struct page **hash)
{
struct page *page;
@@ -525,41+551,11 @@ struct page * __find_get_page (struct address_space *mapping, * We scan the hash list read-only. Addition to and removal from
* the hash-list needs a held write-lock.
*/
-repeat:
spin_lock(&pagecache_lock);
page = __find_page_nolock(mapping, offset, *hash);
if (page)
page_cache_get(page);
spin_unlock(&pagecache_lock);
-
- /* Found the page, sleep if locked. */
- if (page && PageLocked(page)) {
- struct task_struct *tsk = current;
- DECLARE_WAITQUEUE(wait, tsk);
-
- sync_page(page);
-
- __set_task_state(tsk, TASK_UNINTERRUPTIBLE);
- add_wait_queue(&page->wait, &wait);
-
- if (PageLocked(page))
- schedule();
- __set_task_state(tsk, TASK_RUNNING);
- remove_wait_queue(&page->wait, &wait);
-
- /*
- * The page might have been unhashed meanwhile. It's
- * not freed though because we hold a reference to it.
- * If this is the case then it will be freed _here_,
- * and we recheck the hash anyway.
- */
- page_cache_release(page);
- goto repeat;
- }
- /*
- * It's not locked so we can return the page and we hold
- * a reference to it.
- */
return page;
}
@@ -578,39+574,23 @@ struct page * __find_lock_page (struct address_space *mapping, repeat:
spin_lock(&pagecache_lock);
page = __find_page_nolock(mapping, offset, *hash);
- if (page)
+ if (page) {
page_cache_get(page);
- spin_unlock(&pagecache_lock);
-
- /* Found the page, sleep if locked. */
- if (page && TryLockPage(page)) {
- struct task_struct *tsk = current;
- DECLARE_WAITQUEUE(wait, tsk);
-
- sync_page(page);
+ spin_unlock(&pagecache_lock);
- __set_task_state(tsk, TASK_UNINTERRUPTIBLE);
- add_wait_queue(&page->wait, &wait);
+ lock_page(page);
- if (PageLocked(page))
- schedule();
- __set_task_state(tsk, TASK_RUNNING);
- remove_wait_queue(&page->wait, &wait);
+ /* Is the page still hashed? Ok, good.. */
+ if (page->mapping)
+ return page;
- /*
- * The page might have been unhashed meanwhile. It's
- * not freed though because we hold a reference to it.
- * If this is the case then it will be freed _here_,
- * and we recheck the hash anyway.
- */
+ /* Nope: we raced. Release and try again.. */
+ UnlockPage(page);
page_cache_release(page);
goto repeat;
}
- /*
- * It's not locked so we can return the page and we hold
- * a reference to it.
- */
- return page;
+ spin_unlock(&pagecache_lock);
+ return NULL;
}
#if 0
@@ -1035,6+1015,15 @@ page_not_up_to_date:
/* Get exclusive access to the page ... */
lock_page(page);
+
+ /* Did it get unhashed before we got the lock? */
+ if (!page->mapping) {
+ UnlockPage(page);
+ page_cache_release(page);
+ continue;
+ }
+
+ /* Did somebody else fill it already? */
if (Page_Uptodate(page)) {
UnlockPage(page);
goto page_ok;
@@ -1331,16+1320,16 @@ struct page * filemap_nopage(struct vm_area_struct * area, struct inode *inode = file->f_dentry->d_inode;
struct address_space *mapping = inode->i_mapping;
struct page *page, **hash, *old_page;
- unsigned long size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+ unsigned long size, pgoff;
- unsigned long pgoff = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff;
+ pgoff = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff;
+retry_all:
/*
- * Semantics for shared and private memory areas are different
- * past the end of the file. A shared mapping past the last page
- * of the file is an error and results in a SIGBUS, while a
- * private mapping just maps in a zero page.
+ * An external ptracer can access pages that normally aren't
+ * accessible..
*/
+ size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
if ((pgoff >= size) && (area->vm_mm == current->mm))
return NULL;
@@ -1419,6+1408,15 @@ no_cached_page:
page_not_uptodate:
lock_page(page);
+
+ /* Did it get unhashed while we waited for it? */
+ if (!page->mapping) {
+ UnlockPage(page);
+ page_cache_release(page);
+ goto retry_all;
+ }
+
+ /* Did somebody else get it up-to-date? */
if (Page_Uptodate(page)) {
UnlockPage(page);
goto success;
@@ -1437,6+1435,15 @@ page_not_uptodate: * and we need to check for errors.
*/
lock_page(page);
+
+ /* Somebody truncated the page on us? */
+ if (!page->mapping) {
+ UnlockPage(page);
+ page_cache_release(page);
+ goto retry_all;
+ }
+
+ /* Somebody else successfully read it in? */
if (Page_Uptodate(page)) {
UnlockPage(page);
goto success;
@@ -1535,7+1542,12 @@ static inline int filemap_sync_pte(pte_t * ptep, struct vm_area_struct *vma,
spin_unlock(&vma->vm_mm->page_table_lock);
lock_page(page);
- error = filemap_write_page(vma->vm_file, page, 1);
+
+ error = 0;
+ /* Nothing to do if somebody truncated the page from under us.. */
+ if (page->mapping)
+ error = filemap_write_page(vma->vm_file, page, 1);
+
UnlockPage(page);
page_cache_free(page);
@@ -174,6+174,7 @@ void deactivate_page_nolock(struct page * page) */
int maxcount = (page->buffers ? 3 : 2);
page->age = 0;
+ ClearPageReferenced(page);
/*
* Don't touch it if it's not on the active list.
@@ -56,20+56,7 @@ static int try_to_swap_out(struct mm_struct * mm, struct vm_area_struct* vma, un onlist = PageActive(page);
/* Don't look at this pte if it's been accessed recently. */
if (ptep_test_and_clear_young(page_table)) {
- if (onlist) {
- /*
- * Transfer the "accessed" bit from the page
- * tables to the global page map. Page aging
- * will be done by refill_inactive_scan().
- */
- SetPageReferenced(page);
- } else {
- /*
- * The page is not on the active list, so
- * we have to do the page aging ourselves.
- */
- age_page_up(page);
- }
+ age_page_up(page);
goto out_failed;
}
if (!onlist)
@@ -797,7+784,8 @@ int refill_inactive_scan(unsigned int priority, int oneshot) *
* SUBTLE: we can have buffer pages with count 1.
*/
- if (page_count(page) <= (page->buffers ? 2 : 1)) {
+ if (page->age == 0 && page_count(page) <=
+ (page->buffers ? 2 : 1)) {
deactivate_page_nolock(page);
page_active = 0;
} else {
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/if_bridge.h>
-#include <net/divert.h>
+#include <linux/divert.h>
#include <net/dst.h>
#include <net/pkt_sched.h>
#include <net/profile.h>
/* Deliver skb to an old protocol, which is not threaded well
or which do not understand shared skbs.
*/
-static void deliver_to_old_ones(struct packet_type *pt, struct sk_buff *skb, int last)
+static int deliver_to_old_ones(struct packet_type *pt, struct sk_buff *skb, int last)
{
static spinlock_t net_bh_lock = SPIN_LOCK_UNLOCKED;
+ int ret = NET_RX_DROP;
+
if (!last) {
skb = skb_clone(skb, GFP_ATOMIC);
if (skb == NULL)
- return;
+ return ret;
}
/* The assumption (correct one) is that old protocols
@@ -1178,10+1180,11 @@ static void deliver_to_old_ones(struct packet_type *pt, struct sk_buff *skb, int /* Disable timers and wait for all timers completion */
tasklet_disable(bh_task_vec+TIMER_BH);
- pt->func(skb, skb->dev, pt);
+ ret = pt->func(skb, skb->dev, pt);
tasklet_enable(bh_task_vec+TIMER_BH);
spin_unlock(&net_bh_lock);
+ return ret;
}
/* Reparent skb to master device. This function is called
@@ -1264,19+1267,22 @@ void net_call_rx_atomic(void (*fn)(void)) void (*br_handle_frame_hook)(struct sk_buff *skb) = NULL;
#endif
-static void __inline__ handle_bridge(struct sk_buff *skb,
+static int __inline__ handle_bridge(struct sk_buff *skb,
struct packet_type *pt_prev)
{
+ int ret = NET_RX_DROP;
+
if (pt_prev) {
if (!pt_prev->data)
- deliver_to_old_ones(pt_prev, skb, 0);
+ ret = deliver_to_old_ones(pt_prev, skb, 0);
else {
atomic_inc(&skb->users);
- pt_prev->func(skb, skb->dev, pt_prev);
+ ret = pt_prev->func(skb, skb->dev, pt_prev);
}
}
br_handle_frame_hook(skb);
+ return ret;
}
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/checksum.h>
-#include <net/divert.h>
+#include <linux/divert.h>
#include <linux/sockios.h>
const char sysctl_divert_version[32]="0.46"; /* Current version */
*
* PF_INET protocol family socket handler.
*
- * Version: $Id: af_inet.c,v 1.120 2000/10/22 16:06:56 davem Exp $
+ * Version: $Id: af_inet.c,v 1.121 2000/10/24 21:26:18 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
#include <linux/kmod.h>
#endif
#ifdef CONFIG_NET_DIVERT
-#include <net/divert.h>
+#include <linux/divert.h>
#endif /* CONFIG_NET_DIVERT */
#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
#include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
*
* The IP forwarding functionality.
*
- * Version: $Id: ip_forward.c,v 1.46 2000/01/09 02:19:37 davem Exp $
+ * Version: $Id: ip_forward.c,v 1.47 2000/10/24 22:54:26 davem Exp $
*
* Authors: see ip.c
*
@@ -63,13+63,11 @@ static inline int ip_forward_finish(struct sk_buff *skb) dst_release(old_dst);
}
#endif
- ip_send(skb);
- return 0;
+ return (ip_send(skb));
}
ip_forward_options(skb);
- ip_send(skb);
- return 0;
+ return (ip_send(skb));
}
int ip_forward(struct sk_buff *skb)
@@ -81,7+79,7 @@ int ip_forward(struct sk_buff *skb) unsigned short mtu;
if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb))
- return 0;
+ return NET_RX_SUCCESS;
if (skb->pkt_type != PACKET_HOST)
goto drop;
@@ -119,7+117,7 @@ int ip_forward(struct sk_buff *skb)
/* We are about to mangle packet. Copy it! */
if ((skb = skb_cow(skb, dev2->hard_header_len)) == NULL)
- return -1;
+ return NET_RX_DROP;
iph = skb->nh.iph;
opt = &(IPCB(skb)->opt);
@@ -138,7+136,7 @@ int ip_forward(struct sk_buff *skb) if (rt->rt_flags & RTCF_NAT) {
if (ip_do_nat(skb)) {
kfree_skb(skb);
- return -1;
+ return NET_RX_BAD;
}
}
#endif
@@ -163,5+161,5 @@ too_many_hops: icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
drop:
kfree_skb(skb);
- return -1;
+ return NET_RX_DROP;
}
*
* The Internet Protocol (IP) module.
*
- * Version: $Id: ip_input.c,v 1.49 2000/08/21 20:41:55 davem Exp $
+ * Version: $Id: ip_input.c,v 1.50 2000/10/24 22:54:26 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -341,7+341,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb)
skb = skb_cow(skb, skb_headroom(skb));
if (skb == NULL)
- return 0;
+ return NET_RX_DROP;
iph = skb->nh.iph;
skb->ip_summed = 0;
@@ -372,7+372,7 @@ inhdr_error: IP_INC_STATS_BH(IpInHdrErrors);
drop:
kfree_skb(skb);
- return(0);
+ return NET_RX_DROP;
}
/*
@@ -429,6+429,6 @@ inhdr_error: drop:
kfree_skb(skb);
out:
- return(0);
+ return NET_RX_DROP;
}
*
* Dumb Network Address Translation.
*
- * Version: $Id: ip_nat_dumb.c,v 1.9 1999/08/20 11:05:46 davem Exp $
+ * Version: $Id: ip_nat_dumb.c,v 1.10 2000/10/24 22:54:26 davem Exp $
*
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
*
@@ -152,8+152,9 @@ ip_do_nat(struct sk_buff *skb) break;
}
}
- return 0;
+ return NET_RX_SUCCESS;
truncated:
+ /* should be return NET_RX_BAD; */
return -EINVAL;
}
*
* The Internet Protocol (IP) output module.
*
- * Version: $Id: ip_output.c,v 1.85 2000/08/31 23:39:12 davem Exp $
+ * Version: $Id: ip_output.c,v 1.87 2000/10/25 20:07:22 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -183,24+183,24 @@ static struct ip_tunnel **ipip_bucket(struct ip_tunnel *t)
static void ipip_tunnel_unlink(struct ip_tunnel *t)
{
- struct ip_tunnel **tp = ipip_bucket(t);
+ struct ip_tunnel **tp;
- write_lock_bh(&ipip_lock);
- for ( ; *tp; tp = &(*tp)->next) {
+ for (tp = ipip_bucket(t); *tp; tp = &(*tp)->next) {
if (t == *tp) {
+ write_lock_bh(&ipip_lock);
*tp = t->next;
+ write_unlock_bh(&ipip_lock);
break;
}
}
- write_unlock_bh(&ipip_lock);
}
static void ipip_tunnel_link(struct ip_tunnel *t)
{
struct ip_tunnel **tp = ipip_bucket(t);
- write_lock_bh(&ipip_lock);
t->next = *tp;
+ write_lock_bh(&ipip_lock);
*tp = t;
write_unlock_bh(&ipip_lock);
}
*
* RAW - implementation of IP "raw" sockets.
*
- * Version: $Id: raw.c,v 1.54 2000/10/18 18:04:23 davem Exp $
+ * Version: $Id: raw.c,v 1.55 2000/10/24 22:54:26 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -227,11+227,11 @@ static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb) {
IP_INC_STATS(IpInDiscards);
kfree_skb(skb);
- return -1;
+ return NET_RX_DROP;
}
IP_INC_STATS(IpInDelivers);
- return 0;
+ return NET_RX_SUCCESS;
}
/*
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/sockios.h>
-#include <linux/init.h>
#include <linux/if_arp.h>
#include <linux/net.h>
#include <linux/irda.h>
#include <linux/if_bridge.h>
#include <linux/random.h>
#ifdef CONFIG_NET_DIVERT
-#include <net/divert.h>
+#include <linux/divert.h>
#endif /* CONFIG_NET_DIVERT */
#ifdef CONFIG_NET
*
* PACKET - implements raw packet sockets.
*
- * Version: $Id: af_packet.c,v 1.45 2000/10/19 01:05:35 davem Exp $
+ * Version: $Id: af_packet.c,v 1.46 2000/10/24 21:26:19 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
#include <linux/if_bridge.h>
#ifdef CONFIG_NET_DIVERT
-#include <net/divert.h>
+#include <linux/divert.h>
#endif /* CONFIG_NET_DIVERT */
#ifdef CONFIG_INET