rename packages/ to recipes/ per earlier agreement
[openembedded.git] / recipes / linux / linux-wrt-2.4.20 / 2.4.20_broadcom_3_37_2_1109_US.patch
1
2 #
3 # Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
4 #
5
6 --- linux-2.4.20/Makefile~2.4.20_broadcom_3_37_2_1109_US.patch  2005-01-07 05:39:02.000000000 -0500
7 +++ linux-2.4.20/Makefile       2005-01-08 12:16:21.886535400 -0500
8 @@ -90,11 +90,26 @@
9  
10  CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
11           -fno-strict-aliasing -fno-common
12 +
13 +# Turn on -pg to instrument the kernel with calls to mcount().
14 +# Unfortunately, gcc won't allow -pg without frame pointers.
15 +ifdef CONFIG_MCOUNT
16 +  CFLAGS += -pg
17 +  CFLAGS_KERNEL += -pg
18 +  CONFIG_FRAME_POINTER = 1
19 +endif
20  ifndef CONFIG_FRAME_POINTER
21  CFLAGS += -fomit-frame-pointer
22  endif
23  AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
24  
25 +# Broadcom HWNBU source tree
26 +export SRCBASE := $(TOPDIR)/../..
27 +CFLAGS += -I$(SRCBASE)/include
28 +AFLAGS += -I$(SRCBASE)/include
29 +ASFLAGS += -I$(SRCBASE)/include
30 +
31 +
32  #
33  # ROOT_DEV specifies the default root-device when making the image.
34  # This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
35 --- linux-2.4.20/Rules.make~2.4.20_broadcom_3_37_2_1109_US.patch        2005-01-07 05:38:15.000000000 -0500
36 +++ linux-2.4.20/Rules.make     2005-01-07 05:39:02.000000000 -0500
37 @@ -176,7 +176,14 @@
38  _modinst__: dummy
39  ifneq "$(strip $(ALL_MOBJS))" ""
40         mkdir -p $(MODLIB)/kernel/$(MOD_DESTDIR)
41 -       cp $(sort $(ALL_MOBJS)) $(MODLIB)/kernel/$(MOD_DESTDIR)
42 +#      cp $(sort $(ALL_MOBJS)) $(MODLIB)/kernel/$(MOD_DESTDIR)
43 +       for f in $(ALL_MOBJS) ; do \
44 +           $(OBJCOPY) -R __ksymtab -R .comment -R .note -x \
45 +           `$(NM) $$f | cut -f3- -d' ' | sed -n \
46 +           -e 's/__module_parm_\(.*\)/-K \1/p' \
47 +           -e 's/__ks..tab_\(.*\)/-K \1/p'` \
48 +           $$f $(MODLIB)/kernel/$(MOD_DESTDIR)$(MOD_TARGET)$$f ; \
49 +       done
50  endif
51  
52  .PHONY: modules_install
53 --- linux-2.4.20/arch/mips/Makefile~2.4.20_broadcom_3_37_2_1109_US.patch        2005-01-07 05:39:01.000000000 -0500
54 +++ linux-2.4.20/arch/mips/Makefile     2005-01-08 12:16:19.825848672 -0500
55 @@ -39,10 +39,10 @@
56  GCCFLAGS       := -I $(TOPDIR)/include/asm/gcc
57  GCCFLAGS       += -G 0 -mno-abicalls -fno-pic -pipe
58  LINKFLAGS      += -G 0 -static # -N
59 -MODFLAGS       += -mlong-calls
60 +MODFLAGS       += -mlong-calls -fno-common
61  
62 -ifdef CONFIG_REMOTE_DEBUG
63 -GCCFLAGS       += -g
64 +ifdef CONFIG_DEBUG
65 +GCCFLAGS       += -gstabs+
66  ifdef CONFIG_SB1XXX_CORELIS
67  GCCFLAGS       += -mno-sched-prolog -fno-omit-frame-pointer
68  endif
69 @@ -499,6 +499,37 @@
70  endif
71  
72  #
73 +# Broadcom BCM947XX variants
74 +#
75 +ifdef CONFIG_BCM947XX
76 +LIBS           += arch/mips/brcm-boards/generic/brcm.o arch/mips/brcm-boards/bcm947xx/bcm947xx.o
77 +SUBDIRS                += arch/mips/brcm-boards/generic arch/mips/brcm-boards/bcm947xx
78 +LOADADDR       := 0x80001000
79 +zImage: vmlinux
80 +       $(MAKE) -C arch/$(ARCH)/brcm-boards/bcm947xx/compressed
81 +export LOADADDR
82 +endif
83 +
84 +#
85 +# Broadcom BCM933XX variants
86 +#
87 +ifdef CONFIG_BCM933XX
88 +LIBS          += arch/mips/brcm-boards/bcm933xx/bcm933xx.o
89 +SUBDIRS       += arch/mips/brcm-boards/bcm933xx
90 +LOADADDR      := 0x80010000
91 +
92 +vmlinux.srec: vmlinux
93 +       $(OBJCOPY) -O srec $< $@
94 +linux.srec: vmlinux.srec
95 +       $(OBJCOPY) --adjust-vma=0x80000000 -O srec $< $@
96 +vmlinux.out: vmlinux.bin
97 +       $(TOPDIR)/pstore.sh
98 +vmlinux.bin: vmlinux
99 +       $(OBJCOPY) -O binary $< $@
100 +export LOADADDR
101 +endif
102 +
103 +#
104  # SNI RM200 PCI
105  #
106  ifdef CONFIG_SNI_RM200_PCI
107 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
108 +++ linux-2.4.20/arch/mips/brcm-boards/bcm947xx/Makefile        2005-01-07 05:39:02.000000000 -0500
109 @@ -0,0 +1,23 @@
110 +#
111 +# Makefile for Broadcom BCM947XX boards
112 +#
113 +# Copyright 2004, Broadcom Corporation
114 +# All Rights Reserved.
115 +# 
116 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
117 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
118 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
119 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
120 +#
121 +# $Id: Makefile,v 1.1.1.7 2004/04/12 04:31:00 honor Exp $
122 +#
123 +
124 +O_TARGET       := bcm947xx.o
125 +
126 +export-objs    := nvram_linux.o setup.o
127 +obj-y          := prom.o setup.o time.o sbmips.o sbpci.o pcibios.o perfcntr.o gpio.o
128 +obj-y          += sflash.o nvram.o nvram_linux.o
129 +
130 +vpath %.c $(SRCBASE)/shared $(SRCBASE)/shared/nvram
131 +
132 +include $(TOPDIR)/Rules.make
133 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
134 +++ linux-2.4.20/arch/mips/brcm-boards/bcm947xx/compressed/Makefile     2004-05-30 02:30:00.000000000 -0400
135 @@ -0,0 +1,100 @@
136 +#
137 +# Makefile for Broadcom BCM947XX boards
138 +#
139 +# Copyright 2001-2003, Broadcom Corporation
140 +# All Rights Reserved.
141 +# 
142 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
143 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
144 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
145 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
146 +#
147 +# $Id: Makefile,v 1.1.1.6 2003/11/08 08:11:32 honor Exp $
148 +#
149 +# Copyright 2004  Manuel Novoa III <mjn3@codepoet.org>
150 +#   Modified to support bzip'd kernels.
151 +#   Of course, it would be better to integrate bunzip capability into CFE.
152 +#
153 +
154 +# Link at 3 MB offset in RAM
155 +#TEXT_START    ?= 0x80300000
156 +TEXT_START     ?= 0x80001000
157 +BZ_MEM_TOP     := 0x81000000
158 +BZ_TEXT_START  := BZ_MEM_TOP-0x4000
159 +BZ_STACK_TOP   := BZ_TEXT_START-4
160 +
161 +OBJCOPY                := $(CROSS_COMPILE)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S
162 +
163 +SRCBASE                := $(TOPDIR)/../..
164 +VPATH          := $(SRCBASE)/shared
165 +ASFLAGS                += -D__ASSEMBLY__ -I$(SRCBASE)/include -DLOADADDR=$(LOADADDR)
166 +ASFLAGS                += -DBZ_MEM_TOP=$(BZ_MEM_TOP)
167 +ASFLAGS                += -DBZ_TEXT_START=$(BZ_TEXT_START)
168 +ASFLAGS                += -DBZ_STACK_TOP=$(BZ_STACK_TOP)
169 +CFLAGS         += -I$(SRCBASE)/include -DLOADADDR=$(LOADADDR)
170 +CFLAGS         += -DBZ_MEM_TOP=$(BZ_MEM_TOP)
171 +CFLAGS         += -DBZ_TEXT_START=$(BZ_TEXT_START)
172 +CFLAGS         += -DBZ_STACK_TOP=$(BZ_STACK_TOP)
173 +ifdef CONFIG_MCOUNT
174 +CFLAGS         := $(subst -pg,,$(CFLAGS))
175 +endif
176 +CFLAGS         += -ffunction-sections $(call check_gcc, -fvtable-gc, )
177 +SEDFLAGS       := s/BZ_TEXT_START/$(BZ_TEXT_START)/;s/BZ_MEM_TOP/$(BZ_MEM_TOP)/;s/TEXT_START/$(TEXT_START)/
178 +
179 +SYSTEM         ?= $(TOPDIR)/vmlinux
180 +OBJECTS                := head.o data.o
181 +
182 +all: bzImage vmlinuz
183 +
184 +# Don't build dependencies, this may die if $(CC) isn't gcc
185 +dep:
186 +
187 +# Create a gzipped version named vmlinuz for compatibility
188 +vmlinuz: piggy
189 +       gzip -c9 $< > $@
190 +
191 +# Our bzImage is a gzip'd binary that decompresses and runs
192 +#   the appended bzip'd kernel.
193 +bzImage: bzLoaderImage.gz piggz
194 +       cat bzLoaderImage.gz piggz > $@
195 +
196 +bzLoaderImage.gz: bzLoaderImage
197 +       gzip -nc9 $< > $@
198 +
199 +bzLoaderImage: bzLoader
200 +       $(OBJCOPY) $< $@
201 +
202 +bzLoader: vmlinux.lds $(OBJECTS)
203 +       $(LD) -static --gc-sections -no-warn-mismatch -T vmlinux.lds -o $@ $(OBJECTS)
204 +
205 +vmlinux.lds: vmlinux.lds.in Makefile
206 +       @sed "$(SEDFLAGS)" < $< > $@
207 +
208 +piggz: piggy
209 +       bzip2 -c9 $< > $@
210 +
211 +piggy: $(SYSTEM)
212 +       $(OBJCOPY) $< $@
213 +
214 +data.o: data.lds data.image
215 +       $(LD) -no-warn-mismatch -T data.lds -r -o $@ -b binary data.image -b elf32-tradlittlemips
216 +
217 +data.lds:
218 +       @echo "SECTIONS { .data : { code_start = .; *(.data) code_stop = .; }}" > $@
219 +
220 +data.image: decompress_bunzip2.image
221 +       $(OBJCOPY) $< $@
222 +
223 +decompress_bunzip2.image: decompress_bunzip2.lds decompress_bunzip2.o
224 +       $(LD) -static --gc-sections -no-warn-mismatch -T decompress_bunzip2.lds -o $@ decompress_bunzip2.o
225 +
226 +decompress_bunzip2.lds: decompress_bunzip2.lds.in Makefile
227 +       @sed "$(SEDFLAGS)" < $< > $@
228 +
229 +mrproper: clean
230 +
231 +clean:
232 +       rm -f vmlinux vmlinuz piggz piggy *.lds *.o \
233 +               bzLoader bzLoaderImage bzLoaderImage.gz bzImage \
234 +               data.lds data.image \
235 +               decompress_bunzip2.lds decompress_bunzip2.image
236 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
237 +++ linux-2.4.20/arch/mips/brcm-boards/bcm947xx/compressed/head.S       2004-05-30 02:26:40.000000000 -0400
238 @@ -0,0 +1,26 @@
239 +/* Copyright 2004   Manuel Novoa III (mjn3@codepoet.org) */
240 +/* Licensed under the linux kernel's version of the GPL. */
241 +
242 +#include <asm/asm.h>
243 +#include <asm/regdef.h>
244 +
245 +       .text
246 +       LEAF(startup)
247 +       .set noreorder
248 +
249 +       li      t1, BZ_TEXT_START
250 +       add     a0, t1, 0
251 +       la      a1, code_start
252 +       la      a2, code_stop
253 +$L1:
254 +       lw      t0, 0(a1)
255 +       sw      t0, 0(a0)
256 +       add     a1, 4
257 +       add     a0, 4
258 +       blt     a1, a2, $L1
259 +
260 +       add     sp, t1, -4
261 +       jal     t1
262 +       
263 +       .set reorder
264 +       END(startup)
265 --- linux-2.4.20/arch/mips/brcm-boards/bcm947xx/compressed/misc.c~2.4.20_broadcom_3_37_2_1109_US.patch
266 +++ linux-2.4.20/arch/mips/brcm-boards/bcm947xx/compressed/misc.c
267 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
268 +++ linux-2.4.20/arch/mips/brcm-boards/bcm947xx/compressed/vmlinux.lds.in       2004-05-21 13:13:07.000000000 -0400
269 @@ -0,0 +1,17 @@
270 +OUTPUT_ARCH(mips)
271 +ENTRY(startup)
272 +SECTIONS {
273 +       . = TEXT_START;
274 +       .text : {
275 +               *(.text)
276 +               *(.rodata)
277 +       }
278 +
279 +       .data : {
280 +               *(.data)
281 +       }
282 +
283 +       .bss : {
284 +               *(.bss)
285 +       }
286 +}
287 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
288 +++ linux-2.4.20/arch/mips/brcm-boards/bcm947xx/gpio.c  2005-01-07 05:39:02.000000000 -0500
289 @@ -0,0 +1,158 @@
290 +/*
291 + * GPIO char driver
292 + *
293 + * Copyright 2004, Broadcom Corporation
294 + * All Rights Reserved.
295 + * 
296 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
297 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
298 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
299 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
300 + *
301 + * $Id: gpio.c,v 1.1.1.7 2004/04/12 04:31:00 honor Exp $
302 + */
303 +
304 +#include <linux/module.h>
305 +#include <linux/init.h>
306 +#include <linux/fs.h>
307 +#include <linux/miscdevice.h>
308 +#include <asm/uaccess.h>
309 +
310 +#include <typedefs.h>
311 +#include <bcmutils.h>
312 +#include <sbutils.h>
313 +#include <bcmdevs.h>
314 +
315 +static void *gpio_sbh;
316 +static int gpio_major;
317 +static devfs_handle_t gpio_dir;
318 +static struct {
319 +       char *name;
320 +       devfs_handle_t handle;
321 +} gpio_file[] = {
322 +       { "in", NULL },
323 +       { "out", NULL },
324 +       { "outen", NULL },
325 +       { "control", NULL }
326 +};
327 +
328 +static int
329 +gpio_open(struct inode *inode, struct file * file)
330 +{
331 +       if (MINOR(inode->i_rdev) > ARRAYSIZE(gpio_file))
332 +               return -ENODEV;
333 +
334 +       MOD_INC_USE_COUNT;
335 +       return 0;
336 +}
337 +
338 +static int
339 +gpio_release(struct inode *inode, struct file * file)
340 +{
341 +       MOD_DEC_USE_COUNT;
342 +       return 0;
343 +}
344 +
345 +static ssize_t
346 +gpio_read(struct file *file, char *buf, size_t count, loff_t *ppos)
347 +{
348 +       u32 val;
349 +
350 +       switch (MINOR(file->f_dentry->d_inode->i_rdev)) {
351 +       case 0:
352 +               val = sb_gpioin(gpio_sbh);
353 +               break;
354 +       case 1:
355 +               val = sb_gpioout(gpio_sbh, 0, 0);
356 +               break;
357 +       case 2:
358 +               val = sb_gpioouten(gpio_sbh, 0, 0);
359 +               break;
360 +       case 3:
361 +               val = sb_gpiocontrol(gpio_sbh, 0, 0);
362 +               break;
363 +       default:
364 +               return -ENODEV;
365 +       }
366 +
367 +       if (put_user(val, (u32 *) buf))
368 +               return -EFAULT;
369 +
370 +       return sizeof(val);
371 +}
372 +
373 +static ssize_t
374 +gpio_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
375 +{
376 +       u32 val;
377 +
378 +       if (get_user(val, (u32 *) buf))
379 +               return -EFAULT;
380 +
381 +       switch (MINOR(file->f_dentry->d_inode->i_rdev)) {
382 +       case 0:
383 +               return -EACCES;
384 +       case 1:
385 +               sb_gpioout(gpio_sbh, ~0, val);
386 +               break;
387 +       case 2:
388 +               sb_gpioouten(gpio_sbh, ~0, val);
389 +               break;
390 +       case 3:
391 +               sb_gpiocontrol(gpio_sbh, ~0, val);
392 +               break;
393 +       default:
394 +               return -ENODEV;
395 +       }
396 +
397 +       return sizeof(val);
398 +}
399 +
400 +static struct file_operations gpio_fops = {
401 +       owner:          THIS_MODULE,
402 +       open:           gpio_open,
403 +       release:        gpio_release,
404 +       read:           gpio_read,
405 +       write:          gpio_write,
406 +};
407 +
408 +static int __init
409 +gpio_init(void)
410 +{
411 +       int i;
412 +
413 +       if (!(gpio_sbh = sb_kattach()))
414 +               return -ENODEV;
415 +
416 +       sb_gpiosetcore(gpio_sbh);
417 +
418 +       if ((gpio_major = devfs_register_chrdev(0, "gpio", &gpio_fops)) < 0)
419 +               return gpio_major;
420 +
421 +       gpio_dir = devfs_mk_dir(NULL, "gpio", NULL);
422 +
423 +       for (i = 0; i < ARRAYSIZE(gpio_file); i++) {
424 +               gpio_file[i].handle = devfs_register(gpio_dir,
425 +                                                    gpio_file[i].name,
426 +                                                    DEVFS_FL_DEFAULT, gpio_major, i,
427 +                                                    S_IFCHR | S_IRUGO | S_IWUGO,
428 +                                                    &gpio_fops, NULL);
429 +       }
430 +
431 +       return 0;
432 +}
433 +
434 +static void __exit
435 +gpio_exit(void)
436 +{
437 +       int i;
438 +
439 +       for (i = 0; i < ARRAYSIZE(gpio_file); i++)
440 +               devfs_unregister(gpio_file[i].handle);
441 +       devfs_unregister(gpio_dir);
442 +       devfs_unregister_chrdev(gpio_major, "gpio");
443 +       sb_detach(gpio_sbh);
444 +}
445 +
446 +module_init(gpio_init);
447 +module_exit(gpio_exit);
448 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
449 +++ linux-2.4.20/arch/mips/brcm-boards/bcm947xx/nvram_linux.c   2005-01-07 05:39:02.000000000 -0500
450 @@ -0,0 +1,638 @@
451 +/*
452 + * NVRAM variable manipulation (Linux kernel half)
453 + *
454 + * Copyright 2004, Broadcom Corporation
455 + * All Rights Reserved.
456 + * 
457 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
458 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
459 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
460 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
461 + *
462 + * $Id: nvram_linux.c,v 1.10 2004/04/12 06:07:56 honor Exp $
463 + */
464 +
465 +#include <linux/config.h>
466 +#include <linux/init.h>
467 +#include <linux/module.h>
468 +#include <linux/kernel.h>
469 +#include <linux/string.h>
470 +#include <linux/interrupt.h>
471 +#include <linux/spinlock.h>
472 +#include <linux/slab.h>
473 +#include <linux/bootmem.h>
474 +#include <linux/wrapper.h>
475 +#include <linux/fs.h>
476 +#include <linux/miscdevice.h>
477 +#include <linux/mtd/mtd.h>
478 +#include <asm/addrspace.h>
479 +#include <asm/io.h>
480 +#include <asm/uaccess.h>
481 +
482 +#include <typedefs.h>
483 +#include <bcmendian.h>
484 +#include <bcmnvram.h>
485 +#include <bcmutils.h>
486 +#include <sbconfig.h>
487 +#include <sbchipc.h>
488 +#include <sbutils.h>
489 +#include <sbmips.h>
490 +#include <sflash.h>
491 +
492 +/* In BSS to minimize text size and page aligned so it can be mmap()-ed */
493 +static char nvram_buf[NVRAM_SPACE] __attribute__((aligned(PAGE_SIZE)));
494 +
495 +#ifdef MODULE
496 +
497 +#define early_nvram_get(name) nvram_get(name)
498 +
499 +#else /* !MODULE */
500 +
501 +/* Global SB handle */
502 +extern void *bcm947xx_sbh;
503 +extern spinlock_t bcm947xx_sbh_lock;
504 +
505 +/* Convenience */
506 +#define sbh bcm947xx_sbh
507 +#define sbh_lock bcm947xx_sbh_lock
508 +#define KB * 1024
509 +#define MB * 1024 * 1024
510 +
511 +/* Probe for NVRAM header */
512 +static void __init
513 +early_nvram_init(void)
514 +{
515 +       struct nvram_header *header;
516 +       chipcregs_t *cc;
517 +       struct sflash *info = NULL;
518 +       int i;
519 +       uint32 base, off, lim;
520 +
521 +       if ((cc = sb_setcore(sbh, SB_CC, 0)) != NULL) {
522 +               base = CC_FLASH_BASE;
523 +               switch (readl(&cc->capabilities) & CAP_FLASH_MASK) {
524 +               case PFLASH:
525 +                       lim = CC_FLASH_MAX;
526 +                       break;
527 +
528 +               case SFLASH_ST:
529 +               case SFLASH_AT:
530 +                       if ((info = sflash_init(cc)) == NULL)
531 +                               return;
532 +                       lim = info->size;
533 +                       break;
534 +
535 +               case FLASH_NONE:
536 +               default:
537 +                       return;
538 +               }
539 +       } else {
540 +               /* extif assumed, Stop at 4 MB */
541 +               base = FLASH_BASE;
542 +               lim = FLASH_MAX;
543 +       }
544 +
545 +       off = FLASH_MIN;
546 +       while (off <= lim) {
547 +               /* Windowed flash access */
548 +               header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
549 +               if (header->magic == NVRAM_MAGIC) {
550 +                       u32 *src = (u32 *) header;
551 +                       u32 *dst = (u32 *) nvram_buf;
552 +                       for (i = 0; i < sizeof(struct nvram_header); i += 4)
553 +                               *dst++ = *src++;
554 +                       for (; i < header->len && i < NVRAM_SPACE; i += 4)
555 +                               *dst++ = ltoh32(*src++);
556 +                       return;
557 +               }
558 +
559 +               /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
560 +               if (off == 1 KB)
561 +                       break;
562 +               else if (off == 4 KB)
563 +                       off = 1 KB;
564 +               else if (off == lim)
565 +                       off = 4 KB;
566 +               else
567 +                       off <<= 1;
568 +       }
569 +}
570 +
571 +/* Early (before mm or mtd) read-only access to NVRAM */
572 +static char * __init
573 +early_nvram_get(const char *name)
574 +{
575 +       char *var, *value, *end, *eq;
576 +
577 +       if (!name)
578 +               return NULL;
579 +
580 +       if (!nvram_buf[0])
581 +               early_nvram_init();
582 +
583 +       /* Look for name=value and return value */
584 +       var = &nvram_buf[sizeof(struct nvram_header)];
585 +       end = nvram_buf + sizeof(nvram_buf) - 2;
586 +       end[0] = end[1] = '\0';
587 +       for (; *var; var = value + strlen(value) + 1) {
588 +               if (!(eq = strchr(var, '=')))
589 +                       break;
590 +               value = eq + 1;
591 +               if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0)
592 +                       return value;
593 +       }
594 +
595 +       return NULL;
596 +}
597 +
598 +#endif /* !MODULE */
599 +
600 +extern char * _nvram_get(const char *name);
601 +extern int _nvram_set(const char *name, const char *value);
602 +extern int _nvram_unset(const char *name);
603 +extern int _nvram_getall(char *buf, int count);
604 +extern int _nvram_commit(struct nvram_header *header);
605 +extern int _nvram_init(void);
606 +extern void _nvram_exit(void);
607 +
608 +/* Globals */
609 +static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED;
610 +static struct semaphore nvram_sem;
611 +static unsigned long nvram_offset = 0;
612 +static int nvram_major = -1;
613 +static devfs_handle_t nvram_handle = NULL;
614 +static struct mtd_info *nvram_mtd = NULL;
615 +
616 +int
617 +_nvram_read(char *buf)
618 +{
619 +       struct nvram_header *header = (struct nvram_header *) buf;
620 +       size_t len;
621 +
622 +       if (!nvram_mtd ||
623 +           MTD_READ(nvram_mtd, nvram_mtd->size - NVRAM_SPACE, NVRAM_SPACE, &len, buf) ||
624 +           len != NVRAM_SPACE ||
625 +           header->magic != NVRAM_MAGIC) {
626 +               /* Maybe we can recover some data from early initialization */
627 +               memcpy(buf, nvram_buf, NVRAM_SPACE);
628 +       }
629 +
630 +       return 0;
631 +}
632 +
633 +struct nvram_tuple *
634 +_nvram_realloc(struct nvram_tuple *t, const char *name, const char *value)
635 +{
636 +       if ((nvram_offset + strlen(value) + 1) > NVRAM_SPACE)
637 +               return NULL;
638 +
639 +       if (!t) {
640 +               if (!(t = kmalloc(sizeof(struct nvram_tuple) + strlen(name) + 1, GFP_ATOMIC)))
641 +                       return NULL;
642 +
643 +               /* Copy name */
644 +               t->name = (char *) &t[1];
645 +               strcpy(t->name, name);
646 +
647 +               t->value = NULL;
648 +       }
649 +
650 +       /* Copy value */
651 +       if (!t->value || strcmp(t->value, value)) {
652 +               t->value = &nvram_buf[nvram_offset];
653 +               strcpy(t->value, value);
654 +               nvram_offset += strlen(value) + 1;
655 +       }
656 +
657 +       return t;
658 +}
659 +
660 +void
661 +_nvram_free(struct nvram_tuple *t)
662 +{
663 +       if (!t)
664 +               nvram_offset = 0;
665 +       else
666 +               kfree(t);
667 +}
668 +
669 +int
670 +nvram_set(const char *name, const char *value)
671 +{
672 +       unsigned long flags;
673 +       int ret;
674 +       struct nvram_header *header;
675 +
676 +       spin_lock_irqsave(&nvram_lock, flags);
677 +       if ((ret = _nvram_set(name, value))) {
678 +               /* Consolidate space and try again */
679 +               if ((header = kmalloc(NVRAM_SPACE, GFP_ATOMIC))) {
680 +                       if (_nvram_commit(header) == 0)
681 +                               ret = _nvram_set(name, value);
682 +                       kfree(header);
683 +               }
684 +       }
685 +       spin_unlock_irqrestore(&nvram_lock, flags);
686 +
687 +       return ret;
688 +}
689 +
690 +char *
691 +real_nvram_get(const char *name)
692 +{
693 +       unsigned long flags;
694 +       char *value;
695 +
696 +       spin_lock_irqsave(&nvram_lock, flags);
697 +       value = _nvram_get(name);
698 +       spin_unlock_irqrestore(&nvram_lock, flags);
699 +
700 +       return value;
701 +}
702 +
703 +char *
704 +nvram_get(const char *name)
705 +{
706 +       if (nvram_major >= 0)
707 +               return real_nvram_get(name);
708 +       else
709 +               return early_nvram_get(name);
710 +}
711 +
712 +int
713 +nvram_unset(const char *name)
714 +{
715 +       unsigned long flags;
716 +       int ret;
717 +
718 +       spin_lock_irqsave(&nvram_lock, flags);
719 +       ret = _nvram_unset(name);
720 +       spin_unlock_irqrestore(&nvram_lock, flags);
721 +
722 +       return ret;
723 +}
724 +
725 +static void
726 +erase_callback(struct erase_info *done)
727 +{
728 +       wait_queue_head_t *wait_q = (wait_queue_head_t *) done->priv;
729 +       wake_up(wait_q);
730 +}
731 +
732 +int
733 +nvram_commit(void)
734 +{
735 +       char *buf;
736 +       size_t erasesize, len;
737 +       unsigned int i;
738 +       int ret;
739 +       struct nvram_header *header;
740 +       unsigned long flags;
741 +       u_int32_t offset;
742 +       DECLARE_WAITQUEUE(wait, current);
743 +       wait_queue_head_t wait_q;
744 +       struct erase_info erase;
745 +
746 +       printk("nvram_commit(): init\n");
747 +
748 +       if (!nvram_mtd) {
749 +               printk("nvram_commit: NVRAM not found\n");
750 +               return -ENODEV;
751 +       }
752 +
753 +       if (in_interrupt()) {
754 +               printk("nvram_commit: not committing in interrupt\n");
755 +               return -EINVAL;
756 +       }
757 +
758 +       /* Backup sector blocks to be erased */
759 +       erasesize = ROUNDUP(NVRAM_SPACE, nvram_mtd->erasesize);
760 +       if (!(buf = kmalloc(erasesize, GFP_KERNEL))) {
761 +               printk("nvram_commit: out of memory\n");
762 +               return -ENOMEM;
763 +       }
764 +
765 +       down(&nvram_sem);
766 +#if 0
767 +       offset = nvram_mtd->size - erasesize;
768 +       i = erasesize - NVRAM_SPACE;
769 +       ret = MTD_READ(nvram_mtd, offset, i, &len, buf);
770 +       if (ret || len != i) {
771 +               printk("nvram_commit: read error\n");
772 +               ret = -EIO;
773 +               goto done;
774 +#endif
775 +       if ((i = erasesize - NVRAM_SPACE) > 0) {
776 +               offset = nvram_mtd->size - erasesize;
777 +               len = 0;
778 +               ret = MTD_READ(nvram_mtd, offset, i, &len, buf);
779 +               if (ret || len != i) {
780 +                       printk("nvram_commit: read error ret = %d, len = %d/%d\n", ret, len, i);
781 +                       ret = -EIO;
782 +                       goto done;
783 +               }
784 +               header = (struct nvram_header *)(buf + i);
785 +       } else {
786 +               offset = nvram_mtd->size - NVRAM_SPACE;
787 +               header = (struct nvram_header *)buf;
788 +       }
789 +
790 +       /* Regenerate NVRAM */
791 +       spin_lock_irqsave(&nvram_lock, flags);
792 +       ret = _nvram_commit(header);
793 +       spin_unlock_irqrestore(&nvram_lock, flags);
794 +       if (ret)
795 +               goto done;
796 +
797 +       /* Erase sector blocks */
798 +       init_waitqueue_head(&wait_q);
799 +       for (; offset < nvram_mtd->size - NVRAM_SPACE + header->len; offset += nvram_mtd->erasesize) {
800 +               erase.mtd = nvram_mtd;
801 +               erase.addr = offset;
802 +               erase.len = nvram_mtd->erasesize;
803 +               erase.callback = erase_callback;
804 +               erase.priv = (u_long) &wait_q;
805 +
806 +               set_current_state(TASK_INTERRUPTIBLE);
807 +               add_wait_queue(&wait_q, &wait);
808 +
809 +               /* Unlock sector blocks */
810 +               if (nvram_mtd->unlock)
811 +                       nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize);
812 +
813 +               if ((ret = MTD_ERASE(nvram_mtd, &erase))) {
814 +                       set_current_state(TASK_RUNNING);
815 +                       remove_wait_queue(&wait_q, &wait);
816 +                       printk("nvram_commit: erase error\n");
817 +                       goto done;
818 +               }
819 +
820 +               /* Wait for erase to finish */
821 +               schedule();
822 +               remove_wait_queue(&wait_q, &wait);
823 +       }
824 +
825 +       /* Write partition up to end of data area */
826 +       offset = nvram_mtd->size - erasesize;
827 +       i = erasesize - NVRAM_SPACE + header->len;
828 +       ret = MTD_WRITE(nvram_mtd, offset, i, &len, buf);
829 +       if (ret || len != i) {
830 +               printk("nvram_commit: write error\n");
831 +               ret = -EIO;
832 +               goto done;
833 +       }
834 +       /*
835 +        * Reading a few bytes back here will put the device
836 +        * back to the correct mode on certain flashes */
837 +
838 +       offset = nvram_mtd->size - erasesize;
839 +       ret = MTD_READ(nvram_mtd, offset, 4, &len, buf);
840 +
841 + done:
842 +       up(&nvram_sem);
843 +       kfree(buf);
844 +       printk("nvram_commit(): end\n");
845 +       return ret;
846 +}
847 +
848 +int
849 +nvram_getall(char *buf, int count)
850 +{
851 +       unsigned long flags;
852 +       int ret;
853 +
854 +       spin_lock_irqsave(&nvram_lock, flags);
855 +       ret = _nvram_getall(buf, count);
856 +       spin_unlock_irqrestore(&nvram_lock, flags);
857 +
858 +       return ret;
859 +}
860 +
861 +EXPORT_SYMBOL(nvram_get);
862 +EXPORT_SYMBOL(nvram_getall);
863 +EXPORT_SYMBOL(nvram_set);
864 +EXPORT_SYMBOL(nvram_unset);
865 +EXPORT_SYMBOL(nvram_commit);
866 +
867 +/* User mode interface below */
868 +
869 +static ssize_t
870 +dev_nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos)
871 +{
872 +       char tmp[100], *name = tmp, *value;
873 +       ssize_t ret;
874 +       unsigned long off;
875 +
876 +       if (count > sizeof(tmp)) {
877 +               if (!(name = kmalloc(count, GFP_KERNEL)))
878 +                       return -ENOMEM;
879 +       }
880 +
881 +       if (copy_from_user(name, buf, count)) {
882 +               ret = -EFAULT;
883 +               goto done;
884 +       }
885 +
886 +       if (*name == '\0') {
887 +               /* Get all variables */
888 +               ret = nvram_getall(name, count);
889 +               if (ret == 0) {
890 +                       if (copy_to_user(buf, name, count)) {
891 +                               ret = -EFAULT;
892 +                               goto done;
893 +                       }
894 +                       ret = count;
895 +               }
896 +       } else {
897 +               if (!(value = nvram_get(name))) {
898 +                       ret = 0;
899 +                       goto done;
900 +               }
901 +
902 +               /* Provide the offset into mmap() space */
903 +               off = (unsigned long) value - (unsigned long) nvram_buf;
904 +
905 +               if (put_user(off, (unsigned long *) buf)) {
906 +                       ret = -EFAULT;
907 +                       goto done;
908 +               }
909 +
910 +               ret = sizeof(unsigned long);
911 +       }
912 +
913 +       flush_cache_all();      
914
915 +done:
916 +       if (name != tmp)
917 +               kfree(name);
918 +
919 +       return ret;
920 +}
921 +
922 +static ssize_t
923 +dev_nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
924 +{
925 +       char tmp[100], *name = tmp, *value;
926 +       ssize_t ret;
927 +
928 +       if (count > sizeof(tmp)) {
929 +               if (!(name = kmalloc(count, GFP_KERNEL)))
930 +                       return -ENOMEM;
931 +       }
932 +
933 +       if (copy_from_user(name, buf, count)) {
934 +               ret = -EFAULT;
935 +               goto done;
936 +       }
937 +
938 +       value = name;
939 +       name = strsep(&value, "=");
940 +       if (value)
941 +               ret = nvram_set(name, value) ? : count;
942 +       else
943 +               ret = nvram_unset(name) ? : count;
944 +
945 + done:
946 +       if (name != tmp)
947 +               kfree(name);
948 +
949 +       return ret;
950 +}      
951 +
952 +static int
953 +dev_nvram_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
954 +{
955 +       if (cmd != NVRAM_MAGIC)
956 +               return -EINVAL;
957 +       return nvram_commit();
958 +}
959 +
960 +static int
961 +dev_nvram_mmap(struct file *file, struct vm_area_struct *vma)
962 +{
963 +       unsigned long offset = virt_to_phys(nvram_buf);
964 +
965 +       if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
966 +                            vma->vm_page_prot))
967 +               return -EAGAIN;
968 +
969 +       return 0;
970 +}
971 +
972 +static int
973 +dev_nvram_open(struct inode *inode, struct file * file)
974 +{
975 +       MOD_INC_USE_COUNT;
976 +       return 0;
977 +}
978 +
979 +static int
980 +dev_nvram_release(struct inode *inode, struct file * file)
981 +{
982 +       MOD_DEC_USE_COUNT;
983 +       return 0;
984 +}
985 +
986 +static struct file_operations dev_nvram_fops = {
987 +       owner:          THIS_MODULE,
988 +       open:           dev_nvram_open,
989 +       release:        dev_nvram_release,
990 +       read:           dev_nvram_read,
991 +       write:          dev_nvram_write,
992 +       ioctl:          dev_nvram_ioctl,
993 +       mmap:           dev_nvram_mmap,
994 +};
995 +
996 +static void
997 +dev_nvram_exit(void)
998 +{
999 +       int order = 0;
1000 +       struct page *page, *end;
1001 +
1002 +       if (nvram_handle)
1003 +               devfs_unregister(nvram_handle);
1004 +
1005 +       if (nvram_major >= 0)
1006 +               devfs_unregister_chrdev(nvram_major, "nvram");
1007 +
1008 +       if (nvram_mtd)
1009 +               put_mtd_device(nvram_mtd);
1010 +
1011 +       while ((PAGE_SIZE << order) < NVRAM_SPACE)
1012 +               order++;
1013 +       end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1);
1014 +       for (page = virt_to_page(nvram_buf); page <= end; page++)
1015 +               mem_map_unreserve(page);
1016 +
1017 +       _nvram_exit();
1018 +}
1019 +
1020 +static int __init
1021 +dev_nvram_init(void)
1022 +{
1023 +       int order = 0, ret = 0;
1024 +       struct page *page, *end;
1025 +       unsigned int i;
1026 +
1027 +       /* Allocate and reserve memory to mmap() */
1028 +       while ((PAGE_SIZE << order) < NVRAM_SPACE)
1029 +               order++;
1030 +       end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1);
1031 +       for (page = virt_to_page(nvram_buf); page <= end; page++)
1032 +               mem_map_reserve(page);
1033 +
1034 +#ifdef CONFIG_MTD
1035 +       /* Find associated MTD device */
1036 +       for (i = 0; i < MAX_MTD_DEVICES; i++) {
1037 +               nvram_mtd = get_mtd_device(NULL, i);
1038 +               if (nvram_mtd) {
1039 +                       if (!strcmp(nvram_mtd->name, "nvram") &&
1040 +                           nvram_mtd->size >= NVRAM_SPACE)
1041 +                               break;
1042 +                       put_mtd_device(nvram_mtd);
1043 +               }
1044 +       }
1045 +       if (i >= MAX_MTD_DEVICES)
1046 +               nvram_mtd = NULL;
1047 +#endif
1048 +
1049 +       /* Initialize hash table lock */
1050 +       spin_lock_init(&nvram_lock);
1051 +
1052 +       /* Initialize commit semaphore */
1053 +       init_MUTEX(&nvram_sem);
1054 +
1055 +       /* Register char device */
1056 +       if ((nvram_major = devfs_register_chrdev(0, "nvram", &dev_nvram_fops)) < 0) {
1057 +               ret = nvram_major;
1058 +               goto err;
1059 +       }
1060 +
1061 +       /* Initialize hash table */
1062 +       _nvram_init();
1063 +
1064 +       /* Create /dev/nvram handle */
1065 +       nvram_handle = devfs_register(NULL, "nvram", DEVFS_FL_NONE, nvram_major, 0,
1066 +                                     S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, &dev_nvram_fops, NULL);
1067 +
1068 +       /* Set the SDRAM NCDL value into NVRAM if not already done */
1069 +       if (getintvar(NULL, "sdram_ncdl") == 0) {
1070 +               unsigned int ncdl;
1071 +               char buf[] = "0x00000000";
1072 +
1073 +               if ((ncdl = sb_memc_get_ncdl(sbh))) {
1074 +                       sprintf(buf, "0x%08x", ncdl);
1075 +                       nvram_set("sdram_ncdl", buf);
1076 +                       nvram_commit();
1077 +               }
1078 +       }
1079 +
1080 +       return 0;
1081 +
1082 + err:
1083 +       dev_nvram_exit();
1084 +       return ret;
1085 +}
1086 +
1087 +module_init(dev_nvram_init);
1088 +module_exit(dev_nvram_exit);
1089 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
1090 +++ linux-2.4.20/arch/mips/brcm-boards/bcm947xx/pcibios.c       2005-01-07 05:39:02.000000000 -0500
1091 @@ -0,0 +1,332 @@
1092 +/*
1093 + * Low-Level PCI and SB support for BCM47xx (Linux support code)
1094 + *
1095 + * Copyright 2004, Broadcom Corporation
1096 + * All Rights Reserved.
1097 + * 
1098 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1099 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1100 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1101 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1102 + *
1103 + * $Id: pcibios.c,v 1.1.1.6 2004/04/12 04:31:00 honor Exp $ 
1104 + */
1105 +
1106 +#include <linux/config.h>
1107 +#include <linux/types.h>
1108 +#include <linux/kernel.h>
1109 +#include <linux/sched.h>
1110 +#include <linux/pci.h>
1111 +#include <linux/init.h>
1112 +#include <linux/delay.h>
1113 +#include <asm/io.h>
1114 +#include <asm/irq.h>
1115 +#include <asm/paccess.h>
1116 +
1117 +#include <typedefs.h>
1118 +#include <bcmutils.h>
1119 +#include <sbconfig.h>
1120 +#include <sbpci.h>
1121 +#include <pcicfg.h>
1122 +#include <sbutils.h>
1123 +#include <bcmdevs.h>
1124 +#include <bcmnvram.h>
1125 +
1126 +/* Global SB handle */
1127 +extern void *bcm947xx_sbh;
1128 +extern spinlock_t bcm947xx_sbh_lock;
1129 +
1130 +/* Convenience */
1131 +#define sbh bcm947xx_sbh
1132 +#define sbh_lock bcm947xx_sbh_lock
1133 +
1134 +static int
1135 +sbpci_read_config_byte(struct pci_dev *dev, int where, u8 *value)
1136 +{
1137 +       unsigned long flags;
1138 +       int ret;
1139 +
1140 +       spin_lock_irqsave(&sbh_lock, flags);
1141 +       ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value));
1142 +       spin_unlock_irqrestore(&sbh_lock, flags);
1143 +       return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1144 +}
1145 +
1146 +static int
1147 +sbpci_read_config_word(struct pci_dev *dev, int where, u16 *value)
1148 +{
1149 +       unsigned long flags;
1150 +       int ret;
1151 +
1152 +       spin_lock_irqsave(&sbh_lock, flags);
1153 +       ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value));
1154 +       spin_unlock_irqrestore(&sbh_lock, flags);
1155 +       return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1156 +}
1157 +
1158 +static int
1159 +sbpci_read_config_dword(struct pci_dev *dev, int where, u32 *value)
1160 +{
1161 +       unsigned long flags;
1162 +       int ret;
1163 +
1164 +       spin_lock_irqsave(&sbh_lock, flags);
1165 +       ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value));
1166 +       spin_unlock_irqrestore(&sbh_lock, flags);
1167 +       return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1168 +}
1169 +
1170 +static int
1171 +sbpci_write_config_byte(struct pci_dev *dev, int where, u8 value)
1172 +{
1173 +       unsigned long flags;
1174 +       int ret;
1175 +
1176 +       spin_lock_irqsave(&sbh_lock, flags);
1177 +       ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value));
1178 +       spin_unlock_irqrestore(&sbh_lock, flags);
1179 +       return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1180 +}
1181 +
1182 +static int
1183 +sbpci_write_config_word(struct pci_dev *dev, int where, u16 value)
1184 +{
1185 +       unsigned long flags;
1186 +       int ret;
1187 +
1188 +       spin_lock_irqsave(&sbh_lock, flags);
1189 +       ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value));
1190 +       spin_unlock_irqrestore(&sbh_lock, flags);
1191 +       return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1192 +}
1193 +
1194 +static int
1195 +sbpci_write_config_dword(struct pci_dev *dev, int where, u32 value)
1196 +{
1197 +       unsigned long flags;
1198 +       int ret;
1199 +
1200 +       spin_lock_irqsave(&sbh_lock, flags);
1201 +       ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value));
1202 +       spin_unlock_irqrestore(&sbh_lock, flags);
1203 +       return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1204 +}
1205 +
1206 +static struct pci_ops pcibios_ops = {
1207 +       sbpci_read_config_byte,
1208 +       sbpci_read_config_word,
1209 +       sbpci_read_config_dword,
1210 +       sbpci_write_config_byte,
1211 +       sbpci_write_config_word,
1212 +       sbpci_write_config_dword
1213 +};
1214 +
1215 +
1216 +void __init
1217 +pcibios_init(void)
1218 +{
1219 +       ulong flags;
1220 +
1221 +       if (!(sbh = sb_kattach()))
1222 +               panic("sb_kattach failed");
1223 +       spin_lock_init(&sbh_lock);
1224 +
1225 +       spin_lock_irqsave(&sbh_lock, flags);
1226 +       sbpci_init(sbh);
1227 +       spin_unlock_irqrestore(&sbh_lock, flags);
1228 +
1229 +       set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000));
1230 +
1231 +       /* Scan the SB bus */
1232 +       pci_scan_bus(0, &pcibios_ops, NULL);
1233 +
1234 +}
1235 +
1236 +char * __init
1237 +pcibios_setup(char *str)
1238 +{
1239 +       if (!strncmp(str, "ban=", 4)) {
1240 +               sbpci_ban(simple_strtoul(str + 4, NULL, 0));
1241 +               return NULL;
1242 +       }
1243 +
1244 +       return (str);
1245 +}
1246 +
1247 +static u32 pci_iobase = 0x100;
1248 +static u32 pci_membase = SB_PCI_DMA;
1249 +
1250 +void __init
1251 +pcibios_fixup_bus(struct pci_bus *b)
1252 +{
1253 +       struct list_head *ln;
1254 +       struct pci_dev *d;
1255 +       struct resource *res;
1256 +       int pos, size;
1257 +       u32 *base;
1258 +       u8 irq;
1259 +
1260 +               printk("PCI: Fixing up bus %d\n", b->number);
1261 +
1262 +       /* Fix up SB */
1263 +       if (b->number == 0) {
1264 +               for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
1265 +                       d = pci_dev_b(ln);
1266 +                       /* Fix up interrupt lines */
1267 +                       pci_read_config_byte(d, PCI_INTERRUPT_LINE, &irq);
1268 +                       d->irq = irq + 2;
1269 +                       pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
1270 +               }
1271 +       }
1272 +
1273 +       /* Fix up external PCI */
1274 +       else {
1275 +               for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
1276 +                       d = pci_dev_b(ln);
1277 +                       /* Fix up resource bases */
1278 +                       for (pos = 0; pos < 6; pos++) {
1279 +                               res = &d->resource[pos];
1280 +                               base = (res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase;
1281 +                               if (res->end) {
1282 +                                       size = res->end - res->start + 1;
1283 +                                       if (*base & (size - 1))
1284 +                                               *base = (*base + size) & ~(size - 1);
1285 +                                       res->start = *base;
1286 +                                       res->end = res->start + size - 1;
1287 +                                       *base += size;
1288 +                                       pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
1289 +                               }
1290 +                               /* Fix up PCI bridge BAR0 only */
1291 +                               if (b->number == 1 && PCI_SLOT(d->devfn) == 0)
1292 +                                       break;
1293 +                       }
1294 +                       /* Fix up interrupt lines */
1295 +                       if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))
1296 +                               d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq;
1297 +                       pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
1298 +               }
1299 +       }
1300 +}
1301 +
1302 +unsigned int
1303 +pcibios_assign_all_busses(void)
1304 +{
1305 +       return 1;
1306 +}
1307 +
1308 +void
1309 +pcibios_align_resource(void *data, struct resource *res,
1310 +                      unsigned long size, unsigned long align)
1311 +{
1312 +}
1313 +
1314 +int
1315 +pcibios_enable_resources(struct pci_dev *dev)
1316 +{
1317 +       u16 cmd, old_cmd;
1318 +       int idx;
1319 +       struct resource *r;
1320 +
1321 +       /* External PCI only */
1322 +       if (dev->bus->number == 0)
1323 +               return 0;
1324 +
1325 +       pci_read_config_word(dev, PCI_COMMAND, &cmd);
1326 +       old_cmd = cmd;
1327 +       for(idx=0; idx<6; idx++) {
1328 +               r = &dev->resource[idx];
1329 +               if (r->flags & IORESOURCE_IO)
1330 +                       cmd |= PCI_COMMAND_IO;
1331 +               if (r->flags & IORESOURCE_MEM)
1332 +                       cmd |= PCI_COMMAND_MEMORY;
1333 +       }
1334 +       if (dev->resource[PCI_ROM_RESOURCE].start)
1335 +               cmd |= PCI_COMMAND_MEMORY;
1336 +       if (cmd != old_cmd) {
1337 +               printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
1338 +               pci_write_config_word(dev, PCI_COMMAND, cmd);
1339 +       }
1340 +       return 0;
1341 +}
1342 +
1343 +int
1344 +pcibios_enable_device(struct pci_dev *dev, int mask)
1345 +{
1346 +       ulong flags;
1347 +       uint coreidx;
1348 +
1349 +       /* External PCI device enable */
1350 +       if (dev->bus->number != 0)
1351 +               return pcibios_enable_resources(dev);
1352 +
1353 +       /* These cores come out of reset enabled */
1354 +       if (dev->device == SB_MIPS ||
1355 +           dev->device == SB_MIPS33 ||
1356 +           dev->device == SB_EXTIF ||
1357 +           dev->device == SB_CC)
1358 +               return 0;
1359 +
1360 +       spin_lock_irqsave(&sbh_lock, flags);
1361 +       coreidx = sb_coreidx(sbh);
1362 +       if (!sb_setcoreidx(sbh, PCI_SLOT(dev->devfn)))
1363 +               return PCIBIOS_DEVICE_NOT_FOUND;
1364 +
1365 +       /* 
1366 +        * The USB core requires a special bit to be set during core
1367 +        * reset to enable host (OHCI) mode. Resetting the SB core in
1368 +        * pcibios_enable_device() is a hack for compatibility with
1369 +        * vanilla usb-ohci so that it does not have to know about
1370 +        * SB. A driver that wants to use the USB core in device mode
1371 +        * should know about SB and should reset the bit back to 0
1372 +        * after calling pcibios_enable_device().
1373 +        */
1374 +       if (sb_coreid(sbh) == SB_USB) {
1375 +               sb_core_disable(sbh, sb_coreflags(sbh, 0, 0));
1376 +               sb_core_reset(sbh, 1 << 29);
1377 +       } else
1378 +               sb_core_reset(sbh, 0);
1379 +
1380 +       sb_setcoreidx(sbh, coreidx);
1381 +       spin_unlock_irqrestore(&sbh_lock, flags);
1382 +       
1383 +       return 0;
1384 +}
1385 +
1386 +void
1387 +pcibios_update_resource(struct pci_dev *dev, struct resource *root,
1388 +                       struct resource *res, int resource)
1389 +{
1390 +       unsigned long where, size;
1391 +       u32 reg;
1392 +
1393 +       /* External PCI only */
1394 +       if (dev->bus->number == 0)
1395 +               return;
1396 +
1397 +       where = PCI_BASE_ADDRESS_0 + (resource * 4);
1398 +       size = res->end - res->start;
1399 +       pci_read_config_dword(dev, where, &reg);
1400 +       reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
1401 +       pci_write_config_dword(dev, where, reg);
1402 +}
1403 +
1404 +static void __init
1405 +quirk_sbpci_bridge(struct pci_dev *dev)
1406 +{
1407 +       if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0)
1408 +               return;
1409 +
1410 +       printk("PCI: Fixing up bridge\n");
1411 +
1412 +       /* Enable PCI bridge bus mastering and memory space */
1413 +       pci_set_master(dev);
1414 +       pcibios_enable_resources(dev);
1415 +
1416 +       /* Enable PCI bridge BAR1 prefetch and burst */
1417 +       pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3);
1418 +}      
1419 +
1420 +struct pci_fixup pcibios_fixups[] = {
1421 +       { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, quirk_sbpci_bridge },
1422 +       { 0 }
1423 +};
1424 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
1425 +++ linux-2.4.20/arch/mips/brcm-boards/bcm947xx/perfcntr.c      2005-01-07 05:39:02.000000000 -0500
1426 @@ -0,0 +1,67 @@
1427 +/*
1428 + * Broadcom BCM47xx Performance Counter /proc/cpuinfo support
1429 + *
1430 + * Copyright 2004, Broadcom Corporation
1431 + * All Rights Reserved.
1432 + * 
1433 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1434 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1435 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1436 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1437 + *
1438 + * $Id: perfcntr.c,v 1.1.1.3 2004/04/12 04:31:00 honor Exp $
1439 + */
1440 +
1441 +#include <asm/mipsregs.h>
1442 +
1443 +/* 
1444 + * BCM4710 performance counter register select values
1445 + * No even-odd control-counter mapping, just counters
1446 + */
1447 +#define PERF_DCACHE_HIT                0
1448 +#define PERF_DCACHE_MISS       1
1449 +#define PERF_ICACHE_HIT                2
1450 +#define PERF_ICACHE_MISS       3
1451 +#define PERF_ICOUNT            4
1452 +
1453 +/* 
1454 + * Move from Coprocessor 0 Register 25 Select n
1455 + * data <- CPR[0,25,n] 
1456 + * GPR[1] <- data
1457 + */
1458 +#define read_bcm4710_perf_cntr(n)                              \
1459 +({ int __res;                                                  \
1460 +        __asm__ __volatile__(                                  \
1461 +       ".set\tnoreorder\n\t"                                   \
1462 +       ".set\tnoat\n\t"                                        \
1463 +       ".word\t"STR(0x4001c800|(n))"\n\t"                      \
1464 +       "move\t%0,$1\n\t"                                       \
1465 +       ".set\tat\n\t"                                          \
1466 +       ".set\treorder"                                         \
1467 +       :"=r" (__res));                                         \
1468 +       __res;})
1469 +
1470 +asmlinkage unsigned int read_perf_cntr(unsigned int counter)
1471 +{
1472 +       switch (counter) {
1473 +       case PERF_DCACHE_HIT:   return read_bcm4710_perf_cntr(PERF_DCACHE_HIT);
1474 +       case PERF_DCACHE_MISS:  return read_bcm4710_perf_cntr(PERF_DCACHE_MISS);
1475 +       case PERF_ICACHE_HIT:   return read_bcm4710_perf_cntr(PERF_ICACHE_HIT);
1476 +       case PERF_ICACHE_MISS:  return read_bcm4710_perf_cntr(PERF_ICACHE_MISS);
1477 +       case PERF_ICOUNT:       return read_bcm4710_perf_cntr(PERF_ICOUNT);
1478 +       }
1479 +       return 0;
1480 +}
1481 +
1482 +asmlinkage void write_perf_cntr(unsigned int counter, unsigned int val)
1483 +{
1484 +}
1485 +
1486 +asmlinkage unsigned int read_perf_cntl(unsigned int counter)
1487 +{
1488 +       return 0;
1489 +}
1490 +
1491 +asmlinkage void write_perf_cntl(unsigned int counter, unsigned int val)
1492 +{
1493 +}
1494 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
1495 +++ linux-2.4.20/arch/mips/brcm-boards/bcm947xx/prom.c  2005-01-07 05:39:02.000000000 -0500
1496 @@ -0,0 +1,41 @@
1497 +/*
1498 + * Early initialization code for BCM94710 boards
1499 + *
1500 + * Copyright 2004, Broadcom Corporation
1501 + * All Rights Reserved.
1502 + * 
1503 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1504 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1505 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1506 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1507 + *
1508 + * $Id: prom.c,v 1.1.1.6 2004/04/12 04:31:00 honor Exp $
1509 + */
1510 +
1511 +#include <linux/config.h>
1512 +#include <linux/init.h>
1513 +#include <linux/kernel.h>
1514 +#include <linux/types.h>
1515 +#include <asm/bootinfo.h>
1516 +
1517 +void __init
1518 +prom_init(int argc, const char **argv)
1519 +{
1520 +       unsigned long mem;
1521 +
1522 +        mips_machgroup = MACH_GROUP_BRCM;
1523 +        mips_machtype = MACH_BCM947XX;
1524 +
1525 +       /* Figure out memory size by finding aliases */
1526 +       for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
1527 +               if (*(unsigned long *)((unsigned long)(prom_init) + mem) == 
1528 +                   *(unsigned long *)(prom_init))
1529 +                       break;
1530 +       }
1531 +       add_memory_region(0, mem, BOOT_MEM_RAM);
1532 +}
1533 +
1534 +void __init
1535 +prom_free_prom_memory(void)
1536 +{
1537 +}
1538 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
1539 +++ linux-2.4.20/arch/mips/brcm-boards/bcm947xx/setup.c 2005-01-07 05:39:02.000000000 -0500
1540 @@ -0,0 +1,284 @@
1541 +/*
1542 + * Generic setup routines for Broadcom MIPS boards
1543 + *
1544 + * Copyright 2004, Broadcom Corporation
1545 + * All Rights Reserved.
1546 + * 
1547 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1548 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1549 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1550 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1551 + *
1552 + * $Id: setup.c,v 1.3 2004/04/12 05:42:38 honor Exp $
1553 + */
1554 +
1555 +#include <linux/config.h>
1556 +#include <linux/init.h>
1557 +#include <linux/kernel.h>
1558 +#include <linux/serialP.h>
1559 +#include <linux/ide.h>
1560 +#include <asm/bootinfo.h>
1561 +#include <asm/time.h>
1562 +#include <asm/reboot.h>
1563 +
1564 +#ifdef CONFIG_MTD_PARTITIONS
1565 +#include <linux/mtd/mtd.h>
1566 +#include <linux/mtd/partitions.h>
1567 +#include <linux/minix_fs.h>
1568 +#include <linux/ext2_fs.h>
1569 +#include <linux/romfs_fs.h>
1570 +#include <linux/cramfs_fs.h>
1571 +#endif
1572 +
1573 +#include <typedefs.h>
1574 +#include <bcmutils.h>
1575 +#include <bcmnvram.h>
1576 +#include <sbmips.h>
1577 +#include <sbutils.h>
1578 +#include <trxhdr.h>
1579 +
1580 +extern void bcm947xx_time_init(void);
1581 +extern void bcm947xx_timer_setup(struct irqaction *irq);
1582 +
1583 +#ifdef CONFIG_REMOTE_DEBUG
1584 +extern void set_debug_traps(void);
1585 +extern void rs_kgdb_hook(struct serial_state *);
1586 +extern void breakpoint(void);
1587 +#endif
1588 +
1589 +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
1590 +extern struct ide_ops std_ide_ops;
1591 +#endif
1592 +
1593 +/* Global SB handle */
1594 +void *bcm947xx_sbh = NULL;
1595 +spinlock_t bcm947xx_sbh_lock = SPIN_LOCK_UNLOCKED;
1596 +EXPORT_SYMBOL(bcm947xx_sbh);
1597 +EXPORT_SYMBOL(bcm947xx_sbh_lock);
1598 +
1599 +/* Convenience */
1600 +#define sbh bcm947xx_sbh
1601 +#define sbh_lock bcm947xx_sbh_lock
1602 +
1603 +/* Kernel command line */
1604 +char arcs_cmdline[CL_SIZE] __initdata = CONFIG_CMDLINE;
1605 +
1606 +void
1607 +bcm947xx_machine_restart(char *command)
1608 +{
1609 +       printk("Please stand by while rebooting the system...\n");
1610 +
1611 +       /* Set the watchdog timer to reset immediately */
1612 +       __cli();
1613 +       sb_watchdog(sbh, 1);
1614 +       while (1);
1615 +}
1616 +
1617 +void
1618 +bcm947xx_machine_halt(void)
1619 +{
1620 +       printk("System halted\n");
1621 +
1622 +       /* Disable interrupts and watchdog and spin forever */
1623 +       __cli();
1624 +       sb_watchdog(sbh, 0);
1625 +       while (1);
1626 +}
1627 +
1628 +#ifdef CONFIG_SERIAL
1629 +
1630 +static struct serial_struct rs = {
1631 +       line: 0,
1632 +       flags: ASYNC_BOOT_AUTOCONF,
1633 +       io_type: SERIAL_IO_MEM,
1634 +};
1635 +
1636 +static void __init
1637 +serial_add(void *regs, uint irq, uint baud_base, uint reg_shift)
1638 +{
1639 +       rs.iomem_base = regs;
1640 +       rs.irq = irq + 2;
1641 +       rs.baud_base = baud_base / 16;
1642 +       rs.iomem_reg_shift = reg_shift;
1643 +
1644 +       early_serial_setup(&rs);
1645 +
1646 +       rs.line++;
1647 +}
1648 +
1649 +static void __init
1650 +serial_setup(void *sbh)
1651 +{
1652 +       sb_serial_init(sbh, serial_add);
1653 +
1654 +#ifdef CONFIG_REMOTE_DEBUG
1655 +       /* Use the last port for kernel debugging */
1656 +       if (rs.iomem_base)
1657 +               rs_kgdb_hook(&rs);
1658 +#endif
1659 +}
1660 +
1661 +#endif /* CONFIG_SERIAL */
1662 +
1663 +void __init
1664 +brcm_setup(void)
1665 +{
1666 +       char *value;
1667 +
1668 +       /* Get global SB handle */
1669 +       sbh = sb_kattach();
1670 +
1671 +       /* Initialize clocks and interrupts */
1672 +       sb_mips_init(sbh);
1673 +
1674 +#ifdef CONFIG_SERIAL
1675 +       /* Initialize UARTs */
1676 +       serial_setup(sbh);
1677 +#endif
1678 +
1679 +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
1680 +       ide_ops = &std_ide_ops;
1681 +#endif
1682 +
1683 +       /* Override default command line arguments */
1684 +       value = nvram_get("kernel_args");
1685 +       if (value && strlen(value) && strncmp(value, "empty", 5))
1686 +               strncpy(arcs_cmdline, value, sizeof(arcs_cmdline));
1687 +
1688 +
1689 +       /* Generic setup */
1690 +       _machine_restart = bcm947xx_machine_restart;
1691 +       _machine_halt = bcm947xx_machine_halt;
1692 +       _machine_power_off = bcm947xx_machine_halt;
1693 +
1694 +       board_time_init = bcm947xx_time_init;
1695 +       board_timer_setup = bcm947xx_timer_setup;
1696 +}
1697 +
1698 +const char *
1699 +get_system_type(void)
1700 +{
1701 +       return "Broadcom BCM947XX";
1702 +}
1703 +
1704 +void __init
1705 +bus_error_init(void)
1706 +{
1707 +}
1708 +
1709 +#ifdef CONFIG_MTD_PARTITIONS
1710 +
1711 +static struct mtd_partition bcm947xx_parts[] = {
1712 +       { name: "pmon", offset: 0, size: 0, /*mask_flags: MTD_WRITEABLE,*/ },
1713 +       { name: "linux", offset: 0, size: 0, },
1714 +       { name: "rootfs", offset: 0, size: 0, /*mask_flags: MTD_WRITEABLE,*/ },
1715 +       { name: "nvram", offset: 0, size: 0, },
1716 +       { name: NULL, },
1717 +};
1718 +
1719 +struct mtd_partition * __init
1720 +init_mtd_partitions(struct mtd_info *mtd, size_t size)
1721 +{
1722 +       struct minix_super_block *minixsb;
1723 +       struct ext2_super_block *ext2sb;
1724 +       struct romfs_super_block *romfsb;
1725 +       struct cramfs_super *cramfsb;
1726 +       struct trx_header *trx;
1727 +       unsigned char buf[512];
1728 +       int off;
1729 +       size_t len;
1730 +
1731 +       minixsb = (struct minix_super_block *) buf;
1732 +       ext2sb = (struct ext2_super_block *) buf;
1733 +       romfsb = (struct romfs_super_block *) buf;
1734 +       cramfsb = (struct cramfs_super *) buf;
1735 +       trx = (struct trx_header *) buf;
1736 +
1737 +       /* Look at every 64 KB boundary */
1738 +       for (off = 0; off < size; off += (64 * 1024)) {
1739 +               memset(buf, 0xe5, sizeof(buf));
1740 +
1741 +               /*
1742 +                * Read block 0 to test for romfs and cramfs superblock
1743 +                */
1744 +               if (MTD_READ(mtd, off, sizeof(buf), &len, buf) ||
1745 +                   len != sizeof(buf))
1746 +                       continue;
1747 +
1748 +               /* Try looking at TRX header for rootfs offset */
1749 +               if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
1750 +                       bcm947xx_parts[1].offset = off;
1751 +                       if (le32_to_cpu(trx->offsets[1]) > off)
1752 +                               off = le32_to_cpu(trx->offsets[1]);
1753 +                       continue;
1754 +               }
1755 +
1756 +               /* romfs is at block zero too */
1757 +               if (romfsb->word0 == ROMSB_WORD0 &&
1758 +                   romfsb->word1 == ROMSB_WORD1) {
1759 +                       printk(KERN_NOTICE
1760 +                              "%s: romfs filesystem found at block %d\n",
1761 +                              mtd->name, off / BLOCK_SIZE);
1762 +                       goto done;
1763 +               }
1764 +
1765 +               /* so is cramfs */
1766 +               if (cramfsb->magic == CRAMFS_MAGIC) {
1767 +                       printk(KERN_NOTICE
1768 +                              "%s: cramfs filesystem found at block %d\n",
1769 +                              mtd->name, off / BLOCK_SIZE);
1770 +                       goto done;
1771 +               }
1772 +
1773 +               /*
1774 +                * Read block 1 to test for minix and ext2 superblock
1775 +                */
1776 +               if (MTD_READ(mtd, off + BLOCK_SIZE, sizeof(buf), &len, buf) ||
1777 +                   len != sizeof(buf))
1778 +                       continue;
1779 +
1780 +               /* Try minix */
1781 +               if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
1782 +                   minixsb->s_magic == MINIX_SUPER_MAGIC2) {
1783 +                       printk(KERN_NOTICE
1784 +                              "%s: Minix filesystem found at block %d\n",
1785 +                              mtd->name, off / BLOCK_SIZE);
1786 +                       goto done;
1787 +               }
1788 +
1789 +               /* Try ext2 */
1790 +               if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
1791 +                       printk(KERN_NOTICE
1792 +                              "%s: ext2 filesystem found at block %d\n",
1793 +                              mtd->name, off / BLOCK_SIZE);
1794 +                       goto done;
1795 +               }
1796 +       }
1797 +
1798 +       printk(KERN_NOTICE
1799 +              "%s: Couldn't find valid ROM disk image\n",
1800 +              mtd->name);
1801 +
1802 + done:
1803 +       /* Find and size nvram */
1804 +       bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize);
1805 +       bcm947xx_parts[3].size = size - bcm947xx_parts[3].offset;
1806 +
1807 +       /* Find and size rootfs */
1808 +       if (off < size) {
1809 +               bcm947xx_parts[2].offset = off;
1810 +               bcm947xx_parts[2].size = bcm947xx_parts[3].offset - bcm947xx_parts[2].offset;
1811 +       }
1812 +
1813 +       /* Size linux (kernel and rootfs) */
1814 +       bcm947xx_parts[1].size = bcm947xx_parts[3].offset - bcm947xx_parts[1].offset;
1815 +
1816 +       /* Size pmon */
1817 +       bcm947xx_parts[0].size = bcm947xx_parts[1].offset - bcm947xx_parts[0].offset;
1818 +
1819 +       return bcm947xx_parts;
1820 +}
1821 +
1822 +EXPORT_SYMBOL(init_mtd_partitions);
1823 +
1824 +#endif
1825 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
1826 +++ linux-2.4.20/arch/mips/brcm-boards/bcm947xx/time.c  2005-01-07 05:39:02.000000000 -0500
1827 @@ -0,0 +1,117 @@
1828 +/*
1829 + * Copyright 2004, Broadcom Corporation
1830 + * All Rights Reserved.
1831 + * 
1832 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1833 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1834 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1835 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1836 + *
1837 + * $Id: time.c,v 1.1.1.6 2004/04/12 04:31:00 honor Exp $
1838 + */
1839 +#include <linux/config.h>
1840 +#include <linux/init.h>
1841 +#include <linux/kernel.h>
1842 +#include <linux/sched.h>
1843 +#include <linux/serial_reg.h>
1844 +#include <linux/interrupt.h>
1845 +#include <asm/addrspace.h>
1846 +#include <asm/io.h>
1847 +#include <asm/time.h>
1848 +
1849 +#include <typedefs.h>
1850 +#include <bcmnvram.h>
1851 +#include <sbconfig.h>
1852 +#include <sbextif.h>
1853 +#include <sbutils.h>
1854 +#include <sbmips.h>
1855 +
1856 +/* Global SB handle */
1857 +extern void *bcm947xx_sbh;
1858 +extern spinlock_t bcm947xx_sbh_lock;
1859 +
1860 +/* Convenience */
1861 +#define sbh bcm947xx_sbh
1862 +#define sbh_lock bcm947xx_sbh_lock
1863 +
1864 +extern int panic_timeout;
1865 +static int watchdog = 0;
1866 +static u8 *mcr = NULL;
1867 +
1868 +void __init
1869 +bcm947xx_time_init(void)
1870 +{
1871 +       unsigned int hz;
1872 +       extifregs_t *eir;
1873 +
1874 +       /*
1875 +        * Use deterministic values for initial counter interrupt
1876 +        * so that calibrate delay avoids encountering a counter wrap.
1877 +        */
1878 +       write_c0_count(0);
1879 +       write_c0_compare(0xffff);
1880 +
1881 +       if (!(hz = sb_mips_clock(sbh)))
1882 +               hz = 100000000;
1883 +
1884 +       printk("CPU: BCM%04x rev %d at %d MHz\n", sb_chip(sbh), sb_chiprev(sbh),
1885 +              (hz + 500000) / 1000000);
1886 +
1887 +       /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
1888 +       mips_counter_frequency = hz / 2;
1889 +
1890 +       /* Set watchdog interval in ms */
1891 +       watchdog = simple_strtoul(nvram_safe_get("watchdog"), NULL, 0);
1892 +       
1893 +       /* Please set the watchdog to 3 sec if it is less than 3 but not equal to 0 */
1894 +       if (watchdog > 0) {
1895 +               if (watchdog < 3000)
1896 +                       watchdog = 3000;
1897 +       }
1898 +
1899 +
1900 +       /* Set panic timeout in seconds */
1901 +       panic_timeout = watchdog / 1000;
1902 +
1903 +       /* Setup blink */
1904 +       if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) {
1905 +               sbconfig_t *sb = (sbconfig_t *)((unsigned int) eir + SBCONFIGOFF);
1906 +               unsigned long base = EXTIF_CFGIF_BASE(sb_base(readl(&sb->sbadmatch1)));
1907 +               mcr = (u8 *) ioremap_nocache(base + UART_MCR, 1);
1908 +       }
1909 +}
1910 +
1911 +static void
1912 +bcm947xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1913 +{
1914 +       /* Generic MIPS timer code */
1915 +       timer_interrupt(irq, dev_id, regs);
1916 +
1917 +       /* Set the watchdog timer to reset after the specified number of ms */
1918 +       if (watchdog > 0)
1919 +               sb_watchdog(sbh, WATCHDOG_CLOCK / 1000 * watchdog);
1920 +
1921 +#ifdef CONFIG_HWSIM
1922 +       (*((int *)0xa0000f1c))++;
1923 +#else
1924 +       /* Blink one of the LEDs in the external UART */
1925 +       if (mcr && !(jiffies % (HZ/2)))
1926 +               writeb(readb(mcr) ^ UART_MCR_OUT2, mcr);
1927 +#endif
1928 +}
1929 +
1930 +static struct irqaction bcm947xx_timer_irqaction = {
1931 +       bcm947xx_timer_interrupt,
1932 +       SA_INTERRUPT,
1933 +       0,
1934 +       "timer",
1935 +       NULL,
1936 +       NULL
1937 +};
1938 +
1939 +void __init
1940 +bcm947xx_timer_setup(struct irqaction *irq)
1941 +{
1942 +       /* Enable the timer interrupt */
1943 +       setup_irq(7, &bcm947xx_timer_irqaction);
1944 +}
1945 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
1946 +++ linux-2.4.20/arch/mips/brcm-boards/generic/Makefile 2005-01-07 05:39:02.000000000 -0500
1947 @@ -0,0 +1,26 @@
1948 +#
1949 +# Makefile for generic Broadcom MIPS boards
1950 +#
1951 +# Copyright 2004, Broadcom Corporation
1952 +# All Rights Reserved.
1953 +# 
1954 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1955 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1956 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1957 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1958 +#
1959 +# $Id: Makefile,v 1.1.1.6 2004/04/12 04:31:00 honor Exp $
1960 +#
1961 +
1962 +.S.s:
1963 +       $(CPP) $(AFLAGS) $< -o $*.s
1964 +.S.o:
1965 +       $(CC) $(AFLAGS) -c $< -o $*.o
1966 +
1967 +O_TARGET       := brcm.o
1968 +
1969 +obj-y          := int-handler.o irq.o
1970 +
1971 +obj-$(CONFIG_REMOTE_DEBUG)     += gdb_hook.o
1972 +
1973 +include $(TOPDIR)/Rules.make
1974 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
1975 +++ linux-2.4.20/arch/mips/brcm-boards/generic/gdb_hook.c       2005-01-07 05:39:02.000000000 -0500
1976 @@ -0,0 +1,120 @@
1977 +/*
1978 + * Copyright 2004, Broadcom Corporation      
1979 + * All Rights Reserved.      
1980 + *       
1981 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY      
1982 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM      
1983 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS      
1984 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.      
1985 + *
1986 + * Carsten Langgaard, carstenl@mips.com
1987 + * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
1988 + *
1989 + * ########################################################################
1990 + *
1991 + *  This program is free software; you can distribute it and/or modify it
1992 + *  under the terms of the GNU General Public License (Version 2) as
1993 + *  published by the Free Software Foundation.
1994 + *
1995 + *  This program is distributed in the hope it will be useful, but WITHOUT
1996 + *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1997 + *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1998 + *  for more details.
1999 + *
2000 + *  You should have received a copy of the GNU General Public License along
2001 + *  with this program; if not, write to the Free Software Foundation, Inc.,
2002 + *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
2003 + *
2004 + * ########################################################################
2005 + *
2006 + * This is the interface to the remote debugger stub.
2007 + *
2008 + */
2009 +
2010 +#include <linux/serialP.h>
2011 +#include <linux/serial_reg.h>
2012 +
2013 +#include <asm/serial.h>
2014 +#include <asm/io.h>
2015 +
2016 +static struct async_struct kdb_port_info = {0};
2017 +
2018 +static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
2019 +{
2020 +       return readb((unsigned long) info->iomem_base +
2021 +                    (offset<<info->iomem_reg_shift));
2022 +}
2023 +
2024 +static __inline__ void serial_out(struct async_struct *info, int offset,
2025 +                                 int value)
2026 +{
2027 +       writeb(value, (unsigned long) info->iomem_base +
2028 +              (offset<<info->iomem_reg_shift));
2029 +}
2030 +
2031 +void rs_kgdb_hook(struct serial_state *ser) {
2032 +       int t;
2033 +
2034 +       kdb_port_info.state = ser;
2035 +       kdb_port_info.magic = SERIAL_MAGIC;
2036 +       kdb_port_info.port = ser->port;
2037 +       kdb_port_info.flags = ser->flags;
2038 +       kdb_port_info.iomem_base = ser->iomem_base;
2039 +       kdb_port_info.iomem_reg_shift = ser->iomem_reg_shift;
2040 +       kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
2041 +
2042 +       /*
2043 +        * Clear all interrupts
2044 +        */
2045 +       serial_in(&kdb_port_info, UART_LSR);
2046 +       serial_in(&kdb_port_info, UART_RX);
2047 +       serial_in(&kdb_port_info, UART_IIR);
2048 +       serial_in(&kdb_port_info, UART_MSR);
2049 +
2050 +       /*
2051 +        * Now, initialize the UART 
2052 +        */
2053 +       serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);   /* reset DLAB */
2054 +       serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
2055 +       
2056 +       /*
2057 +        * and set the speed of the serial port
2058 +        * (currently hardwired to 115200 8N1
2059 +        */
2060 +
2061 +       /* baud rate is fixed to 115200 (is this sufficient?)*/
2062 +       t = kdb_port_info.state->baud_base / 115200;    
2063 +       /* set DLAB */
2064 +       serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
2065 +       serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
2066 +       serial_out(&kdb_port_info, UART_DLM, t >> 8);  /* MS of divisor */
2067 +       /* reset DLAB */
2068 +       serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
2069 +}
2070 +
2071 +int putDebugChar(char c)
2072 +{
2073 +
2074 +       if (!kdb_port_info.state) {     /* need to init device first */
2075 +               return 0;
2076 +       }
2077 +
2078 +       while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
2079 +               ;
2080 +
2081 +       serial_out(&kdb_port_info, UART_TX, c);
2082 +
2083 +       return 1;
2084 +}
2085 +
2086 +char getDebugChar(void) 
2087 +{
2088 +       if (!kdb_port_info.state) {     /* need to init device first */
2089 +               return 0;
2090 +       }
2091 +
2092 +       while (!(serial_in(&kdb_port_info, UART_LSR) & 1))
2093 +               ;
2094 +
2095 +       return(serial_in(&kdb_port_info, UART_RX));
2096 +}
2097 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
2098 +++ linux-2.4.20/arch/mips/brcm-boards/generic/int-handler.S    2005-01-07 05:39:02.000000000 -0500
2099 @@ -0,0 +1,51 @@
2100 +/*
2101 + * Generic interrupt handler for Broadcom MIPS boards
2102 + *
2103 + * Copyright 2004, Broadcom Corporation
2104 + * All Rights Reserved.
2105 + * 
2106 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
2107 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
2108 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
2109 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
2110 + *
2111 + * $Id: int-handler.S,v 1.1.1.6 2004/04/12 04:31:00 honor Exp $
2112 + */
2113 +
2114 +#include <linux/config.h>
2115 +
2116 +#include <asm/asm.h>
2117 +#include <asm/mipsregs.h>
2118 +#include <asm/regdef.h>
2119 +#include <asm/stackframe.h>
2120 +
2121 +/*
2122 + *     MIPS IRQ        Source
2123 + *      --------        ------
2124 + *             0       Software (ignored)
2125 + *             1        Software (ignored)
2126 + *             2        Combined hardware interrupt (hw0)
2127 + *             3        Hardware
2128 + *             4        Hardware
2129 + *             5        Hardware
2130 + *             6        Hardware
2131 + *             7        R4k timer
2132 + */
2133 +
2134 +       .text
2135 +       .set    noreorder
2136 +       .set    noat
2137 +       .align  5
2138 +       NESTED(brcmIRQ, PT_SIZE, sp)
2139 +       SAVE_ALL
2140 +       CLI
2141 +       .set    at
2142 +    .set    noreorder
2143 +
2144 +       jal         brcm_irq_dispatch
2145 +        move   a0, sp
2146 +
2147 +       j           ret_from_irq
2148 +        nop
2149 +               
2150 +       END(brcmIRQ)
2151 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
2152 +++ linux-2.4.20/arch/mips/brcm-boards/generic/irq.c    2005-01-07 05:39:02.000000000 -0500
2153 @@ -0,0 +1,130 @@
2154 +/*
2155 + * Generic interrupt control functions for Broadcom MIPS boards
2156 + *
2157 + * Copyright 2004, Broadcom Corporation
2158 + * All Rights Reserved.
2159 + * 
2160 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
2161 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
2162 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
2163 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
2164 + *
2165 + * $Id: irq.c,v 1.1.1.6 2004/04/12 04:31:00 honor Exp $
2166 + */
2167 +
2168 +#include <linux/config.h>
2169 +#include <linux/init.h>
2170 +#include <linux/kernel.h>
2171 +#include <linux/types.h>
2172 +#include <linux/interrupt.h>
2173 +#include <linux/irq.h>
2174 +
2175 +#include <asm/irq.h>
2176 +#include <asm/mipsregs.h>
2177 +#include <asm/gdb-stub.h>
2178 +
2179 +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
2180 +
2181 +extern asmlinkage void brcmIRQ(void);
2182 +extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
2183 +
2184 +void
2185 +brcm_irq_dispatch(struct pt_regs *regs)
2186 +{
2187 +       u32 cause;
2188 +
2189 +       cause = read_c0_cause() &
2190 +               read_c0_status() &
2191 +               CAUSEF_IP;
2192 +
2193 +#ifdef CONFIG_KERNPROF
2194 +       change_c0_status(cause | 1, 1);
2195 +#else
2196 +       clear_c0_status(cause);
2197 +#endif
2198 +
2199 +       if (cause & CAUSEF_IP7)
2200 +               do_IRQ(7, regs);
2201 +       if (cause & CAUSEF_IP2)
2202 +               do_IRQ(2, regs);
2203 +       if (cause & CAUSEF_IP3)
2204 +               do_IRQ(3, regs);
2205 +       if (cause & CAUSEF_IP4)
2206 +               do_IRQ(4, regs);
2207 +       if (cause & CAUSEF_IP5)
2208 +               do_IRQ(5, regs);
2209 +       if (cause & CAUSEF_IP6)
2210 +               do_IRQ(6, regs);
2211 +}
2212 +
2213 +static void
2214 +enable_brcm_irq(unsigned int irq)
2215 +{
2216 +       if (irq < 8)
2217 +               set_c0_status(1 << (irq + 8));
2218 +       else
2219 +               set_c0_status(IE_IRQ0);
2220 +}
2221 +
2222 +static void
2223 +disable_brcm_irq(unsigned int irq)
2224 +{
2225 +       if (irq < 8)
2226 +               clear_c0_status(1 << (irq + 8));
2227 +       else
2228 +               clear_c0_status(IE_IRQ0);
2229 +}
2230 +
2231 +static void
2232 +ack_brcm_irq(unsigned int irq)
2233 +{
2234 +       /* Already done in brcm_irq_dispatch */
2235 +}
2236 +
2237 +static unsigned int
2238 +startup_brcm_irq(unsigned int irq)
2239 +{ 
2240 +       enable_brcm_irq(irq);
2241 +
2242 +       return 0; /* never anything pending */
2243 +}
2244 +
2245 +static void
2246 +end_brcm_irq(unsigned int irq)
2247 +{
2248 +       if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
2249 +               enable_brcm_irq(irq);
2250 +}
2251 +
2252 +static struct hw_interrupt_type brcm_irq_type = {
2253 +       typename: "MIPS",
2254 +       startup: startup_brcm_irq,
2255 +       shutdown: disable_brcm_irq,
2256 +       enable: enable_brcm_irq,
2257 +       disable: disable_brcm_irq,
2258 +       ack: ack_brcm_irq,
2259 +       end: end_brcm_irq,
2260 +       NULL
2261 +};
2262 +
2263 +void __init
2264 +init_IRQ(void)
2265 +{
2266 +       int i;
2267 +
2268 +       for (i = 0; i < NR_IRQS; i++) {
2269 +               irq_desc[i].status = IRQ_DISABLED;
2270 +               irq_desc[i].action = 0;
2271 +               irq_desc[i].depth = 1;
2272 +               irq_desc[i].handler = &brcm_irq_type;
2273 +       }
2274 +
2275 +       set_except_vector(0, brcmIRQ);
2276 +       change_c0_status(ST0_IM, ALLINTS);
2277 +
2278 +#ifdef CONFIG_REMOTE_DEBUG
2279 +       printk("Breaking into debugger...\n");
2280 +       set_debug_traps();
2281 +       breakpoint(); 
2282 +#endif
2283 +}
2284 --- linux-2.4.20/arch/mips/config-shared.in~2.4.20_broadcom_3_37_2_1109_US.patch        2005-01-07 05:39:01.000000000 -0500
2285 +++ linux-2.4.20/arch/mips/config-shared.in     2005-01-08 12:16:20.335771152 -0500
2286 @@ -191,8 +191,15 @@
2287        fi
2288     fi
2289  fi
2290 +dep_bool 'Support for Broadcom MIPS-based boards' CONFIG_MIPS_BRCM $CONFIG_EXPERIMENTAL
2291 +dep_bool 'Support for Broadcom BCM947XX' CONFIG_BCM947XX $CONFIG_MIPS_BRCM
2292 +if [ "$CONFIG_BCM947XX" = "y" ] ; then
2293 +   bool '    Support for Broadcom BCM4710' CONFIG_BCM4710
2294 +   bool '    Support for Broadcom BCM4310' CONFIG_BCM4310
2295 +   bool '    Support for Broadcom BCM4704' CONFIG_BCM4704
2296 +   bool '    Support for Broadcom BCM5365' CONFIG_BCM5365
2297 +fi
2298  bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
2299 -bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226
2300  dep_bool 'Support for Toshiba JMR-TX3927 board' CONFIG_TOSHIBA_JMR3927 $CONFIG_MIPS32
2301  bool 'Support for Victor MP-C303/304' CONFIG_VICTOR_MPC30X
2302  if [ "$CONFIG_VICTOR_MPC30X" = "y" ]; then
2303 @@ -206,6 +213,11 @@
2304  define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
2305  
2306  #
2307 +# Provide an option for a default kernel command line
2308 +#
2309 +string 'Default kernel command string' CONFIG_CMDLINE ""
2310 +
2311 +#
2312  # Select some configuration options automatically based on user selections.
2313  #
2314  
2315 @@ -526,6 +538,13 @@
2316     define_bool CONFIG_SWAP_IO_SPACE_L y
2317     define_bool CONFIG_BOOT_ELF32 y
2318  fi
2319 +if [ "$CONFIG_BCM947XX" = "y" ] ; then
2320 +   define_bool CONFIG_PCI y
2321 +   define_bool CONFIG_NONCOHERENT_IO y
2322 +   define_bool CONFIG_NEW_TIME_C y
2323 +   define_bool CONFIG_NEW_IRQ y
2324 +   define_bool CONFIG_HND y
2325 +fi
2326  if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then
2327     define_bool CONFIG_ARC32 y
2328     define_bool CONFIG_ARC_MEMORY y
2329 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
2330 +++ linux-2.4.20/arch/mips/defconfig-bcm947xx   2005-01-07 05:39:02.000000000 -0500
2331 @@ -0,0 +1,769 @@
2332 +#
2333 +# Automatically generated make config: don't edit
2334 +#
2335 +CONFIG_MIPS=y
2336 +CONFIG_MIPS32=y
2337 +# CONFIG_MIPS64 is not set
2338 +
2339 +#
2340 +# Code maturity level options
2341 +#
2342 +CONFIG_EXPERIMENTAL=y
2343 +
2344 +#
2345 +# Loadable module support
2346 +#
2347 +CONFIG_MODULES=y
2348 +# CONFIG_MODVERSIONS is not set
2349 +# CONFIG_KMOD is not set
2350 +
2351 +#
2352 +# Machine selection
2353 +#
2354 +# CONFIG_ACER_PICA_61 is not set
2355 +# CONFIG_MIPS_DB1000 is not set
2356 +# CONFIG_MIPS_DB1100 is not set
2357 +# CONFIG_MIPS_DB1500 is not set
2358 +# CONFIG_MIPS_PB1000 is not set
2359 +# CONFIG_MIPS_PB1100 is not set
2360 +# CONFIG_MIPS_PB1500 is not set
2361 +# CONFIG_BAGET_MIPS is not set
2362 +# CONFIG_CASIO_E55 is not set
2363 +# CONFIG_MIPS_COBALT is not set
2364 +# CONFIG_DECSTATION is not set
2365 +# CONFIG_MIPS_EV64120 is not set
2366 +# CONFIG_MIPS_EV96100 is not set
2367 +# CONFIG_MIPS_IVR is not set
2368 +# CONFIG_HP_LASERJET is not set
2369 +# CONFIG_IBM_WORKPAD is not set
2370 +# CONFIG_LASAT is not set
2371 +# CONFIG_MIPS_ITE8172 is not set
2372 +# CONFIG_MIPS_ATLAS is not set
2373 +# CONFIG_MIPS_MAGNUM_4000 is not set
2374 +# CONFIG_MIPS_MALTA is not set
2375 +# CONFIG_MIPS_SEAD is not set
2376 +# CONFIG_MOMENCO_OCELOT is not set
2377 +# CONFIG_MOMENCO_OCELOT_G is not set
2378 +# CONFIG_DDB5074 is not set
2379 +# CONFIG_DDB5476 is not set
2380 +# CONFIG_DDB5477 is not set
2381 +# CONFIG_NEC_OSPREY is not set
2382 +# CONFIG_NEC_EAGLE is not set
2383 +# CONFIG_OLIVETTI_M700 is not set
2384 +# CONFIG_NINO is not set
2385 +# CONFIG_SGI_IP22 is not set
2386 +# CONFIG_SGI_IP27 is not set
2387 +# CONFIG_SGI_IP32 is not set
2388 +# CONFIG_SIBYTE_SB1xxx_SOC is not set
2389 +CONFIG_MIPS_BRCM=y
2390 +CONFIG_BCM947XX=y
2391 +CONFIG_BCM4710=y
2392 +CONFIG_BCM4310=y
2393 +CONFIG_BCM4704=y
2394 +# CONFIG_BCM5365 is not set
2395 +# CONFIG_SNI_RM200_PCI is not set
2396 +# CONFIG_TOSHIBA_JMR3927 is not set
2397 +# CONFIG_VICTOR_MPC30X is not set
2398 +# CONFIG_ZAO_CAPCELLA is not set
2399 +# CONFIG_HIGHMEM is not set
2400 +CONFIG_RWSEM_GENERIC_SPINLOCK=y
2401 +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
2402 +CONFIG_CMDLINE="root=/dev/mtdblock2 noinitrd console=ttyS0,115200"
2403 +CONFIG_PCI=y
2404 +CONFIG_NONCOHERENT_IO=y
2405 +CONFIG_NEW_TIME_C=y
2406 +CONFIG_NEW_IRQ=y
2407 +CONFIG_HND=y
2408 +# CONFIG_MIPS_AU1000 is not set
2409 +
2410 +#
2411 +# CPU selection
2412 +#
2413 +CONFIG_CPU_MIPS32=y
2414 +# CONFIG_CPU_MIPS64 is not set
2415 +# CONFIG_CPU_R3000 is not set
2416 +# CONFIG_CPU_TX39XX is not set
2417 +# CONFIG_CPU_VR41XX is not set
2418 +# CONFIG_CPU_R4300 is not set
2419 +# CONFIG_CPU_R4X00 is not set
2420 +# CONFIG_CPU_TX49XX is not set
2421 +# CONFIG_CPU_R5000 is not set
2422 +# CONFIG_CPU_R5432 is not set
2423 +# CONFIG_CPU_R6000 is not set
2424 +# CONFIG_CPU_NEVADA is not set
2425 +# CONFIG_CPU_R8000 is not set
2426 +# CONFIG_CPU_R10000 is not set
2427 +# CONFIG_CPU_RM7000 is not set
2428 +# CONFIG_CPU_SB1 is not set
2429 +CONFIG_CPU_HAS_PREFETCH=y
2430 +# CONFIG_VTAG_ICACHE is not set
2431 +# CONFIG_64BIT_PHYS_ADDR is not set
2432 +# CONFIG_CPU_ADVANCED is not set
2433 +CONFIG_CPU_HAS_LLSC=y
2434 +# CONFIG_CPU_HAS_LLDSCD is not set
2435 +# CONFIG_CPU_HAS_WB is not set
2436 +CONFIG_CPU_HAS_SYNC=y
2437 +
2438 +#
2439 +# General setup
2440 +#
2441 +CONFIG_CPU_LITTLE_ENDIAN=y
2442 +CONFIG_NET=y
2443 +# CONFIG_PCI_NAMES is not set
2444 +# CONFIG_ISA is not set
2445 +# CONFIG_EISA is not set
2446 +# CONFIG_TC is not set
2447 +# CONFIG_MCA is not set
2448 +# CONFIG_SBUS is not set
2449 +CONFIG_HOTPLUG=y
2450 +
2451 +#
2452 +# PCMCIA/CardBus support
2453 +#
2454 +# CONFIG_PCMCIA is not set
2455 +
2456 +#
2457 +# PCI Hotplug Support
2458 +#
2459 +# CONFIG_HOTPLUG_PCI is not set
2460 +# CONFIG_HOTPLUG_PCI_COMPAQ is not set
2461 +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
2462 +# CONFIG_HOTPLUG_PCI_ACPI is not set
2463 +# CONFIG_SYSVIPC is not set
2464 +# CONFIG_BSD_PROCESS_ACCT is not set
2465 +CONFIG_SYSCTL=y
2466 +# CONFIG_PRINT_SYSCALLS is not set
2467 +CONFIG_KCORE_ELF=y
2468 +# CONFIG_KCORE_AOUT is not set
2469 +# CONFIG_BINFMT_AOUT is not set
2470 +CONFIG_BINFMT_ELF=y
2471 +# CONFIG_MIPS32_COMPAT is not set
2472 +# CONFIG_MIPS32_O32 is not set
2473 +# CONFIG_MIPS32_N32 is not set
2474 +# CONFIG_BINFMT_ELF32 is not set
2475 +# CONFIG_BINFMT_MISC is not set
2476 +# CONFIG_PM is not set
2477 +
2478 +#
2479 +# Memory Technology Devices (MTD)
2480 +#
2481 +CONFIG_MTD=y
2482 +# CONFIG_MTD_DEBUG is not set
2483 +CONFIG_MTD_PARTITIONS=y
2484 +# CONFIG_MTD_CONCAT is not set
2485 +# CONFIG_MTD_REDBOOT_PARTS is not set
2486 +
2487 +#
2488 +# User Modules And Translation Layers
2489 +#
2490 +CONFIG_MTD_CHAR=y
2491 +# CONFIG_MTD_BLOCK is not set
2492 +CONFIG_MTD_BLOCK_RO=y
2493 +# CONFIG_FTL is not set
2494 +# CONFIG_NFTL is not set
2495 +
2496 +#
2497 +# RAM/ROM/Flash chip drivers
2498 +#
2499 +CONFIG_MTD_CFI=y
2500 +# CONFIG_MTD_JEDECPROBE is not set
2501 +CONFIG_MTD_GEN_PROBE=y
2502 +CONFIG_MTD_CFI_ADV_OPTIONS=y
2503 +CONFIG_MTD_CFI_NOSWAP=y
2504 +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
2505 +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
2506 +CONFIG_MTD_CFI_GEOMETRY=y
2507 +# CONFIG_MTD_CFI_B1 is not set
2508 +CONFIG_MTD_CFI_B2=y
2509 +# CONFIG_MTD_CFI_B4 is not set
2510 +CONFIG_MTD_CFI_I1=y
2511 +# CONFIG_MTD_CFI_I2 is not set
2512 +# CONFIG_MTD_CFI_I4 is not set
2513 +CONFIG_MTD_CFI_INTELEXT=y
2514 +CONFIG_MTD_CFI_AMDSTD=y
2515 +CONFIG_MTD_CFI_SSTSTD=y
2516 +# CONFIG_MTD_RAM is not set
2517 +# CONFIG_MTD_ROM is not set
2518 +# CONFIG_MTD_ABSENT is not set
2519 +# CONFIG_MTD_OBSOLETE_CHIPS is not set
2520 +# CONFIG_MTD_AMDSTD is not set
2521 +# CONFIG_MTD_SHARP is not set
2522 +# CONFIG_MTD_JEDEC is not set
2523 +
2524 +#
2525 +# Mapping drivers for chip access
2526 +#
2527 +# CONFIG_MTD_PHYSMAP is not set
2528 +CONFIG_MTD_BCM947XX=y
2529 +# CONFIG_MTD_PB1000 is not set
2530 +# CONFIG_MTD_PB1500 is not set
2531 +# CONFIG_MTD_PB1100 is not set
2532 +# CONFIG_MTD_CSTM_MIPS_IXX is not set
2533 +# CONFIG_MTD_OCELOT is not set
2534 +# CONFIG_MTD_LASAT is not set
2535 +# CONFIG_MTD_PCI is not set
2536 +
2537 +#
2538 +# Self-contained MTD device drivers
2539 +#
2540 +CONFIG_MTD_SFLASH=y
2541 +# CONFIG_MTD_PMC551 is not set
2542 +# CONFIG_MTD_SLRAM is not set
2543 +# CONFIG_MTD_MTDRAM is not set
2544 +# CONFIG_MTD_BLKMTD is not set
2545 +
2546 +#
2547 +# Disk-On-Chip Device Drivers
2548 +#
2549 +# CONFIG_MTD_DOC1000 is not set
2550 +# CONFIG_MTD_DOC2000 is not set
2551 +# CONFIG_MTD_DOC2001 is not set
2552 +# CONFIG_MTD_DOCPROBE is not set
2553 +
2554 +#
2555 +# NAND Flash Device Drivers
2556 +#
2557 +# CONFIG_MTD_NAND is not set
2558 +
2559 +#
2560 +# Parallel port support
2561 +#
2562 +# CONFIG_PARPORT is not set
2563 +
2564 +#
2565 +# Plug and Play configuration
2566 +#
2567 +# CONFIG_PNP is not set
2568 +# CONFIG_ISAPNP is not set
2569 +
2570 +#
2571 +# Block devices
2572 +#
2573 +# CONFIG_BLK_DEV_MSYS is not set
2574 +# CONFIG_NOROOT is not set
2575 +# CONFIG_BLK_DEV_FD is not set
2576 +# CONFIG_BLK_DEV_XD is not set
2577 +# CONFIG_PARIDE is not set
2578 +# CONFIG_BLK_CPQ_DA is not set
2579 +# CONFIG_BLK_CPQ_CISS_DA is not set
2580 +# CONFIG_CISS_SCSI_TAPE is not set
2581 +# CONFIG_BLK_DEV_DAC960 is not set
2582 +# CONFIG_BLK_DEV_UMEM is not set
2583 +# CONFIG_BLK_DEV_LOOP is not set
2584 +# CONFIG_BLK_DEV_NBD is not set
2585 +# CONFIG_BLK_DEV_RAM is not set
2586 +# CONFIG_BLK_DEV_INITRD is not set
2587 +# CONFIG_BLK_STATS is not set
2588 +
2589 +#
2590 +# Multi-device support (RAID and LVM)
2591 +#
2592 +# CONFIG_MD is not set
2593 +# CONFIG_BLK_DEV_MD is not set
2594 +# CONFIG_MD_LINEAR is not set
2595 +# CONFIG_MD_RAID0 is not set
2596 +# CONFIG_MD_RAID1 is not set
2597 +# CONFIG_MD_RAID5 is not set
2598 +# CONFIG_MD_MULTIPATH is not set
2599 +# CONFIG_BLK_DEV_LVM is not set
2600 +
2601 +#
2602 +# Networking options
2603 +#
2604 +CONFIG_PACKET=y
2605 +# CONFIG_PACKET_MMAP is not set
2606 +# CONFIG_NETLINK_DEV is not set
2607 +CONFIG_NETFILTER=y
2608 +# CONFIG_NETFILTER_DEBUG is not set
2609 +# CONFIG_FILTER is not set
2610 +CONFIG_UNIX=y
2611 +CONFIG_INET=y
2612 +CONFIG_IP_MULTICAST=y
2613 +# CONFIG_IP_ADVANCED_ROUTER is not set
2614 +# CONFIG_IP_PNP is not set
2615 +# CONFIG_NET_IPIP is not set
2616 +# CONFIG_NET_IPGRE is not set
2617 +CONFIG_IP_MROUTE=y
2618 +# CONFIG_IP_PIMSM_V1 is not set
2619 +# CONFIG_IP_PIMSM_V2 is not set
2620 +# CONFIG_ARPD is not set
2621 +# CONFIG_INET_ECN is not set
2622 +# CONFIG_SYN_COOKIES is not set
2623 +
2624 +#
2625 +#   IP: Netfilter Configuration
2626 +#
2627 +CONFIG_IP_NF_CONNTRACK=y
2628 +CONFIG_IP_NF_FTP=y
2629 +CONFIG_IP_NF_TFTP=y
2630 +CONFIG_IP_NF_H323=y
2631 +# CONFIG_IP_NF_IRC is not set
2632 +# CONFIG_IP_NF_MMS is not set
2633 +CONFIG_IP_NF_CT_PROTO_GRE=y
2634 +CONFIG_IP_NF_PPTP=y
2635 +# CONFIG_IP_NF_SIP is not set
2636 +# CONFIG_IP_NF_QUEUE is not set
2637 +CONFIG_IP_NF_IPTABLES=y
2638 +# CONFIG_IP_NF_MATCH_LIMIT is not set
2639 +# CONFIG_IP_NF_POOL is not set
2640 +CONFIG_IP_NF_MATCH_MAC=y
2641 +# CONFIG_IP_NF_MATCH_PKTTYPE is not set
2642 +CONFIG_IP_NF_MATCH_MARK=y
2643 +# CONFIG_IP_NF_MATCH_MULTIPORT is not set
2644 +# CONFIG_IP_NF_MATCH_MPORT is not set
2645 +CONFIG_IP_NF_MATCH_TOS=y
2646 +CONFIG_IP_NF_MATCH_TIME=y
2647 +# CONFIG_IP_NF_MATCH_ECN is not set
2648 +# CONFIG_IP_NF_MATCH_DSCP is not set
2649 +# CONFIG_IP_NF_MATCH_AH_ESP is not set
2650 +# CONFIG_IP_NF_MATCH_LENGTH is not set
2651 +# CONFIG_IP_NF_MATCH_TTL is not set
2652 +CONFIG_IP_NF_MATCH_TCPMSS=y
2653 +# CONFIG_IP_NF_MATCH_HELPER is not set
2654 +CONFIG_IP_NF_MATCH_STATE=y
2655 +# CONFIG_IP_NF_MATCH_CONNTRACK is not set
2656 +# CONFIG_IP_NF_MATCH_UNCLEAN is not set
2657 +CONFIG_IP_NF_MATCH_WEBSTR=y
2658 +# CONFIG_IP_NF_MATCH_OWNER is not set
2659 +CONFIG_IP_NF_FILTER=y
2660 +CONFIG_IP_NF_TARGET_REJECT=y
2661 +# CONFIG_IP_NF_TARGET_MIRROR is not set
2662 +CONFIG_IP_NF_NAT=y
2663 +CONFIG_IP_NF_NAT_NEEDED=y
2664 +CONFIG_IP_NF_TARGET_MASQUERADE=y
2665 +CONFIG_IP_NF_TARGET_REDIRECT=y
2666 +CONFIG_IP_NF_AUTOFW=y
2667 +CONFIG_IP_NF_TARGET_TRIGGER=y
2668 +CONFIG_IP_NF_NAT_H323=y
2669 +CONFIG_IP_NF_NAT_PPTP=y
2670 +# CONFIG_IP_NF_NAT_SIP is not set
2671 +CONFIG_IP_NF_NAT_PROTO_GRE=y
2672 +# CONFIG_IP_NF_NAT_LOCAL is not set
2673 +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
2674 +CONFIG_IP_NF_NAT_FTP=y
2675 +CONFIG_IP_NF_NAT_TFTP=y
2676 +CONFIG_IP_NF_MANGLE=y
2677 +CONFIG_IP_NF_TARGET_TOS=y
2678 +# CONFIG_IP_NF_TARGET_ECN is not set
2679 +# CONFIG_IP_NF_TARGET_DSCP is not set
2680 +CONFIG_IP_NF_TARGET_LOG=y
2681 +CONFIG_IP_NF_TARGET_MARK=y
2682 +# CONFIG_IP_NF_TARGET_ULOG is not set
2683 +CONFIG_IP_NF_TARGET_TCPMSS=y
2684 +# CONFIG_IP_NF_ARPTABLES is not set
2685 +# CONFIG_IPV6 is not set
2686 +# CONFIG_KHTTPD is not set
2687 +# CONFIG_ATM is not set
2688 +CONFIG_VLAN_8021Q=y
2689 +
2690 +#
2691 +#  
2692 +#
2693 +# CONFIG_IPX is not set
2694 +# CONFIG_ATALK is not set
2695 +
2696 +#
2697 +# Appletalk devices
2698 +#
2699 +# CONFIG_DEV_APPLETALK is not set
2700 +# CONFIG_DECNET is not set
2701 +CONFIG_BRIDGE=y
2702 +# CONFIG_X25 is not set
2703 +# CONFIG_LAPB is not set
2704 +# CONFIG_LLC is not set
2705 +# CONFIG_NET_DIVERT is not set
2706 +# CONFIG_ECONET is not set
2707 +# CONFIG_WAN_ROUTER is not set
2708 +# CONFIG_NET_FASTROUTE is not set
2709 +# CONFIG_NET_HW_FLOWCONTROL is not set
2710 +
2711 +#
2712 +# QoS and/or fair queueing
2713 +#
2714 +CONFIG_NET_SCHED=y
2715 +CONFIG_NET_SCH_CBQ=y
2716 +CONFIG_NET_SCH_HTB=y
2717 +# CONFIG_NET_SCH_CSZ is not set
2718 +CONFIG_NET_SCH_PRIO=y
2719 +# CONFIG_NET_SCH_RED is not set
2720 +CONFIG_NET_SCH_SFQ=y
2721 +# CONFIG_NET_SCH_TEQL is not set
2722 +# CONFIG_NET_SCH_TBF is not set
2723 +# CONFIG_NET_SCH_GRED is not set
2724 +# CONFIG_NET_SCH_DSMARK is not set
2725 +# CONFIG_NET_SCH_INGRESS is not set
2726 +CONFIG_NET_QOS=y
2727 +CONFIG_NET_ESTIMATOR=y
2728 +CONFIG_NET_CLS=y
2729 +# CONFIG_NET_CLS_TCINDEX is not set
2730 +# CONFIG_NET_CLS_ROUTE4 is not set
2731 +# CONFIG_NET_CLS_FW is not set
2732 +CONFIG_NET_CLS_U32=y
2733 +# CONFIG_NET_CLS_RSVP is not set
2734 +# CONFIG_NET_CLS_RSVP6 is not set
2735 +# CONFIG_NET_CLS_POLICE is not set
2736 +
2737 +#
2738 +# Network testing
2739 +#
2740 +# CONFIG_NET_PKTGEN is not set
2741 +
2742 +#
2743 +# Telephony Support
2744 +#
2745 +# CONFIG_PHONE is not set
2746 +# CONFIG_PHONE_IXJ is not set
2747 +# CONFIG_PHONE_IXJ_PCMCIA is not set
2748 +
2749 +#
2750 +# ATA/IDE/MFM/RLL support
2751 +#
2752 +# CONFIG_IDE is not set
2753 +# CONFIG_BLK_DEV_IDE_MODES is not set
2754 +# CONFIG_BLK_DEV_HD is not set
2755 +
2756 +#
2757 +# SCSI support
2758 +#
2759 +# CONFIG_SCSI is not set
2760 +
2761 +#
2762 +# I2O device support
2763 +#
2764 +# CONFIG_I2O is not set
2765 +# CONFIG_I2O_PCI is not set
2766 +# CONFIG_I2O_BLOCK is not set
2767 +# CONFIG_I2O_LAN is not set
2768 +# CONFIG_I2O_SCSI is not set
2769 +# CONFIG_I2O_PROC is not set
2770 +
2771 +#
2772 +# Network device support
2773 +#
2774 +CONFIG_NETDEVICES=y
2775 +
2776 +#
2777 +# Broadcom HND network devices
2778 +#
2779 +CONFIG_HND=y
2780 +# CONFIG_IL is not set
2781 +# CONFIG_IL_42XX is not set
2782 +# CONFIG_IL_47XX is not set
2783 +CONFIG_LARQ_BUF=0
2784 +CONFIG_ET=m
2785 +# CONFIG_ET_4413 is not set
2786 +CONFIG_ET_47XX=y
2787 +CONFIG_WL=m
2788 +CONFIG_WL_AP=y
2789 +CONFIG_WL_STA=y
2790 +# CONFIG_WL_OID is not set
2791 +
2792 +#
2793 +# ARCnet devices
2794 +#
2795 +# CONFIG_ARCNET is not set
2796 +# CONFIG_DUMMY is not set
2797 +# CONFIG_BONDING is not set
2798 +# CONFIG_EQUALIZER is not set
2799 +# CONFIG_TUN is not set
2800 +# CONFIG_ETHERTAP is not set
2801 +
2802 +#
2803 +# Ethernet (10 or 100Mbit)
2804 +#
2805 +CONFIG_NET_ETHERNET=y
2806 +# CONFIG_SUNLANCE is not set
2807 +# CONFIG_HAPPYMEAL is not set
2808 +# CONFIG_SUNBMAC is not set
2809 +# CONFIG_SUNQE is not set
2810 +# CONFIG_SUNGEM is not set
2811 +# CONFIG_NET_VENDOR_3COM is not set
2812 +# CONFIG_LANCE is not set
2813 +# CONFIG_NET_VENDOR_SMC is not set
2814 +# CONFIG_NET_VENDOR_RACAL is not set
2815 +# CONFIG_HP100 is not set
2816 +# CONFIG_NET_ISA is not set
2817 +# CONFIG_NET_PCI is not set
2818 +# CONFIG_NET_POCKET is not set
2819 +
2820 +#
2821 +# Ethernet (1000 Mbit)
2822 +#
2823 +# CONFIG_ACENIC is not set
2824 +# CONFIG_DL2K is not set
2825 +# CONFIG_E1000 is not set
2826 +# CONFIG_MYRI_SBUS is not set
2827 +# CONFIG_NS83820 is not set
2828 +# CONFIG_HAMACHI is not set
2829 +# CONFIG_YELLOWFIN is not set
2830 +# CONFIG_SK98LIN is not set
2831 +# CONFIG_TIGON3 is not set
2832 +# CONFIG_FDDI is not set
2833 +# CONFIG_HIPPI is not set
2834 +# CONFIG_PLIP is not set
2835 +CONFIG_PPP=y
2836 +# CONFIG_PPP_MULTILINK is not set
2837 +# CONFIG_PPP_FILTER is not set
2838 +CONFIG_PPP_ASYNC=y
2839 +CONFIG_PPP_SYNC_TTY=y
2840 +# CONFIG_PPP_DEFLATE is not set
2841 +# CONFIG_PPP_BSDCOMP is not set
2842 +CONFIG_PPPOE=y
2843 +# CONFIG_SLIP is not set
2844 +
2845 +#
2846 +# Wireless LAN (non-hamradio)
2847 +#
2848 +# CONFIG_NET_RADIO is not set
2849 +
2850 +#
2851 +# Token Ring devices
2852 +#
2853 +# CONFIG_TR is not set
2854 +# CONFIG_NET_FC is not set
2855 +# CONFIG_RCPCI is not set
2856 +# CONFIG_SHAPER is not set
2857 +
2858 +#
2859 +# Wan interfaces
2860 +#
2861 +# CONFIG_WAN is not set
2862 +
2863 +#
2864 +# Amateur Radio support
2865 +#
2866 +# CONFIG_HAMRADIO is not set
2867 +
2868 +#
2869 +# IrDA (infrared) support
2870 +#
2871 +# CONFIG_IRDA is not set
2872 +
2873 +#
2874 +# ISDN subsystem
2875 +#
2876 +# CONFIG_ISDN is not set
2877 +
2878 +#
2879 +# Input core support
2880 +#
2881 +# CONFIG_INPUT is not set
2882 +# CONFIG_INPUT_KEYBDEV is not set
2883 +# CONFIG_INPUT_MOUSEDEV is not set
2884 +# CONFIG_INPUT_JOYDEV is not set
2885 +# CONFIG_INPUT_EVDEV is not set
2886 +
2887 +#
2888 +# Character devices
2889 +#
2890 +# CONFIG_VT is not set
2891 +CONFIG_SERIAL=y
2892 +CONFIG_SERIAL_CONSOLE=y
2893 +# CONFIG_SERIAL_EXTENDED is not set
2894 +CONFIG_SERIAL_NONSTANDARD=y
2895 +# CONFIG_COMPUTONE is not set
2896 +# CONFIG_ROCKETPORT is not set
2897 +# CONFIG_CYCLADES is not set
2898 +# CONFIG_DIGIEPCA is not set
2899 +# CONFIG_DIGI is not set
2900 +# CONFIG_ESPSERIAL is not set
2901 +# CONFIG_MOXA_INTELLIO is not set
2902 +# CONFIG_MOXA_SMARTIO is not set
2903 +# CONFIG_ISI is not set
2904 +# CONFIG_SYNCLINK is not set
2905 +# CONFIG_SYNCLINKMP is not set
2906 +CONFIG_N_HDLC=y
2907 +# CONFIG_RISCOM8 is not set
2908 +# CONFIG_SPECIALIX is not set
2909 +# CONFIG_SX is not set
2910 +# CONFIG_RIO is not set
2911 +# CONFIG_STALDRV is not set
2912 +# CONFIG_SERIAL_TX3912 is not set
2913 +# CONFIG_SERIAL_TX3912_CONSOLE is not set
2914 +# CONFIG_TXX927_SERIAL is not set
2915 +CONFIG_UNIX98_PTYS=y
2916 +CONFIG_UNIX98_PTY_COUNT=16
2917 +
2918 +#
2919 +# I2C support
2920 +#
2921 +# CONFIG_I2C is not set
2922 +
2923 +#
2924 +# Mice
2925 +#
2926 +# CONFIG_BUSMOUSE is not set
2927 +# CONFIG_MOUSE is not set
2928 +
2929 +#
2930 +# Joysticks
2931 +#
2932 +# CONFIG_INPUT_GAMEPORT is not set
2933 +
2934 +#
2935 +# Input core support is needed for gameports
2936 +#
2937 +
2938 +#
2939 +# Input core support is needed for joysticks
2940 +#
2941 +# CONFIG_QIC02_TAPE is not set
2942 +
2943 +#
2944 +# Watchdog Cards
2945 +#
2946 +# CONFIG_WATCHDOG is not set
2947 +# CONFIG_AMD_PM768 is not set
2948 +# CONFIG_NVRAM is not set
2949 +# CONFIG_RTC is not set
2950 +# CONFIG_DTLK is not set
2951 +# CONFIG_R3964 is not set
2952 +# CONFIG_APPLICOM is not set
2953 +
2954 +#
2955 +# Ftape, the floppy tape device driver
2956 +#
2957 +# CONFIG_FTAPE is not set
2958 +# CONFIG_AGP is not set
2959 +# CONFIG_DRM is not set
2960 +
2961 +#
2962 +# File systems
2963 +#
2964 +# CONFIG_QUOTA is not set
2965 +# CONFIG_AUTOFS_FS is not set
2966 +# CONFIG_AUTOFS4_FS is not set
2967 +# CONFIG_REISERFS_FS is not set
2968 +# CONFIG_REISERFS_CHECK is not set
2969 +# CONFIG_REISERFS_PROC_INFO is not set
2970 +# CONFIG_ADFS_FS is not set
2971 +# CONFIG_ADFS_FS_RW is not set
2972 +# CONFIG_AFFS_FS is not set
2973 +# CONFIG_HFS_FS is not set
2974 +# CONFIG_BEFS_FS is not set
2975 +# CONFIG_BEFS_DEBUG is not set
2976 +# CONFIG_BFS_FS is not set
2977 +# CONFIG_EXT3_FS is not set
2978 +# CONFIG_JBD is not set
2979 +# CONFIG_JBD_DEBUG is not set
2980 +# CONFIG_FAT_FS is not set
2981 +# CONFIG_MSDOS_FS is not set
2982 +# CONFIG_UMSDOS_FS is not set
2983 +# CONFIG_VFAT_FS is not set
2984 +# CONFIG_EFS_FS is not set
2985 +# CONFIG_JFFS_FS is not set
2986 +# CONFIG_JFFS2_FS is not set
2987 +CONFIG_CRAMFS=y
2988 +# CONFIG_TMPFS is not set
2989 +CONFIG_RAMFS=y
2990 +# CONFIG_ISO9660_FS is not set
2991 +# CONFIG_JOLIET is not set
2992 +# CONFIG_ZISOFS is not set
2993 +# CONFIG_JFS_FS is not set
2994 +# CONFIG_JFS_DEBUG is not set
2995 +# CONFIG_JFS_STATISTICS is not set
2996 +# CONFIG_MINIX_FS is not set
2997 +# CONFIG_VXFS_FS is not set
2998 +# CONFIG_NTFS_FS is not set
2999 +# CONFIG_NTFS_RW is not set
3000 +# CONFIG_HPFS_FS is not set
3001 +CONFIG_PROC_FS=y
3002 +CONFIG_DEVFS_FS=y
3003 +CONFIG_DEVFS_MOUNT=y
3004 +# CONFIG_DEVFS_DEBUG is not set
3005 +# CONFIG_DEVPTS_FS is not set
3006 +# CONFIG_QNX4FS_FS is not set
3007 +# CONFIG_QNX4FS_RW is not set
3008 +# CONFIG_ROMFS_FS is not set
3009 +# CONFIG_EXT2_FS is not set
3010 +# CONFIG_SYSV_FS is not set
3011 +# CONFIG_UDF_FS is not set
3012 +# CONFIG_UDF_RW is not set
3013 +# CONFIG_UFS_FS is not set
3014 +# CONFIG_UFS_FS_WRITE is not set
3015 +
3016 +#
3017 +# Network File Systems
3018 +#
3019 +# CONFIG_CODA_FS is not set
3020 +# CONFIG_INTERMEZZO_FS is not set
3021 +# CONFIG_NFS_FS is not set
3022 +# CONFIG_NFS_V3 is not set
3023 +# CONFIG_ROOT_NFS is not set
3024 +# CONFIG_NFSD is not set
3025 +# CONFIG_NFSD_V3 is not set
3026 +# CONFIG_NFSD_TCP is not set
3027 +# CONFIG_SUNRPC is not set
3028 +# CONFIG_LOCKD is not set
3029 +# CONFIG_SMB_FS is not set
3030 +# CONFIG_NCP_FS is not set
3031 +# CONFIG_NCPFS_PACKET_SIGNING is not set
3032 +# CONFIG_NCPFS_IOCTL_LOCKING is not set
3033 +# CONFIG_NCPFS_STRONG is not set
3034 +# CONFIG_NCPFS_NFS_NS is not set
3035 +# CONFIG_NCPFS_OS2_NS is not set
3036 +# CONFIG_NCPFS_SMALLDOS is not set
3037 +# CONFIG_NCPFS_NLS is not set
3038 +# CONFIG_NCPFS_EXTRAS is not set
3039 +# CONFIG_ZISOFS_FS is not set
3040 +
3041 +#
3042 +# Partition Types
3043 +#
3044 +CONFIG_PARTITION_ADVANCED=y
3045 +# CONFIG_ACORN_PARTITION is not set
3046 +# CONFIG_OSF_PARTITION is not set
3047 +# CONFIG_AMIGA_PARTITION is not set
3048 +# CONFIG_ATARI_PARTITION is not set
3049 +# CONFIG_MAC_PARTITION is not set
3050 +# CONFIG_MSDOS_PARTITION is not set
3051 +# CONFIG_LDM_PARTITION is not set
3052 +# CONFIG_SGI_PARTITION is not set
3053 +# CONFIG_ULTRIX_PARTITION is not set
3054 +# CONFIG_SUN_PARTITION is not set
3055 +# CONFIG_EFI_PARTITION is not set
3056 +# CONFIG_SMB_NLS is not set
3057 +# CONFIG_NLS is not set
3058 +
3059 +#
3060 +# Multimedia devices
3061 +#
3062 +# CONFIG_VIDEO_DEV is not set
3063 +
3064 +#
3065 +# Sound
3066 +#
3067 +# CONFIG_SOUND is not set
3068 +
3069 +#
3070 +# USB support
3071 +#
3072 +# CONFIG_USB is not set
3073 +
3074 +#
3075 +# Support for USB gadgets
3076 +#
3077 +# CONFIG_USB_GADGET is not set
3078 +
3079 +#
3080 +# Bluetooth support
3081 +#
3082 +# CONFIG_BLUEZ is not set
3083 +
3084 +#
3085 +# Kernel hacking
3086 +#
3087 +CONFIG_CROSSCOMPILE=y
3088 +# CONFIG_KERNPROF is not set
3089 +# CONFIG_MCOUNT is not set
3090 +# CONFIG_DEBUG is not set
3091 +CONFIG_MAGIC_SYSRQ=y
3092 +# CONFIG_MIPS_UNCACHED is not set
3093 +# CONFIG_KTRACE is not set
3094 +# CONFIG_HWSIM is not set
3095 +
3096 +#
3097 +# Library routines
3098 +#
3099 +CONFIG_ZLIB_INFLATE=y
3100 +# CONFIG_ZLIB_DEFLATE is not set
3101 --- linux-2.4.20/arch/mips/kernel/cpu-probe.c~2.4.20_broadcom_3_37_2_1109_US.patch      2005-01-07 05:39:01.000000000 -0500
3102 +++ linux-2.4.20/arch/mips/kernel/cpu-probe.c   2005-01-07 05:39:02.000000000 -0500
3103 @@ -158,6 +158,16 @@
3104         unsigned long config0 = read_c0_config();
3105         unsigned long config1;
3106  
3107 +       if ((config0 & CONF_BE) !=
3108 +#ifdef CONFIG_CPU_LITTLE_ENDIAN
3109 +                               0
3110 +#else
3111 +                               CONF_BE
3112 +#endif
3113 +               ) {
3114 +               panic("Kernel compiled little-endian, but running on a big-endian cpu");
3115 +       }
3116 +
3117          if (config0 & (1 << 31)) {
3118                 /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */
3119                 mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
3120 @@ -179,9 +189,9 @@
3121         }
3122  #endif
3123         mips_cpu.processor_id = read_c0_prid();
3124 -       switch (mips_cpu.processor_id & 0xff0000) {
3125 +       switch (mips_cpu.processor_id & PRID_COMP_MASK) {
3126         case PRID_COMP_LEGACY:
3127 -               switch (mips_cpu.processor_id & 0xff00) {
3128 +               switch (mips_cpu.processor_id & PRID_IMP_MASK) {
3129                 case PRID_IMP_R2000:
3130                         mips_cpu.cputype = CPU_R2000;
3131                         mips_cpu.isa_level = MIPS_CPU_ISA_I;
3132 @@ -191,7 +201,7 @@
3133                         mips_cpu.tlbsize = 64;
3134                         break;
3135                 case PRID_IMP_R3000:
3136 -                       if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A)
3137 +                       if ((mips_cpu.processor_id & PRID_REV_MASK) == PRID_REV_R3000A)
3138                                 if (cpu_has_confreg())
3139                                         mips_cpu.cputype = CPU_R3081E;
3140                                 else
3141 @@ -205,7 +215,7 @@
3142                         mips_cpu.tlbsize = 64;
3143                         break;
3144                 case PRID_IMP_R4000:
3145 -                       if ((mips_cpu.processor_id & 0xff) >= PRID_REV_R4400)
3146 +                       if ((mips_cpu.processor_id & PRID_REV_MASK) >= PRID_REV_R4400)
3147                                 mips_cpu.cputype = CPU_R4400SC;
3148                         else
3149                                 mips_cpu.cputype = CPU_R4000SC;
3150 @@ -287,7 +297,7 @@
3151                                 mips_cpu.icache.ways = 2;
3152                                 mips_cpu.dcache.ways = 2;
3153                         } else {
3154 -                               switch (mips_cpu.processor_id & 0xff) {
3155 +                               switch (mips_cpu.processor_id & PRID_REV_MASK) {
3156                                 case PRID_REV_TX3912:
3157                                         mips_cpu.cputype = CPU_TX3912;
3158                                         mips_cpu.tlbsize = 32;
3159 @@ -405,7 +415,7 @@
3160                 break;
3161  #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
3162         case PRID_COMP_MIPS:
3163 -               switch (mips_cpu.processor_id & 0xff00) {
3164 +               switch (mips_cpu.processor_id & PRID_IMP_MASK) {
3165                 case PRID_IMP_4KC:
3166                         mips_cpu.cputype = CPU_4KC;
3167                         mips_cpu.isa_level = MIPS_CPU_ISA_M32;
3168 @@ -432,10 +442,10 @@
3169                 }
3170                 break;
3171         case PRID_COMP_ALCHEMY:
3172 -               switch (mips_cpu.processor_id & 0xff00) {
3173 +               switch (mips_cpu.processor_id & PRID_IMP_MASK) {
3174                 case PRID_IMP_AU1_REV1:
3175                 case PRID_IMP_AU1_REV2:
3176 -                       switch ((mips_cpu.processor_id >> 24) & 0xff) {
3177 +                       switch ((mips_cpu.processor_id >> 24) & PRID_REV_MASK) {
3178                         case 0:
3179                                 mips_cpu.cputype = CPU_AU1000;
3180                                 break;
3181 @@ -456,9 +466,43 @@
3182                         break;
3183                 }
3184                 break;
3185 +        case PRID_COMP_BROADCOM:
3186 +                switch (mips_cpu.processor_id & PRID_IMP_MASK) {
3187 +                case PRID_IMP_BCM4710:          
3188 +                        mips_cpu.cputype = CPU_BCM4710;
3189 +                        mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
3190 +                                           MIPS_CPU_4KTLB | MIPS_CPU_COUNTER;
3191 +                        config1 = read_c0_config1();
3192 +                        if (config1 & (1 << 3))
3193 +                                mips_cpu.options |= MIPS_CPU_WATCH;
3194 +                        if (config1 & (1 << 2))
3195 +                                mips_cpu.options |= MIPS_CPU_MIPS16;
3196 +                        if (config1 & 1)
3197 +                                mips_cpu.options |= MIPS_CPU_FPU;
3198 +                        mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
3199 +                        break;
3200 +               case PRID_IMP_4KC:              
3201 +               case PRID_IMP_BCM3302:          
3202 +                       mips_cpu.cputype = CPU_BCM3302;
3203 +                       mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
3204 +                                          MIPS_CPU_4KTLB | MIPS_CPU_COUNTER;
3205 +                       config1 = read_c0_config1();
3206 +                       if (config1 & (1 << 3))
3207 +                               mips_cpu.options |= MIPS_CPU_WATCH;
3208 +                       if (config1 & (1 << 2))
3209 +                               mips_cpu.options |= MIPS_CPU_MIPS16;
3210 +                       if (config1 & 1)
3211 +                               mips_cpu.options |= MIPS_CPU_FPU;
3212 +                       mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
3213 +                       break;
3214 +                default:
3215 +                        mips_cpu.cputype = CPU_UNKNOWN;
3216 +                        break;
3217 +                }
3218 +                break;
3219  #endif /* CONFIG_CPU_MIPS32 */
3220         case PRID_COMP_SIBYTE:
3221 -               switch (mips_cpu.processor_id & 0xff00) {
3222 +               switch (mips_cpu.processor_id & PRID_IMP_MASK) {
3223                 case PRID_IMP_SB1:
3224                         mips_cpu.cputype = CPU_SB1;
3225                         mips_cpu.isa_level = MIPS_CPU_ISA_M64;
3226 --- linux-2.4.20/arch/mips/kernel/entry.S~2.4.20_broadcom_3_37_2_1109_US.patch  2005-01-07 05:39:01.000000000 -0500
3227 +++ linux-2.4.20/arch/mips/kernel/entry.S       2005-01-07 05:39:02.000000000 -0500
3228 @@ -100,6 +100,10 @@
3229                  * and R4400 SC and MC versions.
3230                  */
3231  NESTED(except_vec3_generic, 0, sp)
3232 +#ifdef CONFIG_BCM4710
3233 +               nop
3234 +               nop
3235 +#endif          
3236                 mfc0    k1, CP0_CAUSE
3237                 la      k0, exception_handlers
3238                 andi    k1, k1, 0x7c
3239 --- linux-2.4.20/arch/mips/kernel/head.S~2.4.20_broadcom_3_37_2_1109_US.patch   2005-01-07 05:39:01.000000000 -0500
3240 +++ linux-2.4.20/arch/mips/kernel/head.S        2005-01-07 05:39:02.000000000 -0500
3241 @@ -28,12 +28,20 @@
3242  #include <asm/mipsregs.h>
3243  #include <asm/stackframe.h>
3244  
3245 +#ifdef CONFIG_BCM4710
3246 +#undef eret
3247 +#define eret nop; nop; eret
3248 +#endif
3249 +
3250                 .text
3251 +               j       kernel_entry
3252 +               nop
3253 +
3254                 /*
3255                  * Reserved space for exception handlers.
3256                  * Necessary for machines which link their kernels at KSEG0.
3257                  */
3258 -               .fill   0x400
3259 +               .fill   0x3f4
3260  
3261                 /* The following two symbols are used for kernel profiling. */
3262                 EXPORT(stext)
3263 --- linux-2.4.20/arch/mips/kernel/proc.c~2.4.20_broadcom_3_37_2_1109_US.patch   2005-01-07 05:39:01.000000000 -0500
3264 +++ linux-2.4.20/arch/mips/kernel/proc.c        2005-01-07 05:39:02.000000000 -0500
3265 @@ -73,9 +73,12 @@
3266         [CPU_VR4122]    "NEC VR4122",
3267         [CPU_VR4131]    "NEC VR4131",
3268         [CPU_VR4181]    "NEC VR4181",
3269 -       [CPU_VR4181A]   "NEC VR4181A"
3270 +       [CPU_VR4181A]   "NEC VR4181A",
3271 +       [CPU_BCM4710]   "BCM4710",
3272 +       [CPU_BCM3302]   "BCM3302",
3273  };
3274  
3275 +extern unsigned long unaligned_instructions;
3276  
3277  static int show_cpuinfo(struct seq_file *m, void *v)
3278  {
3279 @@ -124,6 +127,21 @@
3280         seq_printf(m, "sc emulations\t\t: %lu\n", sc_ops);
3281  #endif
3282  
3283 +       seq_printf(m, "unaligned_instructions\t: %u\n", unaligned_instructions);
3284 +
3285 +#if defined(CONFIG_BCM4710) || defined(CONFIG_BCM4310)
3286 +       seq_printf(m, "dcache hits\t\t: %u\n",
3287 +                  read_perf_cntr(0));
3288 +       seq_printf(m, "dcache misses\t\t: %u\n",
3289 +                  read_perf_cntr(1));
3290 +       seq_printf(m, "icache hits\t\t: %u\n",
3291 +                  read_perf_cntr(2));
3292 +       seq_printf(m, "icache misses\t\t: %u\n",
3293 +                  read_perf_cntr(3));
3294 +       seq_printf(m, "instructions\t\t: %u\n",
3295 +                  read_perf_cntr(4));
3296 +#endif
3297 +
3298         return 0;
3299  }
3300  
3301 --- linux-2.4.20/arch/mips/kernel/setup.c~2.4.20_broadcom_3_37_2_1109_US.patch  2005-01-07 05:39:01.000000000 -0500
3302 +++ linux-2.4.20/arch/mips/kernel/setup.c       2005-01-07 05:39:02.000000000 -0500
3303 @@ -490,12 +490,12 @@
3304         void victor_mpc30x_setup(void);
3305         void ibm_workpad_setup(void);
3306         void casio_e55_setup(void);
3307 -       void tanbac_tb0226_setup(void);
3308         void jmr3927_setup(void);
3309         void it8172_setup(void);
3310         void swarm_setup(void);
3311         void hp_setup(void);
3312         void au1x00_setup(void);
3313 +       void brcm_setup(void);
3314  
3315  #ifdef CONFIG_BLK_DEV_FD
3316         fd_ops = &no_fd_ops;
3317 @@ -671,6 +671,9 @@
3318                  hp_setup();
3319                  break;
3320  #endif
3321 +       case MACH_GROUP_BRCM:
3322 +               brcm_setup();
3323 +               break;
3324         default:
3325                 panic("Unsupported architecture");
3326         }
3327 --- linux-2.4.20/arch/mips/kernel/traps.c~2.4.20_broadcom_3_37_2_1109_US.patch  2005-01-07 05:39:01.000000000 -0500
3328 +++ linux-2.4.20/arch/mips/kernel/traps.c       2005-01-07 05:39:02.000000000 -0500
3329 @@ -405,17 +405,12 @@
3330                  unsigned long value)
3331  {
3332         const struct exception_table_entry *mid;
3333 -       long diff;
3334  
3335 -       while (first < last) {
3336 -               mid = (last - first) / 2 + first;
3337 -               diff = mid->insn - value;
3338 -               if (diff < 0)
3339 -                       first = mid + 1;
3340 -               else
3341 -                       last = mid;
3342 +       for (mid = first; mid <= last; mid++) {
3343 +               if (mid->insn == value)
3344 +                       return mid->nextinsn;
3345         }
3346 -       return (first == last && first->insn == value) ? first->nextinsn : 0;
3347 +       return 0;
3348  }
3349  
3350  extern spinlock_t modlist_lock;
3351 @@ -918,7 +913,7 @@
3352  
3353  void __init trap_init(void)
3354  {
3355 -       extern char except_vec1_generic;
3356 +       extern char except_vec1_generic, except_vec2_generic;
3357         extern char except_vec3_generic, except_vec3_r4000;
3358         extern char except_vec_ejtag_debug;
3359         extern char except_vec4;
3360 @@ -928,6 +923,7 @@
3361  
3362         /* Copy the generic exception handler code to it's final destination. */
3363         memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80);
3364 +       memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
3365  
3366         /*
3367          * Setup default vectors
3368 @@ -1014,6 +1010,12 @@
3369                 //set_except_vector(15, handle_ndc);
3370         }
3371  
3372 +       if (mips_cpu.cputype == CPU_SB1) {
3373 +               /* Enable timer interrupt and scd mapped interrupt */
3374 +               clear_c0_status(0xf000);
3375 +               set_c0_status(0xc00);
3376 +       }
3377 +
3378         if (mips_cpu.options & MIPS_CPU_FPU) {
3379                 save_fp_context = _save_fp_context;
3380                 restore_fp_context = _restore_fp_context;
3381 --- linux-2.4.20/arch/mips/kernel/unaligned.c~2.4.20_broadcom_3_37_2_1109_US.patch      2005-01-07 05:39:01.000000000 -0500
3382 +++ linux-2.4.20/arch/mips/kernel/unaligned.c   2005-01-07 05:39:02.000000000 -0500
3383 @@ -145,7 +145,7 @@
3384                 if (verify_area(VERIFY_READ, addr, 2))
3385                         goto sigbus;
3386  
3387 -               __asm__ __volatile__ (".set\tnoat\n"
3388 +               __asm__(".set\tnoat\n"
3389  #ifdef __BIG_ENDIAN
3390                         "1:\tlb\t%0, 0(%2)\n"
3391                         "2:\tlbu\t$1, 1(%2)\n\t"
3392 @@ -178,7 +178,7 @@
3393                 if (verify_area(VERIFY_READ, addr, 4))
3394                         goto sigbus;
3395  
3396 -               __asm__ __volatile__ (
3397 +               __asm__(
3398  #ifdef __BIG_ENDIAN
3399                         "1:\tlwl\t%0, (%2)\n"
3400                         "2:\tlwr\t%0, 3(%2)\n\t"
3401 @@ -208,7 +208,7 @@
3402                 if (verify_area(VERIFY_READ, addr, 2))
3403                         goto sigbus;
3404  
3405 -               __asm__ __volatile__ (
3406 +               __asm__(
3407                         ".set\tnoat\n"
3408  #ifdef __BIG_ENDIAN
3409                         "1:\tlbu\t%0, 0(%2)\n"
3410 @@ -250,7 +250,7 @@
3411                 if (verify_area(VERIFY_READ, addr, 4))
3412                         goto sigbus;
3413  
3414 -               __asm__ __volatile__ (
3415 +               __asm__(
3416  #ifdef __BIG_ENDIAN
3417                         "1:\tlwl\t%0, (%2)\n"
3418                         "2:\tlwr\t%0, 3(%2)\n\t"
3419 @@ -294,7 +294,7 @@
3420                 if (verify_area(VERIFY_READ, addr, 8))
3421                         goto sigbus;
3422  
3423 -               __asm__ __volatile__ (
3424 +               __asm__(
3425  #ifdef __BIG_ENDIAN
3426                         "1:\tldl\t%0, (%2)\n"
3427                         "2:\tldr\t%0, 7(%2)\n\t"
3428 @@ -329,7 +329,7 @@
3429                         goto sigbus;
3430  
3431                 value = regs->regs[insn.i_format.rt];
3432 -               __asm__ __volatile__ (
3433 +               __asm__(
3434  #ifdef __BIG_ENDIAN
3435                         ".set\tnoat\n"
3436                         "1:\tsb\t%1, 1(%2)\n\t"
3437 @@ -365,7 +365,7 @@
3438                         goto sigbus;
3439  
3440                 value = regs->regs[insn.i_format.rt];
3441 -               __asm__ __volatile__ (
3442 +               __asm__(
3443  #ifdef __BIG_ENDIAN
3444                         "1:\tswl\t%1,(%2)\n"
3445                         "2:\tswr\t%1, 3(%2)\n\t"
3446 @@ -403,7 +403,7 @@
3447                         goto sigbus;
3448  
3449                 value = regs->regs[insn.i_format.rt];
3450 -               __asm__ __volatile__ (
3451 +               __asm__(
3452  #ifdef __BIG_ENDIAN
3453                         "1:\tsdl\t%1,(%2)\n"
3454                         "2:\tsdr\t%1, 7(%2)\n\t"
3455 --- linux-2.4.20/arch/mips/mm/Makefile~2.4.20_broadcom_3_37_2_1109_US.patch     2005-01-07 05:39:01.000000000 -0500
3456 +++ linux-2.4.20/arch/mips/mm/Makefile  2005-01-07 05:39:02.000000000 -0500
3457 @@ -28,6 +28,7 @@
3458  obj-$(CONFIG_CPU_MIPS32)       += pg-mips32.o c-mips32.o tlb-r4k.o tlbex-r4k.o
3459  obj-$(CONFIG_CPU_MIPS64)       += pg-mips32.o c-mips32.o tlb-r4k.o tlbex-r4k.o
3460  obj-$(CONFIG_CPU_SB1)          += pg-sb1.o c-sb1.o tlb-sb1.o tlbex-r4k.o cex-sb1.o cerr-sb1.o
3461 +obj-$(CONFIG_BCM4710)          += c-bcm4710.o
3462  
3463  obj-$(CONFIG_R5000_CPU_SCACHE) += r5k-sc.o
3464  
3465 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
3466 +++ linux-2.4.20/arch/mips/mm/c-bcm4710.c       2005-01-07 05:39:02.000000000 -0500
3467 @@ -0,0 +1,392 @@
3468 +/*
3469 + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
3470 + * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
3471 + *
3472 + * This program is free software; you can distribute it and/or modify it
3473 + * under the terms of the GNU General Public License (Version 2) as
3474 + * published by the Free Software Foundation.
3475 + *
3476 + * This program is distributed in the hope it will be useful, but WITHOUT
3477 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3478 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
3479 + * for more details.
3480 + *
3481 + * You should have received a copy of the GNU General Public License along
3482 + * with this program; if not, write to the Free Software Foundation, Inc.,
3483 + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
3484 + *
3485 + * MIPS32 CPU variant specific MMU/Cache routines.
3486 + */
3487 +#include <linux/config.h>
3488 +#include <linux/init.h>
3489 +#include <linux/kernel.h>
3490 +#include <linux/sched.h>
3491 +#include <linux/mm.h>
3492 +
3493 +#include <asm/bootinfo.h>
3494 +#include <asm/cpu.h>
3495 +#include <asm/bcache.h>
3496 +#include <asm/io.h>
3497 +#include <asm/page.h>
3498 +#include <asm/pgtable.h>
3499 +#include <asm/system.h>
3500 +#include <asm/mmu_context.h>
3501 +
3502 +/* CP0 hazard avoidance. */
3503 +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
3504 +                                    "nop; nop; nop; nop; nop; nop;\n\t" \
3505 +                                    ".set reorder\n\t")
3506 +
3507 +/* Primary cache parameters. */
3508 +extern int icache_size, dcache_size;                   /* Size in bytes */
3509 +extern int ic_lsize, dc_lsize;                         /* LineSize in bytes */
3510 +
3511 +#include <asm/cacheops.h>
3512 +#include <asm/bcm4710_cache.h>
3513 +
3514 +#undef DEBUG_CACHE
3515 +
3516 +static inline void mips32_flush_cache_all_pc(void)
3517 +{
3518 +       unsigned long flags;
3519 +
3520 +       local_irq_save(flags);
3521 +       blast_dcache(); blast_icache();
3522 +       local_irq_restore(flags);
3523 +}
3524 +
3525 +static void mips32_flush_cache_range_pc(struct mm_struct *mm,
3526 +                                    unsigned long start,
3527 +                                    unsigned long end)
3528 +{
3529 +       if(mm->context != 0) {
3530 +               unsigned long flags;
3531 +
3532 +#ifdef DEBUG_CACHE
3533 +               printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
3534 +#endif
3535 +               local_irq_save(flags);
3536 +               blast_dcache(); blast_icache();
3537 +               local_irq_restore(flags);
3538 +       }
3539 +}
3540 +
3541 +/*
3542 + * On architectures like the Sparc, we could get rid of lines in
3543 + * the cache created only by a certain context, but on the MIPS
3544 + * (and actually certain Sparc's) we cannot.
3545 + */
3546 +static void mips32_flush_cache_mm_pc(struct mm_struct *mm)
3547 +{
3548 +       if(mm->context != 0) {
3549 +#ifdef DEBUG_CACHE
3550 +               printk("cmm[%d]", (int)mm->context);
3551 +#endif
3552 +               mips32_flush_cache_all_pc();
3553 +       }
3554 +}
3555 +
3556 +static void mips32_flush_cache_page_pc(struct vm_area_struct *vma,
3557 +                                   unsigned long page)
3558 +{
3559 +       struct mm_struct *mm = vma->vm_mm;
3560 +       pgd_t *pgdp;
3561 +       pmd_t *pmdp;
3562 +       pte_t *ptep;
3563 +
3564 +       /*
3565 +        * If ownes no valid ASID yet, cannot possibly have gotten
3566 +        * this page into the cache.
3567 +        */
3568 +       if (mm->context == 0)
3569 +               return;
3570 +
3571 +#ifdef DEBUG_CACHE
3572 +       printk("cpage[%d,%08lx]", (int)mm->context, page);
3573 +#endif
3574 +       page &= PAGE_MASK;
3575 +       pgdp = pgd_offset(mm, page);
3576 +       pmdp = pmd_offset(pgdp, page);
3577 +       ptep = pte_offset(pmdp, page);
3578 +
3579 +       /*
3580 +        * If the page isn't marked valid, the page cannot possibly be
3581 +        * in the cache.
3582 +        */
3583 +       if (!(pte_val(*ptep) & _PAGE_VALID))
3584 +               return;
3585 +
3586 +       /*
3587 +        * Doing flushes for another ASID than the current one is
3588 +        * too difficult since Mips32 caches do a TLB translation
3589 +        * for every cache flush operation.  So we do indexed flushes
3590 +        * in that case, which doesn't overly flush the cache too much.
3591 +        */
3592 +       if (mm == current->active_mm) {
3593 +               blast_dcache_page(page);
3594 +       } else {
3595 +               /* Do indexed flush, too much work to get the (possible)
3596 +                * tlb refills to work correctly.
3597 +                */
3598 +               page = (KSEG0 + (page & (dcache_size - 1)));
3599 +               blast_dcache_page_indexed(page);
3600 +       }
3601 +}
3602 +
3603 +/* If the addresses passed to these routines are valid, they are
3604 + * either:
3605 + *
3606 + * 1) In KSEG0, so we can do a direct flush of the page.
3607 + * 2) In KSEG2, and since every process can translate those
3608 + *    addresses all the time in kernel mode we can do a direct
3609 + *    flush.
3610 + * 3) In KSEG1, no flush necessary.
3611 + */
3612 +static void mips32_flush_page_to_ram_pc(struct page *page)
3613 +{
3614 +       blast_dcache_page((unsigned long)page_address(page));
3615 +}
3616 +
3617 +static void
3618 +mips32_flush_icache_range(unsigned long start, unsigned long end)
3619 +{
3620 +       flush_cache_all();
3621 +}
3622 +
3623 +static void
3624 +mips32_flush_icache_page(struct vm_area_struct *vma, struct page *page)
3625 +{
3626 +       /*
3627 +        * If there's no context yet, or the page isn't executable, no icache 
3628 +        * flush is needed.
3629 +        */
3630 +       if (!(vma->vm_flags & VM_EXEC))
3631 +               return;
3632 +
3633 +       /*
3634 +        * We're not sure of the virtual address(es) involved here, so
3635 +        * conservatively flush the entire caches.
3636 +        */
3637 +       flush_cache_all();
3638 +}
3639 +
3640 +/*
3641 + * Writeback and invalidate the primary cache dcache before DMA.
3642 + */
3643 +static void
3644 +mips32_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
3645 +{
3646 +       unsigned long end, a;
3647 +       unsigned long flags;
3648 +
3649 +       if (size >= dcache_size) {
3650 +               blast_dcache();
3651 +       } else if (size) {
3652 +               local_irq_save(flags);
3653 +               a = addr & ~(dc_lsize - 1);
3654 +               end = (addr + size - 1) & ~(dc_lsize - 1);
3655 +               BCM4710_FILL_TLB(a);
3656 +               BCM4710_FILL_TLB(end);
3657 +               while (1) {
3658 +                       flush_dcache_line(a); /* Hit_Writeback_Inv_D */
3659 +                       if (a == end) break;
3660 +                       a += dc_lsize;
3661 +               }
3662 +               local_irq_restore(flags);
3663 +       }
3664 +       bc_wback_inv(addr, size);
3665 +}
3666 +
3667 +static void
3668 +mips32_dma_cache_inv_pc(unsigned long addr, unsigned long size)
3669 +{
3670 +       unsigned long end, a;
3671 +       unsigned long flags;
3672 +
3673 +       if (size >= dcache_size) {
3674 +               blast_dcache();
3675 +       } else if (size) {
3676 +               local_irq_save(flags);
3677 +               a = addr & ~(dc_lsize - 1);
3678 +               end = (addr + size - 1) & ~(dc_lsize - 1);
3679 +               BCM4710_FILL_TLB(a);
3680 +               BCM4710_FILL_TLB(end);
3681 +               while (1) {
3682 +                       invalidate_dcache_line(a); /* Hit_Inv_D */
3683 +                       if (a == end) break;
3684 +                       a += dc_lsize;
3685 +               }
3686 +               local_irq_restore(flags);
3687 +       }
3688 +
3689 +       bc_inv(addr, size);
3690 +}
3691 +
3692 +static void
3693 +mips32_dma_cache_wback(unsigned long addr, unsigned long size)
3694 +{
3695 +       panic("mips32_dma_cache called - should not happen.");
3696 +}
3697 +
3698 +/*
3699 + * While we're protected against bad userland addresses we don't care
3700 + * very much about what happens in that case.  Usually a segmentation
3701 + * fault will dump the process later on anyway ...
3702 + */
3703 +static void mips32_flush_cache_sigtramp(unsigned long addr)
3704 +{
3705 +       BCM4710_PROTECTED_FILL_TLB(addr);
3706 +       BCM4710_PROTECTED_FILL_TLB(addr + 4);
3707 +       protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
3708 +       protected_flush_icache_line(addr & ~(ic_lsize - 1));
3709 +}
3710 +
3711 +static void mips32_flush_icache_all(void)
3712 +{
3713 +       if (mips_cpu.icache.flags | MIPS_CACHE_VTAG_CACHE) {
3714 +               blast_icache();
3715 +       }
3716 +}
3717 +
3718 +/* Detect and size the various caches. */
3719 +static void __init probe_icache(unsigned long config)
3720 +{
3721 +        unsigned long config1;
3722 +       unsigned int lsize;
3723 +
3724 +       mips_cpu.icache.flags = 0;
3725 +        if (!(config & (1 << 31))) {
3726 +               /*
3727 +                * Not a MIPS32 complainant CPU.
3728 +                * Config 1 register not supported, we assume R4k style.
3729 +                */
3730 +               icache_size = 1 << (12 + ((config >> 9) & 7));
3731 +               ic_lsize = 16 << ((config >> 5) & 1);
3732 +               mips_cpu.icache.linesz = ic_lsize;
3733 +
3734 +               /*
3735 +                * We cannot infer associativity - assume direct map
3736 +                * unless probe template indicates otherwise
3737 +                */
3738 +               if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1;
3739 +               mips_cpu.icache.sets =
3740 +                       (icache_size / ic_lsize) / mips_cpu.icache.ways;
3741 +       } else {
3742 +              config1 = read_c0_config1();
3743 +
3744 +              if ((lsize = ((config1 >> 19) & 7)))
3745 +                      mips_cpu.icache.linesz = 2 << lsize;
3746 +              else
3747 +                      mips_cpu.icache.linesz = lsize;
3748 +              mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7);
3749 +              mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7);
3750 +
3751 +              ic_lsize = mips_cpu.icache.linesz;
3752 +              icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways *
3753 +                            ic_lsize;
3754 +
3755 +              if ((config & 0x8) || (mips_cpu.cputype == CPU_20KC)) {
3756 +                      /* 
3757 +                       * The CPU has a virtually tagged I-cache.
3758 +                       * Some older 20Kc chips doesn't have the 'VI' bit in
3759 +                       * the config register, so we also check for 20Kc.
3760 +                       */
3761 +                      mips_cpu.icache.flags = MIPS_CACHE_VTAG_CACHE;
3762 +                      printk("Virtually tagged I-cache detected\n");
3763 +              }
3764 +       }
3765 +       printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n",
3766 +              icache_size >> 10, ic_lsize, mips_cpu.icache.ways);
3767 +}
3768 +
3769 +static void __init probe_dcache(unsigned long config)
3770 +{
3771 +        unsigned long config1;
3772 +       unsigned int lsize;
3773 +
3774 +       mips_cpu.dcache.flags = 0;
3775 +        if (!(config & (1 << 31))) {
3776 +               /*
3777 +                * Not a MIPS32 complainant CPU.
3778 +                * Config 1 register not supported, we assume R4k style.
3779 +                */
3780 +               dcache_size = 1 << (12 + ((config >> 6) & 7));
3781 +               dc_lsize = 16 << ((config >> 4) & 1);
3782 +               mips_cpu.dcache.linesz = dc_lsize;
3783 +               /*
3784 +                * We cannot infer associativity - assume direct map
3785 +                * unless probe template indicates otherwise
3786 +                */
3787 +               if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1;
3788 +               mips_cpu.dcache.sets =
3789 +                       (dcache_size / dc_lsize) / mips_cpu.dcache.ways;
3790 +       } else {
3791 +               config1 = read_c0_config1();
3792 +
3793 +               if ((lsize = ((config1 >> 10) & 7)))
3794 +                       mips_cpu.dcache.linesz = 2 << lsize;
3795 +               else
3796 +                       mips_cpu.dcache.linesz= lsize;
3797 +               mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7);
3798 +               mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7);
3799 +
3800 +               dc_lsize = mips_cpu.dcache.linesz;
3801 +               dcache_size =
3802 +                       mips_cpu.dcache.sets * mips_cpu.dcache.ways
3803 +                       * dc_lsize;
3804 +       }
3805 +       printk("Primary data cache %dkb, linesize %d bytes (%d ways)\n",
3806 +              dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways);
3807 +}
3808 +
3809 +static void __init setup_noscache_funcs(void)
3810 +{
3811 +       _clear_page = (void *)mips32_clear_page_dc;
3812 +       _copy_page = (void *)mips32_copy_page_dc;
3813 +       _flush_cache_all = mips32_flush_cache_all_pc;
3814 +       ___flush_cache_all = mips32_flush_cache_all_pc;
3815 +       _flush_cache_mm = mips32_flush_cache_mm_pc;
3816 +       _flush_cache_range = mips32_flush_cache_range_pc;
3817 +       _flush_cache_page = mips32_flush_cache_page_pc;
3818 +       _flush_page_to_ram = mips32_flush_page_to_ram_pc;
3819 +
3820 +       _flush_icache_page = mips32_flush_icache_page;
3821 +
3822 +       _dma_cache_wback_inv = mips32_dma_cache_wback_inv_pc;
3823 +       _dma_cache_wback = mips32_dma_cache_wback;
3824 +       _dma_cache_inv = mips32_dma_cache_inv_pc;
3825 +}
3826 +
3827 +static void __init _change_cachability(u32 cm)
3828 +{
3829 +       change_c0_config(CONF_CM_CMASK, cm);
3830 +
3831 +       if ((mips_cpu.processor_id & (PRID_COMP_MASK | PRID_IMP_MASK)) ==
3832 +           (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) {
3833 +               cm = read_c0_diag();
3834 +               /* Enable icache */
3835 +               cm |= (1 << 31);
3836 +               /* Enable dcache */
3837 +               cm |= (1 << 30);
3838 +               write_c0_diag(cm);
3839 +       }
3840 +}      
3841 +static void (*change_cachability)(u32);
3842 +
3843 +void __init ld_mmu_bcm4710(void)
3844 +{
3845 +       unsigned long config = read_c0_config();
3846 +
3847 +       change_cachability = (void (*)(u32)) KSEG1ADDR((unsigned long)(_change_cachability));
3848 +       change_cachability(CONF_CM_DEFAULT);
3849 +
3850 +       probe_icache(config);
3851 +       probe_dcache(config);
3852 +       setup_noscache_funcs();
3853 +
3854 +       _flush_cache_sigtramp = mips32_flush_cache_sigtramp;
3855 +       _flush_icache_range = mips32_flush_icache_range;        /* Ouch */
3856 +       _flush_icache_all = mips32_flush_icache_all;
3857 +
3858 +       __flush_cache_all();
3859 +}
3860 --- linux-2.4.20/arch/mips/mm/c-mips32.c~2.4.20_broadcom_3_37_2_1109_US.patch   2005-01-07 05:39:01.000000000 -0500
3861 +++ linux-2.4.20/arch/mips/mm/c-mips32.c        2005-01-07 05:39:02.000000000 -0500
3862 @@ -163,7 +163,6 @@
3863                                     unsigned long page)
3864  {
3865         struct mm_struct *mm = vma->vm_mm;
3866 -       unsigned long flags;
3867         pgd_t *pgdp;
3868         pmd_t *pmdp;
3869         pte_t *ptep;
3870 @@ -212,7 +211,6 @@
3871                                     unsigned long page)
3872  {
3873         struct mm_struct *mm = vma->vm_mm;
3874 -       unsigned long flags;
3875         pgd_t *pgdp;
3876         pmd_t *pmdp;
3877         pte_t *ptep;
3878 @@ -313,11 +311,11 @@
3879  mips32_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
3880  {
3881         unsigned long end, a;
3882 -       unsigned int flags;
3883 +       unsigned long flags;
3884  
3885         if (size >= dcache_size) {
3886                 blast_dcache();
3887 -       } else {
3888 +       } else if (size) {
3889                 local_irq_save(flags);
3890                 a = addr & ~(dc_lsize - 1);
3891                 end = (addr + size - 1) & ~(dc_lsize - 1);
3892 @@ -338,9 +336,7 @@
3893  
3894         if (size >= scache_size) {
3895                 blast_scache();
3896 -               return;
3897 -       }
3898 -
3899 +       } else if (size) {
3900         a = addr & ~(sc_lsize - 1);
3901         end = (addr + size - 1) & ~(sc_lsize - 1);
3902         while (1) {
3903 @@ -348,17 +344,18 @@
3904                 if (a == end) break;
3905                 a += sc_lsize;
3906         }
3907 +       }
3908  }
3909  
3910  static void
3911  mips32_dma_cache_inv_pc(unsigned long addr, unsigned long size)
3912  {
3913         unsigned long end, a;
3914 -       unsigned int flags;
3915 +       unsigned long flags;
3916  
3917         if (size >= dcache_size) {
3918                 blast_dcache();
3919 -       } else {
3920 +       } else if (size) {
3921                 local_irq_save(flags);
3922                 a = addr & ~(dc_lsize - 1);
3923                 end = (addr + size - 1) & ~(dc_lsize - 1);
3924 @@ -380,9 +377,7 @@
3925  
3926         if (size >= scache_size) {
3927                 blast_scache();
3928 -               return;
3929 -       }
3930 -
3931 +       } else if (size) {
3932         a = addr & ~(sc_lsize - 1);
3933         end = (addr + size - 1) & ~(sc_lsize - 1);
3934         while (1) {
3935 @@ -390,6 +385,7 @@
3936                 if (a == end) break;
3937                 a += sc_lsize;
3938         }
3939 +       }
3940  }
3941  
3942  static void
3943 @@ -664,16 +660,51 @@
3944         setup_noscache_funcs();
3945  }
3946  
3947 -void __init ld_mmu_mips32(void)
3948 +#if defined(CONFIG_BCM4310) || defined(CONFIG_BCM4704) || defined(CONFIG_BCM5365)
3949 +static void __init _change_cachability(u32 cm)
3950  {
3951 -       unsigned long config = read_c0_config();
3952 -       extern char except_vec2_generic;
3953 +       change_c0_config(CONF_CM_CMASK, cm);
3954  
3955 -       /* Default cache error handler for MIPS32 */
3956 -       memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
3957 -       memcpy((void *)(KSEG1 + 0x100), &except_vec2_generic, 0x80);
3958 +       if (BCM330X(mips_cpu.processor_id)) {
3959 +               cm = read_c0_diag();
3960 +               /* Enable icache */
3961 +               cm |= (1 << 31);
3962 +               /* Enable dcache */
3963 +               cm |= (1 << 30);
3964 +               write_c0_diag(cm);
3965 +       }
3966 +}      
3967 +static void (*change_cachability)(u32);
3968 +#endif
3969  
3970 -       change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
3971 +#ifdef CONFIG_BCM4704
3972 +static void __init mips32_icache_fill(unsigned long addr, uint nbytes)
3973 +{
3974 +       int i;
3975 +       for (i = 0; i < nbytes; i += ic_lsize)
3976 +               fill_icache_line((addr + i));
3977 +       }
3978 +
3979 +/*
3980 + *  This must be run from the cache on 4704A0
3981 + *  so there are no mips core BIU ops in progress
3982 + *  when the PFC is enabled.
3983 + */
3984 +#define        PFC_CR0         0xff400000      /* control reg 0 */
3985 +#define        PFC_CR1         0xff400004      /* control reg 1 */
3986 +static void __init enable_pfc(u32 mode)
3987 +{
3988 +       /* write range */
3989 +       *(volatile u32 *)PFC_CR1 = 0xffff0000;
3990 +
3991 +       /* enable */
3992 +       *(volatile u32 *)PFC_CR0 = mode;
3993 +}
3994 +#endif
3995 +
3996 +void __init ld_mmu_mips32(void)
3997 +{
3998 +       unsigned long config = read_c0_config();
3999  
4000         probe_icache(config);
4001         probe_dcache(config);
4002 @@ -684,4 +715,20 @@
4003         _flush_icache_all = mips32_flush_icache_all;
4004  
4005         __flush_cache_all();
4006 +
4007 +#if defined(CONFIG_BCM4310) || defined(CONFIG_BCM4704) || defined(CONFIG_BCM5365)
4008 +       change_cachability = (void (*)(u32)) KSEG1ADDR((unsigned long)(_change_cachability));
4009 +       change_cachability(CONF_CM_DEFAULT);
4010 +#else
4011 +       change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
4012 +#endif
4013 +
4014 +#ifdef CONFIG_BCM4704
4015 +       /* enable prefetch cache */
4016 +       if (BCM330X(mips_cpu.processor_id) &&
4017 +               (read_c0_diag() & (1 << 29))) {
4018 +               mips32_icache_fill((unsigned long) &enable_pfc, 64);
4019 +               enable_pfc(0x15);
4020 +       }
4021 +#endif
4022  }
4023 --- linux-2.4.20/arch/mips/mm/loadmmu.c~2.4.20_broadcom_3_37_2_1109_US.patch    2005-01-07 05:38:15.000000000 -0500
4024 +++ linux-2.4.20/arch/mips/mm/loadmmu.c 2005-01-07 05:39:02.000000000 -0500
4025 @@ -61,12 +61,21 @@
4026  extern void ld_mmu_andes(void);
4027  extern void ld_mmu_sb1(void);
4028  extern void ld_mmu_mips32(void);
4029 +extern void ld_mmu_bcm4710(void);
4030  extern void r3k_tlb_init(void);
4031  extern void r4k_tlb_init(void);
4032  extern void sb1_tlb_init(void);
4033  
4034  void __init loadmmu(void)
4035  {
4036 +#ifdef CONFIG_BCM4710
4037 +       if (mips_cpu.cputype == CPU_BCM4710 &&
4038 +           (mips_cpu.processor_id & PRID_REV_MASK) == 0) {
4039 +               printk("Loading BCM4710 MMU routines.\n");
4040 +               ld_mmu_bcm4710();
4041 +               r4k_tlb_init();
4042 +       } else
4043 +#endif
4044         if (mips_cpu.options & MIPS_CPU_4KTLB) {
4045  #if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \
4046      defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \
4047 --- linux-2.4.20/arch/mips/mm/tlbex-r4k.S~2.4.20_broadcom_3_37_2_1109_US.patch  2005-01-07 05:39:01.000000000 -0500
4048 +++ linux-2.4.20/arch/mips/mm/tlbex-r4k.S       2005-01-07 05:39:02.000000000 -0500
4049 @@ -162,6 +162,9 @@
4050         .set    noat
4051         LEAF(except_vec0_r4000)
4052         .set    mips3
4053 +#ifdef CONFIG_BCM4704        
4054 +        nop           
4055 +#endif                              
4056         GET_PGD(k0, k1)                         # get pgd pointer
4057         mfc0    k0, CP0_BADVADDR                # Get faulting address
4058         srl     k0, k0, _PGDIR_SHIFT            # get pgd only bits
4059 @@ -248,15 +251,16 @@
4060         eret                                    # return from trap
4061         END(except_vec0_nevada)
4062  
4063 -       /* TLB refill, EXL == 0, SB1 with M3 errata handling version */
4064 -       LEAF(except_vec0_sb1)
4065  #ifdef BCM1250_M3_WAR
4066 +
4067 +       /* TLB refill, EXL == 0, SB1 with M3 errata handling version */
4068 +       LEAF(except_vec0_sb1_m3)
4069         mfc0    k0, CP0_BADVADDR
4070         mfc0    k1, CP0_ENTRYHI
4071         xor     k0, k1
4072 -       srl     k0, k0, PAGE_SHIFT+1
4073 -       bnez    k0, 1f
4074 -#endif
4075 +       srl     k0, k0, 13                      # PAGE_SHIFT + 1
4076 +       bnez    k0, 2f
4077 +
4078         GET_PGD(k0, k1)                         # get pgd pointer
4079         mfc0    k0, CP0_BADVADDR                # Get faulting address
4080         srl     k0, k0, _PGDIR_SHIFT            # get pgd only bits
4081 @@ -273,9 +277,12 @@
4082         P_MTC0  k0, CP0_ENTRYLO0                # load it
4083         PTE_SRL k1, k1, 6                       # convert to entrylo1
4084         P_MTC0  k1, CP0_ENTRYLO1                # load it
4085 +       b       1f
4086         tlbwr                                   # write random tlb entry
4087 -1:     eret                                    # return from trap
4088 -       END(except_vec0_sb1)
4089 +1:     nop
4090 +2:     eret                                    # return from trap
4091 +       END(except_vec0_sb1_m3)
4092 +#endif /* BCM1250_M3_WAR */
4093  
4094         /* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */
4095         LEAF(except_vec0_r45k_bvahwbug)
4096 --- linux-2.4.20/arch/mips/ramdisk/Makefile~2.4.20_broadcom_3_37_2_1109_US.patch        2005-01-07 05:39:01.000000000 -0500
4097 +++ linux-2.4.20/arch/mips/ramdisk/Makefile     2005-01-07 05:39:02.000000000 -0500
4098 @@ -5,10 +5,10 @@
4099  # removes any old dependencies. DON'T put your own dependencies here
4100  # unless it's something special (ie not a .c file).
4101  #
4102 -
4103  O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32)
4104 -img = $(CONFIG_EMBEDDED_RAMDISK_IMAGE)
4105 -ramdisk.o: ramdisk.gz ld.script
4106 +img = $(subst ",,$(CONFIG_EMBEDDED_RAMDISK_IMAGE))
4107 +
4108 +ramdisk.o: $(img) ld.script
4109         echo "O_FORMAT:  " $(O_FORMAT)
4110         $(LD) -T ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img)
4111  
4112 --- linux-2.4.20/drivers/block/Config.in~2.4.20_broadcom_3_37_2_1109_US.patch   2005-01-07 05:38:15.000000000 -0500
4113 +++ linux-2.4.20/drivers/block/Config.in        2005-01-07 05:39:02.000000000 -0500
4114 @@ -4,6 +4,10 @@
4115  mainmenu_option next_comment
4116  comment 'Block devices'
4117  
4118 +tristate 'M-Systems DiskOnChip Block Device support' CONFIG_BLK_DEV_MSYS
4119 +
4120 +tristate 'No-root support' CONFIG_NOROOT
4121 +
4122  tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD
4123  if [ "$CONFIG_AMIGA" = "y" ]; then
4124     tristate 'Amiga floppy support' CONFIG_AMIGA_FLOPPY
4125 --- linux-2.4.20/drivers/block/Makefile~2.4.20_broadcom_3_37_2_1109_US.patch    2005-01-07 05:38:15.000000000 -0500
4126 +++ linux-2.4.20/drivers/block/Makefile 2005-01-07 05:39:02.000000000 -0500
4127 @@ -34,4 +34,9 @@
4128  
4129  subdir-$(CONFIG_PARIDE) += paride
4130  
4131 +ifdef CONFIG_BLK_DEV_MSYS
4132 +obj-$(CONFIG_BLK_DEV_MSYS)     += ../../../../router/trueffs/linux/doc.o
4133 +subdir-$(CONFIG_BLK_DEV_MSYS)  += ../../../../router/trueffs/linux
4134 +endif
4135 +
4136  include $(TOPDIR)/Rules.make
4137 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
4138 +++ linux-2.4.20/drivers/block/dummy.c  2005-01-07 05:39:02.000000000 -0500
4139 @@ -0,0 +1,70 @@
4140 +/*
4141 + * dummyfs: a placeholder filesystem that sleeps forever when mounted
4142 + *
4143 + * Copyright 2004, Broadcom Corporation      
4144 + * All Rights Reserved.      
4145 + *       
4146 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY      
4147 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM      
4148 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS      
4149 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.      
4150 + *
4151 + * $Id: dummy.c,v 1.1.1.6 2004/04/12 04:31:22 honor Exp $
4152 + */
4153 +
4154 +#include <linux/config.h>
4155 +#include <linux/module.h>
4156 +
4157 +#include <linux/sched.h>
4158 +#include <linux/fs.h>
4159 +#include <linux/file.h>
4160 +#include <linux/stat.h>
4161 +#include <linux/errno.h>
4162 +#include <linux/major.h>
4163 +#include <linux/wait.h>
4164 +#include <linux/blk.h>
4165 +#include <linux/init.h>
4166 +#include <linux/devfs_fs_kernel.h>
4167 +#include <linux/smp_lock.h>
4168 +#include <linux/swap.h>
4169 +#include <linux/slab.h>
4170 +
4171 +#include <asm/uaccess.h>
4172 +
4173 +/* I don't thik anyone would mind if we stole CM206_CDROM_MAJOR */
4174 +#define DUMMY_MAJOR 0x20
4175 +
4176 +static int dummy_open(struct inode *inode, struct file *file)
4177 +{
4178 +       DECLARE_WAIT_QUEUE_HEAD(wait);
4179 +
4180 +       for (;;)
4181 +               sleep_on(&wait);
4182 +
4183 +       return 0;
4184 +}
4185 +
4186 +static struct block_device_operations dummy_fops = {
4187 +       open:           dummy_open,
4188 +};
4189 +
4190 +int __init dummy_init(void) 
4191 +{
4192 +       if (devfs_register_blkdev(DUMMY_MAJOR, "dummy", &dummy_fops)) {
4193 +               printk(KERN_WARNING "Unable to get major number for dummy device\n");
4194 +               return -EIO;
4195 +       }
4196 +
4197 +       register_disk(NULL, MKDEV(DUMMY_MAJOR, 0), 1, &dummy_fops, 0);
4198 +
4199 +       return 0;
4200 +}
4201 +
4202 +void dummy_exit(void) 
4203 +{
4204 +       if (devfs_unregister_blkdev(0, "dummy"))
4205 +               printk(KERN_WARNING "dummy: cannot unregister blkdev\n");
4206 +}
4207 +
4208 +module_init(dummy_init);
4209 +module_exit(dummy_exit);
4210 --- linux-2.4.20/drivers/char/mem.c~2.4.20_broadcom_3_37_2_1109_US.patch        2005-01-07 05:38:15.000000000 -0500
4211 +++ linux-2.4.20/drivers/char/mem.c     2005-01-07 05:39:02.000000000 -0500
4212 @@ -621,7 +621,8 @@
4213         {1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
4214         {2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
4215         {3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
4216 -#if defined(CONFIG_ISA) || !defined(__mc68000__)
4217 +#if defined(CONFIG_ISA) || !defined(__mc68000__) || \
4218 +    defined(CONFIG_BCM94702_CPCI)
4219         {4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
4220  #endif
4221         {5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
4222 --- linux-2.4.20/drivers/char/serial.c~2.4.20_broadcom_3_37_2_1109_US.patch     2005-01-07 05:39:01.000000000 -0500
4223 +++ linux-2.4.20/drivers/char/serial.c  2005-01-07 05:39:02.000000000 -0500
4224 @@ -444,6 +444,10 @@
4225                 return inb(info->port+1);
4226  #endif
4227         case SERIAL_IO_MEM:
4228 +#ifdef CONFIG_BCM4310
4229 +               readb((unsigned long) info->iomem_base +
4230 +                     (UART_SCR<<info->iomem_reg_shift));
4231 +#endif
4232                 return readb((unsigned long) info->iomem_base +
4233                              (offset<<info->iomem_reg_shift));
4234         default:
4235 @@ -464,6 +468,9 @@
4236         case SERIAL_IO_MEM:
4237                 writeb(value, (unsigned long) info->iomem_base +
4238                               (offset<<info->iomem_reg_shift));
4239 +#ifdef CONFIG_BCM4704
4240 +               *((volatile unsigned int *) KSEG1ADDR(0x18000000));
4241 +#endif
4242                 break;
4243         default:
4244                 outb(value, info->port+offset);
4245 @@ -5970,6 +5977,13 @@
4246          *      Divisor, bytesize and parity
4247          */
4248         state = rs_table + co->index;
4249 +       /*
4250 +       * Safe guard: state structure must have been initialized
4251 +       */
4252 +       if (state->iomem_base == NULL) {
4253 +               printk("!unable to setup serial console!\n");
4254 +               return -1;
4255 +       }
4256         if (doflow)
4257                 state->flags |= ASYNC_CONS_FLOW;
4258         info = &async_sercons;
4259 --- linux-2.4.20/drivers/ide/ide-pci.c~2.4.20_broadcom_3_37_2_1109_US.patch     2005-01-07 05:38:15.000000000 -0500
4260 +++ linux-2.4.20/drivers/ide/ide-pci.c  2005-01-07 05:39:02.000000000 -0500
4261 @@ -793,11 +793,6 @@
4262                         goto bypass_piix_dma;
4263                 if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDCADMA))
4264                         goto bypass_legacy_dma;
4265 -               if (hwif->udma_four) {
4266 -                       printk("%s: ATA-66/100 forced bit set (WARNING)!!\n", d->name);
4267 -               } else {
4268 -                       hwif->udma_four = (d->ata66_check) ? d->ata66_check(hwif) : 0;
4269 -               }
4270  #ifdef CONFIG_BLK_DEV_IDEDMA
4271                 if (IDE_PCI_DEVID_EQ(d->devid, DEVID_SIS5513) ||
4272                     IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) ||
4273 @@ -855,6 +850,11 @@
4274                                 printk("%s: %s Bus-Master DMA disabled (BIOS)\n", hwif->name, d->name);
4275                         }
4276                 }
4277 +               if (hwif->udma_four) {
4278 +                       printk("%s: ATA-66/100 forced bit set (WARNING)!!\n", d->name);
4279 +               } else {
4280 +                       hwif->udma_four = (d->ata66_check) ? d->ata66_check(hwif) : 0;
4281 +               }
4282  #endif /* CONFIG_BLK_DEV_IDEDMA */
4283  bypass_legacy_dma:
4284  bypass_piix_dma:
4285 --- linux-2.4.20/drivers/mtd/chips/Config.in~2.4.20_broadcom_3_37_2_1109_US.patch       2005-01-07 05:38:15.000000000 -0500
4286 +++ linux-2.4.20/drivers/mtd/chips/Config.in    2005-01-07 05:39:02.000000000 -0500
4287 @@ -43,6 +43,7 @@
4288  fi
4289  dep_tristate '  Support for Intel/Sharp flash chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_GEN_PROBE
4290  dep_tristate '  Support for AMD/Fujitsu flash chips' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_GEN_PROBE
4291 +dep_tristate '  Support for SST flash chips' CONFIG_MTD_CFI_SSTSTD $CONFIG_MTD_GEN_PROBE
4292  
4293  dep_tristate '  Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONFIG_MTD
4294  dep_tristate '  Support for ROM chips in bus mapping' CONFIG_MTD_ROM $CONFIG_MTD
4295 --- linux-2.4.20/drivers/mtd/chips/Makefile~2.4.20_broadcom_3_37_2_1109_US.patch        2005-01-07 05:38:15.000000000 -0500
4296 +++ linux-2.4.20/drivers/mtd/chips/Makefile     2005-01-07 05:39:02.000000000 -0500
4297 @@ -17,6 +17,7 @@
4298  obj-$(CONFIG_MTD)              += chipreg.o
4299  obj-$(CONFIG_MTD_AMDSTD)       += amd_flash.o 
4300  obj-$(CONFIG_MTD_CFI)          += cfi_probe.o
4301 +obj-$(CONFIG_MTD_CFI_SSTSTD)   += cfi_cmdset_0701.o
4302  obj-$(CONFIG_MTD_CFI_AMDSTD)   += cfi_cmdset_0002.o
4303  obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o
4304  obj-$(CONFIG_MTD_GEN_PROBE)    += gen_probe.o
4305 --- linux-2.4.20/drivers/mtd/chips/cfi_cmdset_0001.c~2.4.20_broadcom_3_37_2_1109_US.patch       2005-01-07 05:38:15.000000000 -0500
4306 +++ linux-2.4.20/drivers/mtd/chips/cfi_cmdset_0001.c    2005-01-07 05:39:02.000000000 -0500
4307 @@ -59,6 +59,8 @@
4308  #ifdef DEBUG_CFI_FEATURES
4309  static void cfi_tell_features(struct cfi_pri_intelext *extp)
4310  {
4311 +       int i;
4312 +
4313         printk("  Feature/Command Support: %4.4X\n", extp->FeatureSupport);
4314         printk("     - Chip Erase:         %s\n", extp->FeatureSupport&1?"supported":"unsupported");
4315         printk("     - Suspend Erase:      %s\n", extp->FeatureSupport&2?"supported":"unsupported");
4316 @@ -184,7 +186,7 @@
4317         unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
4318  
4319         mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
4320 -       //printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips);
4321 +       printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips);
4322  
4323         if (!mtd) {
4324                 printk(KERN_ERR "Failed to allocate memory for MTD device\n");
4325 @@ -1226,6 +1228,9 @@
4326                         chip->state = chip->oldstate;
4327                         wake_up(&chip->wq);
4328                 }
4329 +
4330 +               /* make absolutely sure that chip is out of lock/suspend state */
4331 +               cfi_write(map, CMD(0xFF), 0);
4332                 spin_unlock_bh(chip->mutex);
4333         }
4334  }
4335 @@ -1319,6 +1324,7 @@
4336         }
4337         
4338         /* Done and happy. */
4339 +       cfi_write(map, CMD(0x70), adr);
4340         chip->state = FL_STATUS;
4341         DISABLE_VPP(map);
4342         wake_up(&chip->wq);
4343 @@ -1468,6 +1474,7 @@
4344         }
4345         
4346         /* Done and happy. */
4347 +       cfi_write(map, CMD(0x70), adr);
4348         chip->state = FL_STATUS;
4349         DISABLE_VPP(map);
4350         wake_up(&chip->wq);
4351 @@ -1483,34 +1490,96 @@
4352  #ifdef DEBUG_LOCK_BITS
4353         int ofs_factor = cfi->interleave * cfi->device_type;
4354  #endif
4355 +       int i, first;
4356 +       struct mtd_erase_region_info *regions = mtd->eraseregions;
4357 +
4358 +       if (ofs > mtd->size)
4359 +               return -EINVAL;
4360 +
4361 +       if ((len + ofs) > mtd->size)
4362 +               return -EINVAL;
4363 +
4364 +       /* Check that both start and end of the requested erase are
4365 +        * aligned with the erasesize at the appropriate addresses.
4366 +        */
4367 +
4368 +       i = 0;
4369 +
4370 +       /* Skip all erase regions which are ended before the start of 
4371 +          the requested erase. Actually, to save on the calculations,
4372 +          we skip to the first erase region which starts after the
4373 +          start of the requested erase, and then go back one.
4374 +       */
4375 +       
4376 +       while (i < mtd->numeraseregions && ofs >= regions[i].offset)
4377 +              i++;
4378 +       i--;
4379 +
4380 +       /* OK, now i is pointing at the erase region in which this 
4381 +          erase request starts. Check the start of the requested
4382 +          erase range is aligned with the erase size which is in
4383 +          effect here.
4384 +       */
4385 +
4386 +       if (ofs & (regions[i].erasesize-1))
4387 +               return -EINVAL;
4388 +
4389 +       /* Remember the erase region we start on */
4390 +       first = i;
4391 +
4392 +       /* Next, check that the end of the requested erase is aligned
4393 +        * with the erase region at that address.
4394 +        */
4395 +
4396 +       while (i<mtd->numeraseregions && (ofs + len) >= regions[i].offset)
4397 +               i++;
4398 +
4399 +       /* As before, drop back one to point at the region in which
4400 +          the address actually falls
4401 +       */
4402 +       i--;
4403 +       
4404 +       if ((ofs + len) & (regions[i].erasesize-1))
4405 +               return -EINVAL;
4406  
4407         chipnum = ofs >> cfi->chipshift;
4408         adr = ofs - (chipnum << cfi->chipshift);
4409 +       i = first;
4410  
4411 -#ifdef DEBUG_LOCK_BITS
4412 -       {
4413 -               unsigned long temp_adr = adr;
4414 -               unsigned long temp_len = len;
4415 +       while(len) {
4416                   
4417 +#ifdef DEBUG_LOCK_BITS
4418                 cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
4419 -                while (temp_len) {
4420 -                       printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor)));
4421 -                       temp_adr += mtd->erasesize;
4422 -                       temp_len -= mtd->erasesize;
4423 -               }
4424 +               printk("before unlock %x: block status register is %x\n",adr,cfi_read_query(map, adr+(2*ofs_factor)));
4425                 cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
4426 -       }
4427  #endif
4428  
4429         ret = do_unlock_oneblock(map, &cfi->chips[chipnum], adr);
4430  
4431  #ifdef DEBUG_LOCK_BITS
4432         cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
4433 -       printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
4434 +               printk("after unlock %x: block status register is %x\n",adr,cfi_read_query(map, adr+(2*ofs_factor)));
4435         cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
4436  #endif
4437         
4438 +               if (ret)
4439         return ret;
4440 +
4441 +               adr += regions[i].erasesize;
4442 +               len -= regions[i].erasesize;
4443 +
4444 +               if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
4445 +                       i++;
4446 +
4447 +               if (adr >> cfi->chipshift) {
4448 +                       adr = 0;
4449 +                       chipnum++;
4450 +                       
4451 +                       if (chipnum >= cfi->numchips)
4452 +                       break;
4453 +               }
4454 +       }
4455 +       return 0;
4456  }
4457  
4458  static int cfi_intelext_suspend(struct mtd_info *mtd)
4459 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
4460 +++ linux-2.4.20/drivers/mtd/chips/cfi_cmdset_0701.c    2005-01-07 05:39:02.000000000 -0500
4461 @@ -0,0 +1,855 @@
4462 +/*
4463 + * Common Flash Interface support:
4464 + *   SST Standard Vendor Command Set (ID 0x0701)
4465 + *
4466 + * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
4467 + *
4468 + * 2_by_8 routines added by Simon Munton
4469 + *
4470 + * This code is GPL
4471 + *
4472 + * $Id: cfi_cmdset_0701.c,v 1.1.1.4 2003/10/14 08:08:17 sparq Exp $
4473 + *
4474 + */
4475 +
4476 +#include <linux/module.h>
4477 +#include <linux/types.h>
4478 +#include <linux/kernel.h>
4479 +#include <linux/sched.h>
4480 +#include <asm/io.h>
4481 +#include <asm/byteorder.h>
4482 +
4483 +#include <linux/errno.h>
4484 +#include <linux/slab.h>
4485 +#include <linux/delay.h>
4486 +#include <linux/interrupt.h>
4487 +#include <linux/mtd/map.h>
4488 +#include <linux/mtd/cfi.h>
4489 +
4490 +static int cfi_sststd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
4491 +static int cfi_sststd_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
4492 +static int cfi_sststd_erase_onesize(struct mtd_info *, struct erase_info *);
4493 +static int cfi_sststd_erase_varsize(struct mtd_info *, struct erase_info *);
4494 +static void cfi_sststd_sync (struct mtd_info *);
4495 +static int cfi_sststd_suspend (struct mtd_info *);
4496 +static void cfi_sststd_resume (struct mtd_info *);
4497 +
4498 +static void cfi_sststd_destroy(struct mtd_info *);
4499 +
4500 +struct mtd_info *cfi_cmdset_0701(struct map_info *, int);
4501 +static struct mtd_info *cfi_sststd_setup (struct map_info *);
4502 +
4503 +
4504 +static struct mtd_chip_driver cfi_sststd_chipdrv = {
4505 +       probe: NULL, /* Not usable directly */
4506 +       destroy: cfi_sststd_destroy,
4507 +       name: "cfi_cmdset_0701",
4508 +       module: THIS_MODULE
4509 +};
4510 +
4511 +struct mtd_info *cfi_cmdset_0701(struct map_info *map, int primary)
4512 +{
4513 +       struct cfi_private *cfi = map->fldrv_priv;
4514 +       int ofs_factor = cfi->interleave * cfi->device_type;
4515 +       int i;
4516 +       __u8 major, minor;
4517 +       __u32 base = cfi->chips[0].start;
4518 +
4519 +       if (cfi->cfi_mode==1){
4520 +               __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
4521 +
4522 +               cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
4523 +               cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
4524 +               cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
4525 +               
4526 +               major = cfi_read_query(map, base + (adr+3)*ofs_factor);
4527 +               minor = cfi_read_query(map, base + (adr+4)*ofs_factor);
4528 +               
4529 +               printk(" SST Query Table v%c.%c at 0x%4.4X\n",
4530 +                      major, minor, adr);
4531 +               cfi_send_gen_cmd(0xf0, 0x5555, base, map, cfi, cfi->device_type, NULL);
4532 +               
4533 +               cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
4534 +               cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
4535 +               cfi_send_gen_cmd(0x90, 0x5555, base, map, cfi, cfi->device_type, NULL);
4536 +               cfi->mfr = cfi_read_query(map, base);
4537 +               cfi->id = cfi_read_query(map, base + ofs_factor);
4538 +
4539 +               cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
4540 +               cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
4541 +               cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
4542 +               
4543 +               switch (cfi->device_type) {
4544 +               case CFI_DEVICETYPE_X16:
4545 +                       cfi->addr_unlock1 = 0x5555;
4546 +                       cfi->addr_unlock2 = 0x2AAA;
4547 +                       break;
4548 +               default:
4549 +                       printk(KERN_NOTICE "Eep. Unknown cfi_cmdset_0701 device type %d\n", cfi->device_type);
4550 +                       return NULL;
4551 +               }
4552 +       } /* CFI mode */
4553 +
4554 +       for (i=0; i< cfi->numchips; i++) {
4555 +               cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
4556 +               cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
4557 +               cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
4558 +       }               
4559 +       
4560 +       map->fldrv = &cfi_sststd_chipdrv;
4561 +       MOD_INC_USE_COUNT;
4562 +
4563 +       cfi_send_gen_cmd(0xf0, 0x5555, base, map, cfi, cfi->device_type, NULL);
4564 +       return cfi_sststd_setup(map);
4565 +}
4566 +
4567 +static struct mtd_info *cfi_sststd_setup(struct map_info *map)
4568 +{
4569 +       struct cfi_private *cfi = map->fldrv_priv;
4570 +       struct mtd_info *mtd;
4571 +       unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
4572 +
4573 +       mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
4574 +       printk("number of %s chips: %d\n", (cfi->cfi_mode)?"JEDEC":"CFI",cfi->numchips);
4575 +
4576 +       if (!mtd) {
4577 +         printk("Failed to allocate memory for MTD device\n");
4578 +         kfree(cfi->cmdset_priv);
4579 +         return NULL;
4580 +       }
4581 +
4582 +       memset(mtd, 0, sizeof(*mtd));
4583 +       mtd->priv = map;
4584 +       mtd->type = MTD_NORFLASH;
4585 +       /* Also select the correct geometry setup too */ 
4586 +       mtd->size = devsize * cfi->numchips;
4587 +       
4588 +       if (cfi->cfiq->NumEraseRegions == 1) {
4589 +               /* No need to muck about with multiple erase sizes */
4590 +               mtd->erasesize = ((cfi->cfiq->EraseRegionInfo[0] >> 8) & ~0xff) * cfi->interleave;
4591 +       } else {
4592 +               unsigned long offset = 0;
4593 +               int i,j;
4594 +
4595 +               mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
4596 +               mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * mtd->numeraseregions, GFP_KERNEL);
4597 +               if (!mtd->eraseregions) { 
4598 +                       printk("Failed to allocate memory for MTD erase region info\n");
4599 +                       kfree(cfi->cmdset_priv);
4600 +                       return NULL;
4601 +               }
4602 +                       
4603 +               for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
4604 +                       unsigned long ernum, ersize;
4605 +                       ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
4606 +                       ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
4607 +                       
4608 +                       if (mtd->erasesize < ersize) {
4609 +                               mtd->erasesize = ersize;
4610 +                       }
4611 +                       for (j=0; j<cfi->numchips; j++) {
4612 +                               mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset;
4613 +                               mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize;
4614 +                               mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum;
4615 +                       }
4616 +                       offset += (ersize * ernum);
4617 +               }
4618 +
4619 +               // debug
4620 +               for (i=0; i<mtd->numeraseregions;i++){
4621 +                       printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
4622 +                              i,mtd->eraseregions[i].offset,
4623 +                              mtd->eraseregions[i].erasesize,
4624 +                              mtd->eraseregions[i].numblocks);
4625 +               }
4626 +       }
4627 +
4628 +       switch (CFIDEV_BUSWIDTH)
4629 +       {
4630 +       case 1:
4631 +       case 2:
4632 +       case 4:
4633 +               if (mtd->numeraseregions > 1)
4634 +                       mtd->erase = cfi_sststd_erase_varsize;
4635 +               else
4636 +                       mtd->erase = cfi_sststd_erase_onesize;
4637 +               mtd->read = cfi_sststd_read;
4638 +               mtd->write = cfi_sststd_write;
4639 +               break;
4640 +
4641 +       default:
4642 +               printk("Unsupported buswidth\n");
4643 +               kfree(mtd);
4644 +               kfree(cfi->cmdset_priv);
4645 +               return NULL;
4646 +               break;
4647 +       }
4648 +       mtd->sync = cfi_sststd_sync;
4649 +       mtd->suspend = cfi_sststd_suspend;
4650 +       mtd->resume = cfi_sststd_resume;
4651 +       mtd->flags = MTD_CAP_NORFLASH;
4652 +       map->fldrv = &cfi_sststd_chipdrv;
4653 +       mtd->name = map->name;
4654 +       MOD_INC_USE_COUNT;
4655 +       return mtd;
4656 +}
4657 +
4658 +static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
4659 +{
4660 +       DECLARE_WAITQUEUE(wait, current);
4661 +       unsigned long timeo = jiffies + HZ;
4662 +
4663 + retry:
4664 +       cfi_spin_lock(chip->mutex);
4665 +
4666 +       if (chip->state != FL_READY){
4667 +               printk("Waiting for chip to read, status = %d\n", chip->state);
4668 +               set_current_state(TASK_UNINTERRUPTIBLE);
4669 +               add_wait_queue(&chip->wq, &wait);
4670 +                
4671 +               cfi_spin_unlock(chip->mutex);
4672 +
4673 +               schedule();
4674 +               remove_wait_queue(&chip->wq, &wait);
4675 +               timeo = jiffies + HZ;
4676 +
4677 +               goto retry;
4678 +       }       
4679 +
4680 +       adr += chip->start;
4681 +
4682 +       chip->state = FL_READY;
4683 +
4684 +       map->copy_from(map, buf, adr, len);
4685 +
4686 +       wake_up(&chip->wq);
4687 +       cfi_spin_unlock(chip->mutex);
4688 +
4689 +       return 0;
4690 +}
4691 +
4692 +static int cfi_sststd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
4693 +{
4694 +       struct map_info *map = mtd->priv;
4695 +       struct cfi_private *cfi = map->fldrv_priv;
4696 +       unsigned long ofs;
4697 +       int chipnum;
4698 +       int ret = 0;
4699 +
4700 +       /* ofs: offset within the first chip that the first read should start */
4701 +
4702 +       chipnum = (from >> cfi->chipshift);
4703 +       ofs = from - (chipnum <<  cfi->chipshift);
4704 +
4705 +
4706 +       *retlen = 0;
4707 +
4708 +       while (len) {
4709 +               unsigned long thislen;
4710 +
4711 +               if (chipnum >= cfi->numchips)
4712 +                       break;
4713 +
4714 +               if ((len + ofs -1) >> cfi->chipshift)
4715 +                       thislen = (1<<cfi->chipshift) - ofs;
4716 +               else
4717 +                       thislen = len;
4718 +
4719 +               ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
4720 +               if (ret)
4721 +                       break;
4722 +
4723 +               *retlen += thislen;
4724 +               len -= thislen;
4725 +               buf += thislen;
4726 +
4727 +               ofs = 0;
4728 +               chipnum++;
4729 +       }
4730 +       return ret;
4731 +}
4732 +
4733 +static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum, int fast)
4734 +{
4735 +       unsigned long timeo = jiffies + HZ;
4736 +       unsigned int Last[4];
4737 +       unsigned long Count = 0;
4738 +       struct cfi_private *cfi = map->fldrv_priv;
4739 +       DECLARE_WAITQUEUE(wait, current);
4740 +       int ret = 0;
4741 +
4742 + retry:
4743 +       cfi_spin_lock(chip->mutex);
4744 +
4745 +       if (chip->state != FL_READY){
4746 +               printk("Waiting for chip to write, status = %d\n", chip->state);
4747 +               set_current_state(TASK_UNINTERRUPTIBLE);
4748 +               add_wait_queue(&chip->wq, &wait);
4749 +                
4750 +               cfi_spin_unlock(chip->mutex);
4751 +
4752 +               schedule();
4753 +               remove_wait_queue(&chip->wq, &wait);
4754 +               printk("Wake up to write:\n");
4755 +               timeo = jiffies + HZ;
4756 +
4757 +               goto retry;
4758 +       }       
4759 +
4760 +       chip->state = FL_WRITING;
4761 +
4762 +       adr += chip->start;
4763 +       ENABLE_VPP(map);
4764 +    cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
4765 +    cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
4766 +    cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
4767 +
4768 +       cfi_write(map, datum, adr);
4769 +
4770 +       cfi_spin_unlock(chip->mutex);
4771 +       cfi_udelay(chip->word_write_time);
4772 +       cfi_spin_lock(chip->mutex);
4773 +
4774 +       Last[0] = cfi_read(map, adr);
4775 +       //      printk("Last[0] is %x\n", Last[0]);
4776 +       Last[1] = cfi_read(map, adr);
4777 +       //      printk("Last[1] is %x\n", Last[1]);
4778 +       Last[2] = cfi_read(map, adr);
4779 +       //      printk("Last[2] is %x\n", Last[2]);
4780 +
4781 +       for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && Count < 10000; Count++){
4782 +               cfi_spin_unlock(chip->mutex);
4783 +               cfi_udelay(10);
4784 +               cfi_spin_lock(chip->mutex);
4785 +               
4786 +               Last[Count % 4] = cfi_read(map, adr);
4787 +               //              printk("Last[%d%%4] is %x\n", Count, Last[Count%4]);
4788 +       }
4789 +       
4790 +       if (Last[(Count - 1) % 4] != datum){
4791 +               printk("Last[%ld] is %x, datum is %x\n",(Count - 1) % 4,Last[(Count - 1) % 4],datum);
4792 +               cfi_send_gen_cmd(0xF0, 0, chip->start, map, cfi, cfi->device_type, NULL);
4793 +               DISABLE_VPP(map);
4794 +               ret = -EIO;
4795 +       }       
4796 +       DISABLE_VPP(map);
4797 +       chip->state = FL_READY;
4798 +       wake_up(&chip->wq);
4799 +       cfi_spin_unlock(chip->mutex);
4800 +       
4801 +       return ret;
4802 +}
4803 +
4804 +static int cfi_sststd_write (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
4805 +{
4806 +       struct map_info *map = mtd->priv;
4807 +       struct cfi_private *cfi = map->fldrv_priv;
4808 +       int ret = 0;
4809 +       int chipnum;
4810 +       unsigned long ofs, chipstart;
4811 +
4812 +       *retlen = 0;
4813 +       if (!len)
4814 +               return 0;
4815 +
4816 +       chipnum = to >> cfi->chipshift;
4817 +       ofs = to  - (chipnum << cfi->chipshift);
4818 +       chipstart = cfi->chips[chipnum].start;
4819 +
4820 +       /* If it's not bus-aligned, do the first byte write */
4821 +       if (ofs & (CFIDEV_BUSWIDTH-1)) {
4822 +               unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1);
4823 +               int i = ofs - bus_ofs;
4824 +               int n = 0;
4825 +               u_char tmp_buf[4];
4826 +               __u32 datum;
4827 +
4828 +               map->copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
4829 +               while (len && i < CFIDEV_BUSWIDTH)
4830 +                       tmp_buf[i++] = buf[n++], len--;
4831 +
4832 +               if (cfi_buswidth_is_2()) {
4833 +                       datum = *(__u16*)tmp_buf;
4834 +               } else if (cfi_buswidth_is_4()) {
4835 +                       datum = *(__u32*)tmp_buf;
4836 +               } else {
4837 +                       return -EINVAL;  /* should never happen, but be safe */
4838 +               }
4839 +
4840 +               ret = do_write_oneword(map, &cfi->chips[chipnum], 
4841 +                               bus_ofs, datum, 0);
4842 +               if (ret) 
4843 +                       return ret;
4844 +               
4845 +               ofs += n;
4846 +               buf += n;
4847 +               (*retlen) += n;
4848 +
4849 +               if (ofs >> cfi->chipshift) {
4850 +                       chipnum ++; 
4851 +                       ofs = 0;
4852 +                       if (chipnum == cfi->numchips)
4853 +                               return 0;
4854 +               }
4855 +       }
4856 +       
4857 +       /* We are now aligned, write as much as possible */
4858 +       while(len >= CFIDEV_BUSWIDTH) {
4859 +               __u32 datum;
4860 +
4861 +               if (cfi_buswidth_is_1()) {
4862 +                       datum = *(__u8*)buf;
4863 +               } else if (cfi_buswidth_is_2()) {
4864 +                       datum = *(__u16*)buf;
4865 +               } else if (cfi_buswidth_is_4()) {
4866 +                       datum = *(__u32*)buf;
4867 +               } else {
4868 +                       return -EINVAL;
4869 +               }
4870 +               ret = do_write_oneword(map, &cfi->chips[chipnum],
4871 +                                      ofs, datum, cfi->fast_prog);
4872 +               if (ret) {
4873 +                       return ret;
4874 +               }
4875 +
4876 +               ofs += CFIDEV_BUSWIDTH;
4877 +               buf += CFIDEV_BUSWIDTH;
4878 +               (*retlen) += CFIDEV_BUSWIDTH;
4879 +               len -= CFIDEV_BUSWIDTH;
4880 +
4881 +               if (ofs >> cfi->chipshift) {
4882 +                       chipnum ++; 
4883 +                       ofs = 0;
4884 +                       if (chipnum == cfi->numchips)
4885 +                               return 0;
4886 +                       chipstart = cfi->chips[chipnum].start;
4887 +               }
4888 +       }
4889 +
4890 +       if (len & (CFIDEV_BUSWIDTH-1)) {
4891 +               int i = 0, n = 0;
4892 +               u_char tmp_buf[4];
4893 +               __u32 datum;
4894 +
4895 +               map->copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
4896 +               while (len--)
4897 +                       tmp_buf[i++] = buf[n++];
4898 +
4899 +               if (cfi_buswidth_is_2()) {
4900 +                       datum = *(__u16*)tmp_buf;
4901 +               } else if (cfi_buswidth_is_4()) {
4902 +                       datum = *(__u32*)tmp_buf;
4903 +               } else {
4904 +                       return -EINVAL;  /* should never happen, but be safe */
4905 +               }
4906 +
4907 +               ret = do_write_oneword(map, &cfi->chips[chipnum], 
4908 +                               ofs, datum, 0);
4909 +               if (ret) 
4910 +                       return ret;
4911 +               
4912 +               (*retlen) += n;
4913 +       }
4914 +
4915 +       return 0;
4916 +}
4917 +
4918 +static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
4919 +{
4920 +       unsigned int status;
4921 +       unsigned long timeo = jiffies + HZ;
4922 +       struct cfi_private *cfi = map->fldrv_priv;
4923 +       unsigned int rdy_mask;
4924 +       DECLARE_WAITQUEUE(wait, current);
4925 +
4926 + retry:
4927 +       cfi_spin_lock(chip->mutex);
4928 +
4929 +       if (chip->state != FL_READY){
4930 +               set_current_state(TASK_UNINTERRUPTIBLE);
4931 +               add_wait_queue(&chip->wq, &wait);
4932 +                
4933 +               cfi_spin_unlock(chip->mutex);
4934 +
4935 +               schedule();
4936 +               remove_wait_queue(&chip->wq, &wait);
4937 +               timeo = jiffies + HZ;
4938 +
4939 +               goto retry;
4940 +       }       
4941 +
4942 +       chip->state = FL_ERASING;
4943 +
4944 +       adr += chip->start;
4945 +       ENABLE_VPP(map);
4946 +       cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
4947 +       cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
4948 +       cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
4949 +       cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
4950 +       cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
4951 +       cfi_write(map, CMD(0x30), adr);
4952 +       
4953 +       timeo = jiffies + (HZ*20);
4954 +
4955 +       cfi_spin_unlock(chip->mutex);
4956 +       schedule_timeout(HZ);
4957 +       cfi_spin_lock(chip->mutex);
4958 +       
4959 +       rdy_mask = CMD(0x80);
4960 +
4961 +       /* Once the state machine's known to be working I'll do that */
4962 +
4963 +       while ( ( (status = cfi_read(map,adr)) & rdy_mask ) != rdy_mask ) {
4964 +               static int z=0;
4965 +
4966 +               if (chip->state != FL_ERASING) {
4967 +                       /* Someone's suspended the erase. Sleep */
4968 +                       set_current_state(TASK_UNINTERRUPTIBLE);
4969 +                       add_wait_queue(&chip->wq, &wait);
4970 +                       
4971 +                       cfi_spin_unlock(chip->mutex);
4972 +                       printk("erase suspended. Sleeping\n");
4973 +                       
4974 +                       schedule();
4975 +                       remove_wait_queue(&chip->wq, &wait);
4976 +                       timeo = jiffies + (HZ*2); 
4977 +                       cfi_spin_lock(chip->mutex);
4978 +                       continue;
4979 +               }
4980 +
4981 +               /* OK Still waiting */
4982 +               if (time_after(jiffies, timeo)) {
4983 +                       chip->state = FL_READY;
4984 +                       cfi_spin_unlock(chip->mutex);
4985 +                       printk("waiting for erase to complete timed out.");
4986 +                       DISABLE_VPP(map);
4987 +                       return -EIO;
4988 +               }
4989 +               
4990 +               /* Latency issues. Drop the lock, wait a while and retry */
4991 +               cfi_spin_unlock(chip->mutex);
4992 +
4993 +               z++;
4994 +               if ( 0 && !(z % 100 )) 
4995 +                       printk("chip not ready yet after erase. looping\n");
4996 +
4997 +               cfi_udelay(1);
4998 +               
4999 +               cfi_spin_lock(chip->mutex);
5000 +               continue;
5001 +       }
5002 +       
5003 +       /* Done and happy. */
5004 +       DISABLE_VPP(map);
5005 +       chip->state = FL_READY;
5006 +       wake_up(&chip->wq);
5007 +       cfi_spin_unlock(chip->mutex);
5008 +       return 0;
5009 +}
5010 +
5011 +static int cfi_sststd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
5012 +{
5013 +       struct map_info *map = mtd->priv;
5014 +       struct cfi_private *cfi = map->fldrv_priv;
5015 +       unsigned long adr, len;
5016 +       int chipnum, ret = 0;
5017 +       int i, first;
5018 +       struct mtd_erase_region_info *regions = mtd->eraseregions;
5019 +
5020 +       if (instr->addr > mtd->size)
5021 +               return -EINVAL;
5022 +
5023 +       if ((instr->len + instr->addr) > mtd->size)
5024 +               return -EINVAL;
5025 +
5026 +       /* Check that both start and end of the requested erase are
5027 +        * aligned with the erasesize at the appropriate addresses.
5028 +        */
5029 +
5030 +       i = 0;
5031 +
5032 +       /* Skip all erase regions which are ended before the start of 
5033 +          the requested erase. Actually, to save on the calculations,
5034 +          we skip to the first erase region which starts after the
5035 +          start of the requested erase, and then go back one.
5036 +       */
5037 +       
5038 +       while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
5039 +              i++;
5040 +       i--;
5041 +
5042 +       /* OK, now i is pointing at the erase region in which this 
5043 +          erase request starts. Check the start of the requested
5044 +          erase range is aligned with the erase size which is in
5045 +          effect here.
5046 +       */
5047 +
5048 +       if (instr->addr & (regions[i].erasesize-1))
5049 +               return -EINVAL;
5050 +
5051 +       /* Remember the erase region we start on */
5052 +       first = i;
5053 +
5054 +       /* Next, check that the end of the requested erase is aligned
5055 +        * with the erase region at that address.
5056 +        */
5057 +
5058 +       while (i<mtd->numeraseregions && (instr->addr + instr->len) >= regions[i].offset)
5059 +               i++;
5060 +
5061 +       /* As before, drop back one to point at the region in which
5062 +          the address actually falls
5063 +       */
5064 +       i--;
5065 +       
5066 +       if ((instr->addr + instr->len) & (regions[i].erasesize-1))
5067 +               return -EINVAL;
5068 +       
5069 +       chipnum = instr->addr >> cfi->chipshift;
5070 +       adr = instr->addr - (chipnum << cfi->chipshift);
5071 +       len = instr->len;
5072 +
5073 +       i=first;
5074 +
5075 +       while(len) {
5076 +               ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
5077 +
5078 +               if (ret)
5079 +                       return ret;
5080 +
5081 +               adr += regions[i].erasesize;
5082 +               len -= regions[i].erasesize;
5083 +
5084 +               if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
5085 +                       i++;
5086 +
5087 +               if (adr >> cfi->chipshift) {
5088 +                       adr = 0;
5089 +                       chipnum++;
5090 +                       
5091 +                       if (chipnum >= cfi->numchips)
5092 +                       break;
5093 +               }
5094 +       }
5095 +
5096 +       instr->state = MTD_ERASE_DONE;
5097 +       if (instr->callback)
5098 +               instr->callback(instr);
5099 +       
5100 +       return 0;
5101 +}
5102 +
5103 +static int cfi_sststd_erase_onesize(struct mtd_info *mtd, struct erase_info *instr)
5104 +{
5105 +       struct map_info *map = mtd->priv;
5106 +       struct cfi_private *cfi = map->fldrv_priv;
5107 +       unsigned long adr, len;
5108 +       int chipnum, ret = 0;
5109 +
5110 +       if (instr->addr & (mtd->erasesize - 1))
5111 +               return -EINVAL;
5112 +
5113 +       if (instr->len & (mtd->erasesize -1))
5114 +               return -EINVAL;
5115 +
5116 +       if ((instr->len + instr->addr) > mtd->size)
5117 +               return -EINVAL;
5118 +
5119 +       chipnum = instr->addr >> cfi->chipshift;
5120 +       adr = instr->addr - (chipnum << cfi->chipshift);
5121 +       len = instr->len;
5122 +
5123 +       while(len) {
5124 +               ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
5125 +
5126 +               if (ret)
5127 +                       return ret;
5128 +
5129 +               adr += mtd->erasesize;
5130 +               len -= mtd->erasesize;
5131 +
5132 +               if (adr >> cfi->chipshift) {
5133 +                       adr = 0;
5134 +                       chipnum++;
5135 +                       
5136 +                       if (chipnum >= cfi->numchips)
5137 +                       break;
5138 +               }
5139 +       }
5140 +               
5141 +       instr->state = MTD_ERASE_DONE;
5142 +       if (instr->callback)
5143 +               instr->callback(instr);
5144 +       
5145 +       return 0;
5146 +}
5147 +
5148 +static void cfi_sststd_sync (struct mtd_info *mtd)
5149 +{
5150 +       struct map_info *map = mtd->priv;
5151 +       struct cfi_private *cfi = map->fldrv_priv;
5152 +       int i;
5153 +       struct flchip *chip;
5154 +       int ret = 0;
5155 +       DECLARE_WAITQUEUE(wait, current);
5156 +
5157 +       for (i=0; !ret && i<cfi->numchips; i++) {
5158 +               chip = &cfi->chips[i];
5159 +
5160 +       retry:
5161 +               cfi_spin_lock(chip->mutex);
5162 +
5163 +               switch(chip->state) {
5164 +               case FL_READY:
5165 +               case FL_STATUS:
5166 +               case FL_CFI_QUERY:
5167 +               case FL_JEDEC_QUERY:
5168 +                       chip->oldstate = chip->state;
5169 +                       chip->state = FL_SYNCING;
5170 +                       /* No need to wake_up() on this state change - 
5171 +                        * as the whole point is that nobody can do anything
5172 +                        * with the chip now anyway.
5173 +                        */
5174 +               case FL_SYNCING:
5175 +                       cfi_spin_unlock(chip->mutex);
5176 +                       break;
5177 +
5178 +               default:
5179 +                       /* Not an idle state */
5180 +                       add_wait_queue(&chip->wq, &wait);
5181 +                       
5182 +                       cfi_spin_unlock(chip->mutex);
5183 +
5184 +                       schedule();
5185 +
5186 +                       remove_wait_queue(&chip->wq, &wait);
5187 +                       
5188 +                       goto retry;
5189 +               }
5190 +       }
5191 +
5192 +       /* Unlock the chips again */
5193 +
5194 +       for (i--; i >=0; i--) {
5195 +               chip = &cfi->chips[i];
5196 +
5197 +               cfi_spin_lock(chip->mutex);
5198 +               
5199 +               if (chip->state == FL_SYNCING) {
5200 +                       chip->state = chip->oldstate;
5201 +                       wake_up(&chip->wq);
5202 +               }
5203 +               cfi_spin_unlock(chip->mutex);
5204 +       }
5205 +}
5206 +
5207 +
5208 +static int cfi_sststd_suspend(struct mtd_info *mtd)
5209 +{
5210 +       struct map_info *map = mtd->priv;
5211 +       struct cfi_private *cfi = map->fldrv_priv;
5212 +       int i;
5213 +       struct flchip *chip;
5214 +       int ret = 0;
5215 +//printk("suspend\n");
5216 +
5217 +       for (i=0; !ret && i<cfi->numchips; i++) {
5218 +               chip = &cfi->chips[i];
5219 +
5220 +               cfi_spin_lock(chip->mutex);
5221 +
5222 +               switch(chip->state) {
5223 +               case FL_READY:
5224 +               case FL_STATUS:
5225 +               case FL_CFI_QUERY:
5226 +               case FL_JEDEC_QUERY:
5227 +                       chip->oldstate = chip->state;
5228 +                       chip->state = FL_PM_SUSPENDED;
5229 +                       /* No need to wake_up() on this state change - 
5230 +                        * as the whole point is that nobody can do anything
5231 +                        * with the chip now anyway.
5232 +                        */
5233 +               case FL_PM_SUSPENDED:
5234 +                       break;
5235 +
5236 +               default:
5237 +                       ret = -EAGAIN;
5238 +                       break;
5239 +               }
5240 +               cfi_spin_unlock(chip->mutex);
5241 +       }
5242 +
5243 +       /* Unlock the chips again */
5244 +
5245 +       if (ret) {
5246 +               for (i--; i >=0; i--) {
5247 +                       chip = &cfi->chips[i];
5248 +
5249 +                       cfi_spin_lock(chip->mutex);
5250 +               
5251 +                       if (chip->state == FL_PM_SUSPENDED) {
5252 +                               chip->state = chip->oldstate;
5253 +                               wake_up(&chip->wq);
5254 +                       }
5255 +                       cfi_spin_unlock(chip->mutex);
5256 +               }
5257 +       }
5258 +       
5259 +       return ret;
5260 +}
5261 +
5262 +static void cfi_sststd_resume(struct mtd_info *mtd)
5263 +{
5264 +       struct map_info *map = mtd->priv;
5265 +       struct cfi_private *cfi = map->fldrv_priv;
5266 +       int i;
5267 +       struct flchip *chip;
5268 +//printk("resume\n");
5269 +
5270 +       for (i=0; i<cfi->numchips; i++) {
5271 +       
5272 +               chip = &cfi->chips[i];
5273 +
5274 +               cfi_spin_lock(chip->mutex);
5275 +               
5276 +               if (chip->state == FL_PM_SUSPENDED) {
5277 +                       chip->state = FL_READY;
5278 +                       cfi_write(map, CMD(0xF0), chip->start);
5279 +                       wake_up(&chip->wq);
5280 +               }
5281 +               else
5282 +                       printk("Argh. Chip not in PM_SUSPENDED state upon resume()\n");
5283 +
5284 +               cfi_spin_unlock(chip->mutex);
5285 +       }
5286 +}
5287 +
5288 +static void cfi_sststd_destroy(struct mtd_info *mtd)
5289 +{
5290 +       struct map_info *map = mtd->priv;
5291 +       struct cfi_private *cfi = map->fldrv_priv;
5292 +       kfree(cfi->cmdset_priv);
5293 +       kfree(cfi);
5294 +}
5295 +
5296 +#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
5297 +#define cfi_sststd_init init_module
5298 +#define cfi_sststd_exit cleanup_module
5299 +#endif
5300 +
5301 +static char im_name[]="cfi_cmdset_0701";
5302 +
5303 +mod_init_t cfi_sststd_init(void)
5304 +{
5305 +       inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0701);
5306 +       return 0;
5307 +}
5308 +
5309 +mod_exit_t cfi_sststd_exit(void)
5310 +{
5311 +       inter_module_unregister(im_name);
5312 +}
5313 +
5314 +module_init(cfi_sststd_init);
5315 +module_exit(cfi_sststd_exit);
5316 +
5317 --- linux-2.4.20/drivers/mtd/chips/cfi_probe.c~2.4.20_broadcom_3_37_2_1109_US.patch     2005-01-07 05:38:15.000000000 -0500
5318 +++ linux-2.4.20/drivers/mtd/chips/cfi_probe.c  2005-01-07 05:39:02.000000000 -0500
5319 @@ -58,8 +58,15 @@
5320         cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
5321         cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
5322  
5323 +       if (!qry_present(map,base,cfi)) {
5324 +               /* rather broken SST cfi probe (requires SST unlock) */
5325 +               cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
5326 +               cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
5327 +               cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
5328 +               cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
5329         if (!qry_present(map,base,cfi))
5330                 return 0;
5331 +       }
5332  
5333         if (!cfi->numchips) {
5334                 /* This is the first time we're called. Set up the CFI 
5335 --- linux-2.4.20/drivers/mtd/chips/gen_probe.c~2.4.20_broadcom_3_37_2_1109_US.patch     2005-01-07 05:38:15.000000000 -0500
5336 +++ linux-2.4.20/drivers/mtd/chips/gen_probe.c  2005-01-07 05:39:02.000000000 -0500
5337 @@ -289,6 +289,10 @@
5338         case 0x0002:
5339                 return cfi_cmdset_0002(map, primary);
5340  #endif
5341 +#ifdef CONFIG_MTD_CFI_SSTSTD
5342 +       case 0x0701:
5343 +               return cfi_cmdset_0701(map, primary);
5344 +#endif
5345         }
5346  
5347         return cfi_cmdset_unknown(map, primary);
5348 --- linux-2.4.20/drivers/mtd/devices/Config.in~2.4.20_broadcom_3_37_2_1109_US.patch     2005-01-07 05:39:01.000000000 -0500
5349 +++ linux-2.4.20/drivers/mtd/devices/Config.in  2005-01-07 05:39:02.000000000 -0500
5350 @@ -5,6 +5,7 @@
5351  mainmenu_option next_comment
5352  
5353  comment 'Self-contained MTD device drivers'
5354 +bool '  Broadcom Chipcommon Serial Flash support' CONFIG_MTD_SFLASH
5355  dep_tristate '  Ramix PMC551 PCI Mezzanine RAM card support' CONFIG_MTD_PMC551 $CONFIG_MTD $CONFIG_PCI
5356  if [ "$CONFIG_MTD_PMC551" = "y" -o  "$CONFIG_MTD_PMC551" = "m" ]; then
5357     bool '    PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX
5358 --- linux-2.4.20/drivers/mtd/devices/Makefile~2.4.20_broadcom_3_37_2_1109_US.patch      2005-01-07 05:38:15.000000000 -0500
5359 +++ linux-2.4.20/drivers/mtd/devices/Makefile   2005-01-07 05:39:02.000000000 -0500
5360 @@ -12,6 +12,7 @@
5361  # here where previously there was none.  We now have to ensure that
5362  # doc200[01].o are linked before docprobe.o
5363  
5364 +obj-$(CONFIG_MTD_SFLASH)       += sflash.o
5365  obj-$(CONFIG_MTD_DOC1000)      += doc1000.o
5366  obj-$(CONFIG_MTD_DOC2000)      += doc2000.o
5367  obj-$(CONFIG_MTD_DOC2001)      += doc2001.o
5368 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
5369 +++ linux-2.4.20/drivers/mtd/devices/sflash.c   2005-01-07 05:39:02.000000000 -0500
5370 @@ -0,0 +1,283 @@
5371 +/*
5372 + * Broadcom SiliconBackplane chipcommon serial flash interface
5373 + *
5374 + * Copyright 2004, Broadcom Corporation      
5375 + * All Rights Reserved.      
5376 + *       
5377 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY      
5378 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM      
5379 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS      
5380 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.      
5381 + *
5382 + * $Id: sflash.c,v 1.1.1.7 2004/04/12 04:31:46 honor Exp $
5383 + */
5384 +
5385 +#include <linux/config.h>
5386 +#include <linux/module.h>
5387 +#include <linux/slab.h>
5388 +#include <linux/ioport.h>
5389 +#include <linux/mtd/compatmac.h>
5390 +#include <linux/mtd/mtd.h>
5391 +#include <linux/mtd/partitions.h>
5392 +#include <linux/errno.h>
5393 +#include <linux/pci.h>
5394 +#include <asm/io.h>
5395 +
5396 +#include <typedefs.h>
5397 +#include <bcmdevs.h>
5398 +#include <bcmutils.h>
5399 +#include <osl.h>
5400 +#include <bcmutils.h>
5401 +#include <bcmnvram.h>
5402 +#include <sbconfig.h>
5403 +#include <sbchipc.h>
5404 +#include <sflash.h>
5405 +
5406 +#ifdef CONFIG_MTD_PARTITIONS
5407 +extern struct mtd_partition * init_mtd_partitions(struct mtd_info *mtd, size_t size);
5408 +#endif
5409 +
5410 +struct sflash_mtd {
5411 +       chipcregs_t *cc;
5412 +       struct semaphore lock;
5413 +       struct mtd_info mtd;
5414 +       struct mtd_erase_region_info region;
5415 +};
5416 +
5417 +/* Private global state */
5418 +static struct sflash_mtd sflash;
5419 +
5420 +static int
5421 +sflash_mtd_poll(struct sflash_mtd *sflash, unsigned int offset, int timeout)
5422 +{
5423 +       int now = jiffies;
5424 +       int ret = 0;
5425 +
5426 +       for (;;) {
5427 +               if (!sflash_poll(sflash->cc, offset)) {
5428 +                       ret = 0;
5429 +                       break;
5430 +               }
5431 +               if (time_after(jiffies, now + timeout)) {
5432 +                       printk(KERN_ERR "sflash: timeout\n");
5433 +                       ret = -ETIMEDOUT;
5434 +                       break;
5435 +               }
5436 +               if (current->need_resched) {
5437 +                       set_current_state(TASK_UNINTERRUPTIBLE);
5438 +                       schedule_timeout(timeout / 10);
5439 +               } else
5440 +                       udelay(1);
5441 +       }
5442 +
5443 +       return ret;
5444 +}
5445 +
5446 +static int
5447 +sflash_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
5448 +{
5449 +       struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
5450 +       int bytes, ret = 0;
5451 +
5452 +       /* Check address range */
5453 +       if (!len)
5454 +               return 0;
5455 +       if ((from + len) > mtd->size)
5456 +               return -EINVAL;
5457 +       
5458 +       down(&sflash->lock);
5459 +
5460 +       *retlen = 0;
5461 +       while (len) {
5462 +               if ((bytes = sflash_read(sflash->cc, (uint) from, len, buf)) < 0) {
5463 +                       ret = bytes;
5464 +                       break;
5465 +               }
5466 +               from += (loff_t) bytes;
5467 +               len -= bytes;
5468 +               buf += bytes;
5469 +               *retlen += bytes;
5470 +       }
5471 +
5472 +       up(&sflash->lock);
5473 +
5474 +       return ret;
5475 +}
5476 +
5477 +static int
5478 +sflash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
5479 +{
5480 +       struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
5481 +       int bytes, ret = 0;
5482 +
5483 +       /* Check address range */
5484 +       if (!len)
5485 +               return 0;
5486 +       if ((to + len) > mtd->size)
5487 +               return -EINVAL;
5488 +
5489 +       down(&sflash->lock);
5490 +
5491 +       *retlen = 0;
5492 +       while (len) {
5493 +               if ((bytes = sflash_write(sflash->cc, (uint) to, len, buf)) < 0) {
5494 +                       ret = bytes;
5495 +                       break;
5496 +               }
5497 +               if ((ret = sflash_mtd_poll(sflash, (unsigned int) to, HZ / 10)))
5498 +                       break;
5499 +               to += (loff_t) bytes;
5500 +               len -= bytes;
5501 +               buf += bytes;
5502 +               *retlen += bytes;
5503 +       }
5504 +
5505 +       up(&sflash->lock);
5506 +
5507 +       return ret;
5508 +}
5509 +
5510 +static int
5511 +sflash_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
5512 +{
5513 +       struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
5514 +       int i, j, ret = 0;
5515 +       unsigned int addr, len;
5516 +
5517 +       /* Check address range */
5518 +       if (!erase->len)
5519 +               return 0;
5520 +       if ((erase->addr + erase->len) > mtd->size)
5521 +               return -EINVAL;
5522 +
5523 +       addr = erase->addr;
5524 +       len = erase->len;
5525 +
5526 +       down(&sflash->lock);
5527 +
5528 +       /* Ensure that requested region is aligned */
5529 +       for (i = 0; i < mtd->numeraseregions; i++) {
5530 +               for (j = 0; j < mtd->eraseregions[i].numblocks; j++) {
5531 +                       if (addr == mtd->eraseregions[i].offset + mtd->eraseregions[i].erasesize * j &&
5532 +                           len >= mtd->eraseregions[i].erasesize) {
5533 +                               if ((ret = sflash_erase(sflash->cc, addr)) < 0)
5534 +                                       break;
5535 +                               if ((ret = sflash_mtd_poll(sflash, addr, 10 * HZ)))
5536 +                                       break;
5537 +                               addr += mtd->eraseregions[i].erasesize;
5538 +                               len -= mtd->eraseregions[i].erasesize;
5539 +                       }
5540 +               }
5541 +               if (ret)
5542 +                       break;
5543 +       }
5544 +
5545 +       up(&sflash->lock);
5546 +
5547 +       /* Set erase status */
5548 +       if (ret)
5549 +               erase->state = MTD_ERASE_FAILED;
5550 +       else 
5551 +               erase->state = MTD_ERASE_DONE;
5552 +
5553 +       /* Call erase callback */
5554 +       if (erase->callback)
5555 +               erase->callback(erase);
5556 +
5557 +       return ret;
5558 +}
5559 +
5560 +#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
5561 +#define sflash_mtd_init init_module
5562 +#define sflash_mtd_exit cleanup_module
5563 +#endif
5564 +
5565 +mod_init_t
5566 +sflash_mtd_init(void)
5567 +{
5568 +       struct pci_dev *pdev;
5569 +       int ret = 0;
5570 +       struct sflash *info;
5571 +       uint i;
5572 +#ifdef CONFIG_MTD_PARTITIONS
5573 +       struct mtd_partition *parts;
5574 +#endif
5575 +
5576 +       if (!(pdev = pci_find_device(VENDOR_BROADCOM, SB_CC, NULL))) {
5577 +               printk(KERN_ERR "sflash: chipcommon not found\n");
5578 +               return -ENODEV;
5579 +       }
5580 +
5581 +       memset(&sflash, 0, sizeof(struct sflash_mtd));
5582 +       init_MUTEX(&sflash.lock);
5583 +
5584 +       /* Map registers and flash base */
5585 +       if (!(sflash.cc = ioremap_nocache(pci_resource_start(pdev, 0),
5586 +                                         pci_resource_len(pdev, 0)))) {
5587 +               printk(KERN_ERR "sflash: error mapping registers\n");
5588 +               ret = -EIO;
5589 +               goto fail;
5590 +       }
5591 +
5592 +       /* Initialize serial flash access */
5593 +       info = sflash_init(sflash.cc);
5594 +
5595 +       if (!info) {
5596 +               printk(KERN_ERR "sflash: found no supported devices\n");
5597 +               ret = -ENODEV;
5598 +               goto fail;
5599 +       }
5600 +
5601 +       /* Setup region info */
5602 +       sflash.region.offset = 0;
5603 +       sflash.region.erasesize = info->blocksize;
5604 +       sflash.region.numblocks = info->numblocks;
5605 +       if (sflash.region.erasesize > sflash.mtd.erasesize)
5606 +               sflash.mtd.erasesize = sflash.region.erasesize;
5607 +       sflash.mtd.size = info->size;
5608 +       sflash.mtd.numeraseregions = 1;
5609 +
5610 +       /* Register with MTD */
5611 +       sflash.mtd.name = "sflash";
5612 +       sflash.mtd.type = MTD_NORFLASH;
5613 +       sflash.mtd.flags = MTD_CAP_NORFLASH;
5614 +       sflash.mtd.eraseregions = &sflash.region;
5615 +       sflash.mtd.module = THIS_MODULE;
5616 +       sflash.mtd.erase = sflash_mtd_erase;
5617 +       sflash.mtd.read = sflash_mtd_read;
5618 +       sflash.mtd.write = sflash_mtd_write;
5619 +       sflash.mtd.priv = &sflash;
5620 +
5621 +#ifdef CONFIG_MTD_PARTITIONS
5622 +       parts = init_mtd_partitions(&sflash.mtd, sflash.mtd.size);
5623 +       for (i = 0; parts[i].name; i++);
5624 +       ret = add_mtd_partitions(&sflash.mtd, parts, i);
5625 +#else
5626 +       ret = add_mtd_device(&sflash.mtd);
5627 +#endif
5628 +       if (ret) {
5629 +               printk(KERN_ERR "sflash: add_mtd failed\n");
5630 +               goto fail;
5631 +       }
5632 +
5633 +       return 0;
5634 +
5635 + fail:
5636 +       if (sflash.cc)
5637 +               iounmap((void *) sflash.cc);
5638 +       return ret;
5639 +}
5640 +
5641 +mod_exit_t
5642 +sflash_mtd_exit(void)
5643 +{
5644 +#ifdef CONFIG_MTD_PARTITIONS
5645 +       del_mtd_partitions(&sflash.mtd);
5646 +#else
5647 +       del_mtd_device(&sflash.mtd);
5648 +#endif
5649 +       iounmap((void *) sflash.cc);
5650 +}
5651 +
5652 +module_init(sflash_mtd_init);
5653 +module_exit(sflash_mtd_exit);
5654 --- linux-2.4.20/drivers/mtd/maps/Config.in~2.4.20_broadcom_3_37_2_1109_US.patch        2005-01-07 05:39:01.000000000 -0500
5655 +++ linux-2.4.20/drivers/mtd/maps/Config.in     2005-01-07 05:39:02.000000000 -0500
5656 @@ -44,6 +44,7 @@
5657  fi
5658  
5659  if [ "$CONFIG_MIPS" = "y" ]; then
5660 +   dep_tristate '  CFI Flash device mapped on Broadcom BCM947XX boards' CONFIG_MTD_BCM947XX $CONFIG_MTD_CFI
5661     dep_tristate '  Pb1000 boot flash device' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000
5662     dep_tristate '  Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500
5663     dep_tristate '  Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100
5664 --- linux-2.4.20/drivers/mtd/maps/Makefile~2.4.20_broadcom_3_37_2_1109_US.patch 2005-01-07 05:39:01.000000000 -0500
5665 +++ linux-2.4.20/drivers/mtd/maps/Makefile      2005-01-07 05:39:02.000000000 -0500
5666 @@ -6,6 +6,7 @@
5667  O_TARGET       := mapslink.o
5668  
5669  # Chip mappings
5670 +obj-$(CONFIG_MTD_BCM947XX)      += bcm947xx-flash.o
5671  obj-$(CONFIG_MTD_CDB89712)      += cdb89712.o
5672  obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
5673  obj-$(CONFIG_MTD_CFI_FLAGADM)  += cfi_flagadm.o
5674 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
5675 +++ linux-2.4.20/drivers/mtd/maps/bcm947xx-flash.c      2005-01-08 12:16:21.889534944 -0500
5676 @@ -0,0 +1,225 @@
5677 +/*
5678 + * Flash mapping for BCM947XX boards
5679 + *
5680 + * Copyright 2004, Broadcom Corporation
5681 + * All Rights Reserved.
5682 + * 
5683 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
5684 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
5685 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
5686 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
5687 + *
5688 + * $Id: bcm947xx-flash.c,v 1.8 2004/04/12 05:42:38 honor Exp $
5689 + */
5690 +
5691 +#include <linux/module.h>
5692 +#include <linux/types.h>
5693 +#include <linux/kernel.h>
5694 +#include <asm/io.h>
5695 +#include <linux/mtd/mtd.h>
5696 +#include <linux/mtd/map.h>
5697 +#include <linux/mtd/partitions.h>
5698 +#include <linux/config.h>
5699 +
5700 +#include <typedefs.h>
5701 +#include <bcmnvram.h>
5702 +#include <bcmutils.h>
5703 +#include <sbconfig.h>
5704 +#include <sbchipc.h>
5705 +#include <sbutils.h>
5706 +#include <trxhdr.h>
5707 +
5708 +/* Global SB handle */
5709 +extern void *bcm947xx_sbh;
5710 +extern spinlock_t bcm947xx_sbh_lock;
5711 +
5712 +/* Convenience */
5713 +#define sbh bcm947xx_sbh
5714 +#define sbh_lock bcm947xx_sbh_lock
5715 +
5716 +#ifdef CONFIG_MTD_PARTITIONS
5717 +extern struct mtd_partition * init_mtd_partitions(struct mtd_info *mtd, size_t size);
5718 +#endif
5719 +
5720 +#define WINDOW_ADDR 0x1fc00000
5721 +#define WINDOW_SIZE 0x400000
5722 +#define BUSWIDTH 2
5723 +
5724 +/* e.g., flash=2M or flash=4M */
5725 +static int flash = 0;
5726 +MODULE_PARM(flash, "i");
5727 +static int __init
5728 +bcm947xx_setup(char *str)
5729 +{
5730 +       flash = memparse(str, &str);
5731 +       return 1;
5732 +}
5733 +__setup("flash=", bcm947xx_setup);
5734 +
5735 +static struct mtd_info *bcm947xx_mtd;
5736 +
5737 +__u8 bcm947xx_map_read8(struct map_info *map, unsigned long ofs)
5738 +{
5739 +       if (map->map_priv_2 == 1)
5740 +               return __raw_readb(map->map_priv_1 + ofs);
5741 +
5742 +       u16 val = __raw_readw(map->map_priv_1 + (ofs & ~1));
5743 +       if (ofs & 1)
5744 +               return ((val >> 8) & 0xff);
5745 +       else
5746 +               return (val & 0xff);
5747 +}
5748 +
5749 +__u16 bcm947xx_map_read16(struct map_info *map, unsigned long ofs)
5750 +{
5751 +       return __raw_readw(map->map_priv_1 + ofs);
5752 +}
5753 +
5754 +__u32 bcm947xx_map_read32(struct map_info *map, unsigned long ofs)
5755 +{
5756 +       return __raw_readl(map->map_priv_1 + ofs);
5757 +}
5758 +
5759 +void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
5760 +{
5761 +       memcpy_fromio(to, map->map_priv_1 + from, len);
5762 +}
5763 +
5764 +void bcm947xx_map_write8(struct map_info *map, __u8 d, unsigned long adr)
5765 +{
5766 +       __raw_writeb(d, map->map_priv_1 + adr);
5767 +       mb();
5768 +}
5769 +
5770 +void bcm947xx_map_write16(struct map_info *map, __u16 d, unsigned long adr)
5771 +{
5772 +       __raw_writew(d, map->map_priv_1 + adr);
5773 +       mb();
5774 +}
5775 +
5776 +void bcm947xx_map_write32(struct map_info *map, __u32 d, unsigned long adr)
5777 +{
5778 +       __raw_writel(d, map->map_priv_1 + adr);
5779 +       mb();
5780 +}
5781 +
5782 +void bcm947xx_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
5783 +{
5784 +       memcpy_toio(map->map_priv_1 + to, from, len);
5785 +}
5786 +
5787 +struct map_info bcm947xx_map = {
5788 +       name: "Physically mapped flash",
5789 +       size: WINDOW_SIZE,
5790 +       buswidth: BUSWIDTH,
5791 +       read8: bcm947xx_map_read8,
5792 +       read16: bcm947xx_map_read16,
5793 +       read32: bcm947xx_map_read32,
5794 +       copy_from: bcm947xx_map_copy_from,
5795 +       write8: bcm947xx_map_write8,
5796 +       write16: bcm947xx_map_write16,
5797 +       write32: bcm947xx_map_write32,
5798 +       copy_to: bcm947xx_map_copy_to
5799 +};
5800 +
5801 +#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
5802 +#define init_bcm947xx_map init_module
5803 +#define cleanup_bcm947xx_map cleanup_module
5804 +#endif
5805 +
5806 +mod_init_t init_bcm947xx_map(void)
5807 +{
5808 +       ulong flags;
5809 +       uint coreidx;
5810 +       chipcregs_t *cc;
5811 +       uint32 fltype;
5812 +       uint window_addr = 0, window_size = 0;
5813 +       size_t size;
5814 +       int ret = 0;
5815 +#ifdef CONFIG_MTD_PARTITIONS
5816 +       struct mtd_partition *parts;
5817 +       int i;
5818 +#endif
5819 +
5820 +       spin_lock_irqsave(&sbh_lock, flags);
5821 +       coreidx = sb_coreidx(sbh);
5822 +
5823 +       /* Check strapping option if chipcommon exists */
5824 +       if ((cc = sb_setcore(sbh, SB_CC, 0))) {
5825 +               fltype = readl(&cc->capabilities) & CAP_FLASH_MASK;
5826 +               if (fltype == PFLASH) {
5827 +                       bcm947xx_map.map_priv_2 = 1;
5828 +                       window_addr = 0x1c000000;
5829 +                       bcm947xx_map.size = window_size = 32 * 1024 * 1024;
5830 +                       if ((readl(&cc->flash_config) & CC_CFG_DS) == 0)
5831 +                               bcm947xx_map.buswidth = 1;
5832 +               }
5833 +       } else {
5834 +               fltype = PFLASH;
5835 +               bcm947xx_map.map_priv_2 = 0;
5836 +               window_addr = WINDOW_ADDR;
5837 +               window_size = WINDOW_SIZE;
5838 +       }
5839 +
5840 +       sb_setcoreidx(sbh, coreidx);
5841 +       spin_unlock_irqrestore(&sbh_lock, flags);
5842 +
5843 +       if (fltype != PFLASH) {
5844 +               printk(KERN_ERR "pflash: found no supported devices\n");
5845 +               ret = -ENODEV;
5846 +               goto fail;
5847 +       }
5848 +
5849 +       bcm947xx_map.map_priv_1 = (unsigned long) ioremap(window_addr, window_size);
5850 +       if (!bcm947xx_map.map_priv_1) {
5851 +               printk(KERN_ERR "pflash: ioremap failed\n");
5852 +               ret = -EIO;
5853 +               goto fail;
5854 +       }
5855 +
5856 +       if (!(bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map))) {
5857 +               printk(KERN_ERR "pflash: cfi_probe failed\n");
5858 +               ret = -ENXIO;
5859 +               goto fail;
5860 +       }
5861 +
5862 +       bcm947xx_mtd->module = THIS_MODULE;
5863 +
5864 +       /* Allow size override for testing */
5865 +       size = flash ? : bcm947xx_mtd->size;
5866 +
5867 +       printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, window_addr);
5868 +
5869 +#ifdef CONFIG_MTD_PARTITIONS
5870 +       parts = init_mtd_partitions(bcm947xx_mtd, size);
5871 +       for (i = 0; parts[i].name; i++);
5872 +       ret = add_mtd_partitions(bcm947xx_mtd, parts, i);
5873 +       if (ret) {
5874 +               printk(KERN_ERR "pflash: add_mtd_partitions failed\n");
5875 +               goto fail;
5876 +       }
5877 +#endif
5878 +
5879 +       return 0;
5880 +
5881 + fail:
5882 +       if (bcm947xx_mtd)
5883 +               map_destroy(bcm947xx_mtd);
5884 +       if (bcm947xx_map.map_priv_1)
5885 +               iounmap((void *) bcm947xx_map.map_priv_1);
5886 +       bcm947xx_map.map_priv_1 = 0;
5887 +       return ret;
5888 +}
5889 +
5890 +mod_exit_t cleanup_bcm947xx_map(void)
5891 +{
5892 +#ifdef CONFIG_MTD_PARTITIONS
5893 +       del_mtd_partitions(bcm947xx_mtd);
5894 +#endif
5895 +       map_destroy(bcm947xx_mtd);
5896 +       iounmap((void *) bcm947xx_map.map_priv_1);
5897 +       bcm947xx_map.map_priv_1 = 0;
5898 +}
5899 +
5900 +module_init(init_bcm947xx_map);
5901 +module_exit(cleanup_bcm947xx_map);
5902 --- linux-2.4.20/drivers/mtd/mtdblock_ro.c~2.4.20_broadcom_3_37_2_1109_US.patch 2005-01-07 05:38:15.000000000 -0500
5903 +++ linux-2.4.20/drivers/mtd/mtdblock_ro.c      2005-01-08 12:16:19.492899288 -0500
5904 @@ -1,18 +1,16 @@
5905  /*
5906 - * $Id: mtdblock_ro.c,v 1.12 2001/11/20 11:42:33 dwmw2 Exp $
5907 + * Direct MTD block device access
5908   *
5909 - * Read-only version of the mtdblock device, without the 
5910 - * read/erase/modify/writeback stuff
5911 + * $Id: mtdblock_ro.c,v 1.1.1.4 2003/10/14 08:08:16 sparq Exp $
5912 + *
5913 + * 02-nov-2000 Nicolas Pitre           Added read-modify-write with cache
5914   */
5915  
5916 -#ifdef MTDBLOCK_DEBUG
5917 -#define DEBUGLVL debug
5918 -#endif                                                        
5919 -
5920 -
5921 -#include <linux/module.h>
5922 +#include <linux/config.h>
5923  #include <linux/types.h>
5924 -
5925 +#include <linux/module.h>
5926 +#include <linux/kernel.h>
5927 +#include <linux/slab.h>
5928  #include <linux/mtd/mtd.h>
5929  #include <linux/mtd/compatmac.h>
5930  
5931 @@ -24,56 +22,106 @@
5932  #define DEVICE_OFF(device)
5933  #define DEVICE_NO_RANDOM
5934  #include <linux/blk.h>
5935 -
5936 +/* for old kernels... */
5937 +#ifndef QUEUE_EMPTY
5938 +#define QUEUE_EMPTY  (!CURRENT)
5939 +#endif
5940  #if LINUX_VERSION_CODE < 0x20300
5941 -#define RQFUNC_ARG void
5942 -#define blkdev_dequeue_request(req) do {CURRENT = req->next;} while (0)
5943 +#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].plug_tq.sync)
5944  #else
5945 -#define RQFUNC_ARG request_queue_t *q
5946 +#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].request_queue.plugged)
5947  #endif
5948  
5949 -#ifdef MTDBLOCK_DEBUG
5950 -static int debug = MTDBLOCK_DEBUG;
5951 -MODULE_PARM(debug, "i");
5952 +#ifdef CONFIG_DEVFS_FS
5953 +#include <linux/devfs_fs_kernel.h>
5954 +static void mtd_notify_add(struct mtd_info* mtd);
5955 +static void mtd_notify_remove(struct mtd_info* mtd);
5956 +static struct mtd_notifier notifier = {
5957 +        mtd_notify_add,
5958 +        mtd_notify_remove,
5959 +        NULL
5960 +};
5961 +static devfs_handle_t devfs_dir_handle = NULL;
5962 +static devfs_handle_t devfs_ro_handle[MAX_MTD_DEVICES];
5963  #endif
5964  
5965 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
5966 -#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
5967 -#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
5968 -#else
5969 -#define BLK_INC_USE_COUNT do {} while(0)
5970 -#define BLK_DEC_USE_COUNT do {} while(0)
5971 -#endif
5972 +static struct mtdblk_dev {
5973 +       struct mtd_info *mtd; /* Locked */
5974 +       int count;
5975 +} *mtdblks[MAX_MTD_DEVICES];
5976  
5977 -static int mtd_sizes[MAX_MTD_DEVICES];
5978 +static spinlock_t mtdblks_lock;
5979  
5980 +static int mtd_sizes[MAX_MTD_DEVICES];
5981  
5982  static int mtdblock_open(struct inode *inode, struct file *file)
5983  {
5984 -       struct mtd_info *mtd = NULL;
5985 -
5986 +       struct mtdblk_dev *mtdblk;
5987 +       struct mtd_info *mtd;
5988         int dev;
5989  
5990 -       DEBUG(1,"mtdblock_open\n");
5991 +       DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
5992         
5993 -       if (inode == 0)
5994 +       if (!inode)
5995                 return -EINVAL;
5996         
5997         dev = MINOR(inode->i_rdev);
5998 +       if (dev >= MAX_MTD_DEVICES)
5999 +               return -EINVAL;
6000         
6001         mtd = get_mtd_device(NULL, dev);
6002         if (!mtd)
6003 -               return -EINVAL;
6004 +               return -ENODEV;
6005         if (MTD_ABSENT == mtd->type) {
6006                 put_mtd_device(mtd);
6007 -               return -EINVAL;
6008 +               return -ENODEV;
6009         }
6010  
6011 -       BLK_INC_USE_COUNT;
6012 +       spin_lock(&mtdblks_lock);
6013  
6014 -       mtd_sizes[dev] = mtd->size>>9;
6015 +       /* If it's already open, no need to piss about. */
6016 +       if (mtdblks[dev]) {
6017 +               mtdblks[dev]->count++;
6018 +               spin_unlock(&mtdblks_lock);
6019 +               return 0;
6020 +       }
6021  
6022 -       DEBUG(1, "ok\n");
6023 +       /* OK, it's not open. Try to find it */
6024 +
6025 +       /* First we have to drop the lock, because we have to
6026 +          to things which might sleep.
6027 +       */
6028 +       spin_unlock(&mtdblks_lock);
6029 +
6030 +       mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
6031 +       if (!mtdblk) {
6032 +               put_mtd_device(mtd);
6033 +               return -ENOMEM;
6034 +       }
6035 +       memset(mtdblk, 0, sizeof(*mtdblk));
6036 +       mtdblk->count = 1;
6037 +       mtdblk->mtd = mtd;
6038 +
6039 +       /* OK, we've created a new one. Add it to the list. */
6040 +
6041 +       spin_lock(&mtdblks_lock);
6042 +
6043 +       if (mtdblks[dev]) {
6044 +               /* Another CPU made one at the same time as us. */
6045 +               mtdblks[dev]->count++;
6046 +               spin_unlock(&mtdblks_lock);
6047 +               put_mtd_device(mtdblk->mtd);
6048 +               kfree(mtdblk);
6049 +               return 0;
6050 +       }
6051 +
6052 +       mtdblks[dev] = mtdblk;
6053 +       mtd_sizes[dev] = mtdblk->mtd->size/1024;
6054 +       set_device_ro (inode->i_rdev, !(mtdblk->mtd->flags & MTD_WRITEABLE));
6055 +       
6056 +       spin_unlock(&mtdblks_lock);
6057 +       
6058 +       DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
6059  
6060         return 0;
6061  }
6062 @@ -81,162 +129,169 @@
6063  static release_t mtdblock_release(struct inode *inode, struct file *file)
6064  {
6065         int dev;
6066 -       struct mtd_info *mtd;
6067 -
6068 -       DEBUG(1, "mtdblock_release\n");
6069 +       struct mtdblk_dev *mtdblk;
6070 +       DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
6071  
6072         if (inode == NULL)
6073                 release_return(-ENODEV);
6074     
6075         dev = MINOR(inode->i_rdev);
6076 -       mtd = __get_mtd_device(NULL, dev);
6077 +       mtdblk = mtdblks[dev];
6078  
6079 -       if (!mtd) {
6080 -               printk(KERN_WARNING "MTD device is absent on mtd_release!\n");
6081 -               BLK_DEC_USE_COUNT;
6082 -               release_return(-ENODEV);
6083 +       spin_lock(&mtdblks_lock);
6084 +       if (!--mtdblk->count) {
6085 +               /* It was the last usage. Free the device */
6086 +               mtdblks[dev] = NULL;
6087 +               spin_unlock(&mtdblks_lock);
6088 +               if (mtdblk->mtd->sync)
6089 +                       mtdblk->mtd->sync(mtdblk->mtd);
6090 +               put_mtd_device(mtdblk->mtd);
6091 +               kfree(mtdblk);
6092 +       } else {
6093 +               spin_unlock(&mtdblks_lock);
6094         }
6095         
6096 -       if (mtd->sync)
6097 -               mtd->sync(mtd);
6098 -
6099 -       put_mtd_device(mtd);
6100 -
6101 -       DEBUG(1, "ok\n");
6102 +       DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
6103  
6104 -       BLK_DEC_USE_COUNT;
6105         release_return(0);
6106  }  
6107  
6108  
6109 -static void mtdblock_request(RQFUNC_ARG)
6110 +/* 
6111 + * This is a special request_fn because it is executed in a process context 
6112 + * to be able to sleep independently of the caller.  The io_request_lock 
6113 + * is held upon entry and exit.
6114 + * The head of our request queue is considered active so there is no need 
6115 + * to dequeue requests before we are done.
6116 + */
6117 +static void handle_mtdblock_request(void)
6118  {
6119 -   struct request *current_request;
6120 -   unsigned int res = 0;
6121 -   struct mtd_info *mtd;
6122 +       struct request *req;
6123 +       struct mtdblk_dev *mtdblk;
6124 +       unsigned int res;
6125  
6126 -   while (1)
6127 -   {
6128 -      /* Grab the Request and unlink it from the request list, INIT_REQUEST
6129 -                will execute a return if we are done. */
6130 +       for (;;) {
6131        INIT_REQUEST;
6132 -      current_request = CURRENT;
6133 -   
6134 -      if (MINOR(current_request->rq_dev) >= MAX_MTD_DEVICES)
6135 -      {
6136 -        printk("mtd: Unsupported device!\n");
6137 -        end_request(0);
6138 -        continue;
6139 -      }
6140 -      
6141 -      // Grab our MTD structure
6142 -
6143 -      mtd = __get_mtd_device(NULL, MINOR(current_request->rq_dev));
6144 -      if (!mtd) {
6145 -             printk("MTD device %d doesn't appear to exist any more\n", CURRENT_DEV);
6146 -             end_request(0);
6147 -      }
6148 +               req = CURRENT;
6149 +               spin_unlock_irq(&io_request_lock);
6150 +               mtdblk = mtdblks[MINOR(req->rq_dev)];
6151 +               res = 0;
6152  
6153 -      if (current_request->sector << 9 > mtd->size ||
6154 -         (current_request->sector + current_request->nr_sectors) << 9 > mtd->size)
6155 -      {
6156 -        printk("mtd: Attempt to read past end of device!\n");
6157 -        printk("size: %x, sector: %lx, nr_sectors %lx\n", mtd->size, current_request->sector, current_request->nr_sectors);
6158 -        end_request(0);
6159 -        continue;
6160 -      }
6161 +               if (MINOR(req->rq_dev) >= MAX_MTD_DEVICES)
6162 +                       panic(__FUNCTION__": minor out of bound");
6163        
6164 -      /* Remove the request we are handling from the request list so nobody messes
6165 -         with it */
6166 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
6167 -      /* Now drop the lock that the ll_rw_blk functions grabbed for us
6168 -         and process the request. This is necessary due to the extreme time
6169 -         we spend processing it. */
6170 -      spin_unlock_irq(&io_request_lock);
6171 -#endif
6172 +               if ((req->sector + req->current_nr_sectors) > (mtdblk->mtd->size >> 9))
6173 +                       goto end_req;
6174  
6175        // Handle the request
6176 -      switch (current_request->cmd)
6177 +               switch (req->cmd)
6178        {
6179 +                       int err;
6180           size_t retlen;
6181  
6182          case READ:
6183 -        if (MTD_READ(mtd,current_request->sector<<9, 
6184 -                     current_request->nr_sectors << 9, 
6185 -                     &retlen, current_request->buffer) == 0)
6186 +                       err = MTD_READ (mtdblk->mtd, req->sector << 9, 
6187 +                                       req->current_nr_sectors << 9,
6188 +                                       &retlen, req->buffer);
6189 +                       if (!err)
6190             res = 1;
6191 -        else
6192 -           res = 0;
6193          break;
6194 +               }
6195          
6196 -        case WRITE:
6197 -
6198 -        /* printk("mtdblock_request WRITE sector=%d(%d)\n",current_request->sector,
6199 -               current_request->nr_sectors);
6200 -        */
6201 -
6202 -        // Read only device
6203 -        if ((mtd->flags & MTD_CAP_RAM) == 0)
6204 -        {
6205 -           res = 0;
6206 -           break;
6207 +end_req:
6208 +               spin_lock_irq(&io_request_lock);
6209 +               end_request(res);
6210          }
6211 +}
6212  
6213 -        // Do the write
6214 -        if (MTD_WRITE(mtd,current_request->sector<<9, 
6215 -                      current_request->nr_sectors << 9, 
6216 -                      &retlen, current_request->buffer) == 0)
6217 -           res = 1;
6218 -        else
6219 -           res = 0;
6220 -        break;
6221 +static volatile int leaving = 0;
6222 +static DECLARE_MUTEX_LOCKED(thread_sem);
6223 +static DECLARE_WAIT_QUEUE_HEAD(thr_wq);
6224          
6225 -        // Shouldn't happen
6226 -        default:
6227 -        printk("mtd: unknown request\n");
6228 -        break;
6229 -      }
6230 +int mtdblock_thread(void *dummy)
6231 +{
6232 +       struct task_struct *tsk = current;
6233 +       DECLARE_WAITQUEUE(wait, tsk);
6234  
6235 -      // Grab the lock and re-thread the item onto the linked list
6236 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
6237 +       tsk->session = 1;
6238 +       tsk->pgrp = 1;
6239 +       /* we might get involved when memory gets low, so use PF_MEMALLOC */
6240 +       tsk->flags |= PF_MEMALLOC;
6241 +       strcpy(tsk->comm, "mtdblockd");
6242 +       tsk->tty = NULL;
6243 +       spin_lock_irq(&tsk->sigmask_lock);
6244 +       sigfillset(&tsk->blocked);
6245 +       recalc_sigpending(tsk);
6246 +       spin_unlock_irq(&tsk->sigmask_lock);
6247 +       exit_mm(tsk);
6248 +       exit_files(tsk);
6249 +       exit_sighand(tsk);
6250 +       exit_fs(tsk);
6251 +
6252 +       while (!leaving) {
6253 +               add_wait_queue(&thr_wq, &wait);
6254 +               set_current_state(TASK_INTERRUPTIBLE);
6255         spin_lock_irq(&io_request_lock);
6256 -#endif
6257 -       end_request(res);
6258 +               if (QUEUE_EMPTY || QUEUE_PLUGGED) {
6259 +                       spin_unlock_irq(&io_request_lock);
6260 +                       schedule();
6261 +                       remove_wait_queue(&thr_wq, &wait); 
6262 +               } else {
6263 +                       remove_wait_queue(&thr_wq, &wait); 
6264 +                       set_current_state(TASK_RUNNING);
6265 +                       handle_mtdblock_request();
6266 +                       spin_unlock_irq(&io_request_lock);
6267 +               }
6268     }
6269 +
6270 +       up(&thread_sem);
6271 +       return 0;
6272  }
6273  
6274 +#if LINUX_VERSION_CODE < 0x20300
6275 +#define RQFUNC_ARG void
6276 +#else
6277 +#define RQFUNC_ARG request_queue_t *q
6278 +#endif
6279 +
6280 +static void mtdblock_request(RQFUNC_ARG)
6281 +{
6282 +       /* Don't do anything, except wake the thread if necessary */
6283 +       wake_up(&thr_wq);
6284 +}
6285  
6286  
6287  static int mtdblock_ioctl(struct inode * inode, struct file * file,
6288                       unsigned int cmd, unsigned long arg)
6289  {
6290 -       struct mtd_info *mtd;
6291 +       struct mtdblk_dev *mtdblk;
6292  
6293 -       mtd = __get_mtd_device(NULL, MINOR(inode->i_rdev));
6294 +       mtdblk = mtdblks[MINOR(inode->i_rdev)];
6295  
6296 -       if (!mtd) return -EINVAL;
6297 +#ifdef PARANOIA
6298 +       if (!mtdblk)
6299 +               BUG();
6300 +#endif
6301  
6302         switch (cmd) {
6303         case BLKGETSIZE:   /* Return device size */
6304 -               return put_user((mtd->size >> 9), (unsigned long *) arg);
6305 -
6306 -#ifdef BLKGETSIZE64
6307 +               return put_user((mtdblk->mtd->size >> 9), (unsigned long *) arg);
6308         case BLKGETSIZE64:
6309 -               return put_user((u64)mtd->size, (u64 *)arg);
6310 -#endif
6311 +               return put_user((u64)mtdblk->mtd->size, (u64 *)arg);
6312  
6313         case BLKFLSBUF:
6314  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
6315 -               if(!capable(CAP_SYS_ADMIN))  return -EACCES;
6316 +               if(!capable(CAP_SYS_ADMIN))
6317 +                       return -EACCES;
6318  #endif
6319                 fsync_dev(inode->i_rdev);
6320                 invalidate_buffers(inode->i_rdev);
6321 -               if (mtd->sync)
6322 -                       mtd->sync(mtd);
6323 +               if (mtdblk->mtd->sync)
6324 +                       mtdblk->mtd->sync(mtdblk->mtd);
6325                 return 0;
6326  
6327         default:
6328 -               return -ENOTTY;
6329 +               return -EINVAL;
6330         }
6331  }
6332  
6333 @@ -261,34 +316,85 @@
6334  };
6335  #endif
6336  
6337 +#ifdef CONFIG_DEVFS_FS
6338 +/* Notification that a new device has been added. Create the devfs entry for
6339 + * it. */
6340 +
6341 +static void mtd_notify_add(struct mtd_info* mtd)
6342 +{
6343 +        char name[8];
6344 +
6345 +        if (!mtd || mtd->type == MTD_ABSENT)
6346 +                return;
6347 +
6348 +        sprintf(name, "%d", mtd->index);
6349 +        devfs_ro_handle[mtd->index] = devfs_register(devfs_dir_handle, name,
6350 +                        DEVFS_FL_DEFAULT, MTD_BLOCK_MAJOR, mtd->index,
6351 +                        S_IFBLK | S_IRUGO | S_IWUGO,
6352 +                        &mtd_fops, NULL);
6353 +}
6354 +
6355 +static void mtd_notify_remove(struct mtd_info* mtd)
6356 +{
6357 +        if (!mtd || mtd->type == MTD_ABSENT)
6358 +                return;
6359 +
6360 +        devfs_unregister(devfs_ro_handle[mtd->index]);
6361 +}
6362 +#endif
6363 +
6364  int __init init_mtdblock(void)
6365  {
6366         int i;
6367  
6368 +       spin_lock_init(&mtdblks_lock);
6369 +#ifdef CONFIG_DEVFS_FS
6370 +       if (devfs_register_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME, &mtd_fops))
6371 +       {
6372 +               printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
6373 +                       MTD_BLOCK_MAJOR);
6374 +               return -EAGAIN;
6375 +       }
6376 +
6377 +       devfs_dir_handle = devfs_mk_dir(NULL, DEVICE_NAME, NULL);
6378 +       register_mtd_user(&notifier);
6379 +#else
6380         if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
6381                 printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
6382                        MTD_BLOCK_MAJOR);
6383                 return -EAGAIN;
6384         }
6385 +#endif
6386         
6387         /* We fill it in at open() time. */
6388         for (i=0; i< MAX_MTD_DEVICES; i++) {
6389                 mtd_sizes[i] = 0;
6390         }
6391 -       
6392 +       init_waitqueue_head(&thr_wq);
6393         /* Allow the block size to default to BLOCK_SIZE. */
6394         blksize_size[MAJOR_NR] = NULL;
6395         blk_size[MAJOR_NR] = mtd_sizes;
6396         
6397         blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
6398 +       kernel_thread (mtdblock_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
6399         return 0;
6400  }
6401  
6402  static void __exit cleanup_mtdblock(void)
6403  {
6404 +       leaving = 1;
6405 +       wake_up(&thr_wq);
6406 +       down(&thread_sem);
6407 +#ifdef CONFIG_DEVFS_FS
6408 +       unregister_mtd_user(&notifier);
6409 +       devfs_unregister(devfs_dir_handle);
6410 +       devfs_unregister_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME);
6411 +#else
6412         unregister_blkdev(MAJOR_NR,DEVICE_NAME);
6413 -       blksize_size[MAJOR_NR] = NULL;
6414 +#endif
6415         blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
6416 +       blksize_size[MAJOR_NR] = NULL;
6417 +       blk_size[MAJOR_NR] = NULL;
6418  }
6419  
6420  module_init(init_mtdblock);
6421 @@ -296,5 +402,5 @@
6422  
6423  
6424  MODULE_LICENSE("GPL");
6425 -MODULE_AUTHOR("Erwin Authried <eauth@softsys.co.at> et al.");
6426 -MODULE_DESCRIPTION("Simple read-only block device emulation access to MTD devices");
6427 +MODULE_AUTHOR("Nicolas Pitre <nico@cam.org> et al.");
6428 +MODULE_DESCRIPTION("Caching read/erase/writeback block device emulation access to MTD devices");
6429 --- linux-2.4.20/drivers/net/Config.in~2.4.20_broadcom_3_37_2_1109_US.patch     2005-01-07 05:39:01.000000000 -0500
6430 +++ linux-2.4.20/drivers/net/Config.in  2005-01-08 12:16:21.077658368 -0500
6431 @@ -2,6 +2,7 @@
6432  # Network device configuration
6433  #
6434  
6435 +source drivers/net/hnd/Config.in
6436  source drivers/net/arcnet/Config.in
6437  
6438  tristate 'Dummy net driver support' CONFIG_DUMMY
6439 --- linux-2.4.20/drivers/net/Makefile~2.4.20_broadcom_3_37_2_1109_US.patch      2005-01-07 05:39:01.000000000 -0500
6440 +++ linux-2.4.20/drivers/net/Makefile   2005-01-08 12:16:21.891534640 -0500
6441 @@ -21,6 +21,17 @@
6442  list-multi     :=      rcpci.o
6443  rcpci-objs     :=      rcpci45.o rclanmtl.o
6444  
6445 +subdir-m += mac
6446 +subdir-m += diag
6447 +
6448 +ifeq ($(CONFIG_HW_QOS),y)
6449 +subdir-m += port_based_qos
6450 +else
6451 +       ifeq ($(CONFIG_PERFORMANCE),y)
6452 +       subdir-m += port_based_qos
6453 +       endif
6454 +endif
6455 +
6456  ifeq ($(CONFIG_TULIP),y)
6457    obj-y += tulip/tulip.o
6458  endif
6459 @@ -242,6 +253,36 @@
6460  endif
6461  endif
6462  
6463 +#
6464 +# Broadcom HND devices
6465 +#
6466 +
6467 +ifdef CONFIG_HND
6468 +subdir-$(CONFIG_HND) += hnd
6469 +endif
6470 +ifdef CONFIG_ET
6471 +subdir-$(CONFIG_ET) += et.4702
6472 +subdir-$(CONFIG_ET) += et
6473 +endif
6474 +ifdef CONFIG_IL
6475 +subdir-$(CONFIG_IL) += il
6476 +endif
6477 +ifdef CONFIG_WL
6478 +subdir-$(CONFIG_WL) += wl
6479 +endif
6480 +ifeq ($(CONFIG_HND),y)
6481 +  obj-y += hnd/hnd.o
6482 +endif
6483 +ifeq ($(CONFIG_ET),y)
6484 +  obj-y += et/et.o
6485 +endif
6486 +ifeq ($(CONFIG_IL),y)
6487 +  obj-y += il/il.o
6488 +endif
6489 +ifeq ($(CONFIG_WL),y)
6490 +  obj-y += wl/wl.o
6491 +endif
6492 +
6493  include $(TOPDIR)/Rules.make
6494  
6495  clean:
6496 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
6497 +++ linux-2.4.20/drivers/net/diag/Makefile      2005-01-07 05:39:02.000000000 -0500
6498 @@ -0,0 +1,27 @@
6499 +#  Copyright 2001, Cybertan Corporation
6500 +#  All Rights Reserved.
6501 +#  
6502 +#  This is UNPUBLISHED PROPRIETARY SOURCE CODE of Cybertan Corporation;
6503 +#  the contents of this file may not be disclosed to third parties, copied or
6504 +#  duplicated in any form, in whole or in part, without the prior written
6505 +#  permission of Cybertan Corporation.
6506 +#
6507 +#
6508 +# $Id: Makefile,v 1.1 2003/07/09 14:09:58 honor Exp $
6509 +#
6510 +
6511 +O_TARGET       := diag.o
6512 +
6513 +MAC_OBJS       := diag_led.o
6514 +
6515 +export-objs    := 
6516 +obj-y          := $(MAC_OBJS)
6517 +obj-m          := $(O_TARGET)
6518 +
6519 +SRCBASE                := $(TOPDIR)/../..
6520 +EXTRA_CFLAGS   += -I$(SRCBASE)/include
6521 +
6522 +vpath %.c $(SRCBASE)/shared
6523 +
6524 +include $(TOPDIR)/Rules.make
6525 +
6526 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
6527 +++ linux-2.4.20/drivers/net/et/Makefile        2005-01-07 05:39:02.000000000 -0500
6528 @@ -0,0 +1,42 @@
6529 +#
6530 +# Makefile for the Broadcom et driver
6531 +#
6532 +# Copyright 2004, Broadcom Corporation
6533 +# All Rights Reserved.
6534 +# 
6535 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
6536 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
6537 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
6538 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
6539 +#
6540 +# $Id: Makefile,v 1.1.1.6 2004/04/12 04:31:57 honor Exp $
6541 +#
6542 +
6543 +O_TARGET       := et.o
6544 +
6545 +ET_OBJS                := et_linux.o etc.o
6546 +
6547 +ifeq ($(CONFIG_ET_47XX),y)
6548 +ET_OBJS                += etc47xx.o etc_robo.o etc_adm.o
6549 +EXTRA_CFLAGS   += -DBCM47XX_CHOPS
6550 +endif
6551 +ifeq ($(CONFIG_ET_4413),y)
6552 +ET_OBJS                += etc4413.o
6553 +EXTRA_CFLAGS   += -DBCM4413_CHOPS
6554 +endif
6555 +
6556 +export-objs    :=
6557 +obj-y          := $(ET_OBJS)
6558 +obj-m          := $(O_TARGET)
6559 +
6560 +EXTRA_CFLAGS   += -DDMA
6561 +
6562 +# Search for sources under src/et/sys or objects under src/et/linux
6563 +ifneq ($(wildcard $(SRCBASE)/et/sys),)
6564 +EXTRA_CFLAGS   += -I$(SRCBASE)/et/sys
6565 +vpath %.c $(SRCBASE)/et/sys $(SRCBASE)/shared
6566 +else
6567 +obj-y          := $(foreach obj,$(ET_OBJS),$(SRCBASE)/et/linux/$(obj))
6568 +endif
6569 +
6570 +include $(TOPDIR)/Rules.make
6571 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
6572 +++ linux-2.4.20/drivers/net/et.4702/Makefile   2005-01-07 05:39:02.000000000 -0500
6573 @@ -0,0 +1,43 @@
6574 +#  Copyright 2001, Broadcom Corporation
6575 +#  All Rights Reserved.
6576 +#  
6577 +#  This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
6578 +#  the contents of this file may not be disclosed to third parties, copied or
6579 +#  duplicated in any form, in whole or in part, without the prior written
6580 +#  permission of Broadcom Corporation.
6581 +#
6582 +# Makefile for the Broadcom et driver
6583 +#
6584 +# $Id: Makefile,v 1.2 2003/11/13 13:04:22 honor Exp $
6585 +#
6586 +
6587 +O_TARGET       := 4702et.o
6588 +
6589 +ET_OBJS                := et_linux.o etc.o
6590 +
6591 +ifeq ($(CONFIG_ET_47XX),y)
6592 +ET_OBJS                += etc47xx.o etc_robo.o
6593 +EXTRA_CFLAGS   += -DBCM47XX_CHOPS
6594 +endif
6595 +ifeq ($(CONFIG_ET_4413),y)
6596 +ET_OBJS                += etc4413.o
6597 +EXTRA_CFLAGS   += -DBCM4413_CHOPS
6598 +endif
6599 +
6600 +export-objs    :=
6601 +obj-y          := $(ET_OBJS)
6602 +obj-m          := $(O_TARGET)
6603 +
6604 +SRCBASE                := $(TOPDIR)/../..
6605 +EXTRA_CFLAGS   += -I$(SRCBASE)/include
6606 +EXTRA_CFLAGS   += -DDMA
6607 +
6608 +# Search for sources under src/et/sys or objects under src/et/linux
6609 +ifneq ($(wildcard $(SRCBASE)/et.4702/sys),)
6610 +EXTRA_CFLAGS   += -I$(SRCBASE)/et.4702/sys
6611 +vpath %.c $(SRCBASE)/et.4702/sys $(SRCBASE)/shared
6612 +else
6613 +obj-y          := $(foreach obj,$(ET_OBJS),$(SRCBASE)/et.4702/linux/$(obj))
6614 +endif
6615 +
6616 +include $(TOPDIR)/Rules.make
6617 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
6618 +++ linux-2.4.20/drivers/net/hnd/Config.in      2005-01-07 05:39:02.000000000 -0500
6619 @@ -0,0 +1,35 @@
6620 +#
6621 +# Broadcom Home Networking Division (HND) driver configuration
6622 +#
6623 +# Copyright 2004, Broadcom Corporation
6624 +# All Rights Reserved.
6625 +# 
6626 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
6627 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
6628 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
6629 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
6630 +#
6631 +
6632 +mainmenu_option next_comment
6633 +comment 'Broadcom HND network devices'
6634 +   tristate 'Broadcom HND network device support' CONFIG_HND $CONFIG_PCI
6635 +   if [ "$CONFIG_HND" != "n" ]; then
6636 +      dep_tristate '  Broadcom InsideLine HPNA support' CONFIG_IL $CONFIG_HND
6637 +      if [ "$CONFIG_IL" != "n" ]; then
6638 +         bool '    Broadcom BCM42xx support' CONFIG_IL_42XX
6639 +         bool '    Broadcom BCM47xx support' CONFIG_IL_47XX
6640 +         int '    LARQ buffer allocation (0 = tiny, 2 = huge)' CONFIG_LARQ_BUF 0
6641 +      fi
6642 +      dep_tristate '  Broadcom 10/100 Ethernet support' CONFIG_ET $CONFIG_HND
6643 +      if [ "$CONFIG_ET" != "n" ]; then
6644 +         bool '    Broadcom BCM4413 support' CONFIG_ET_4413
6645 +         bool '    Broadcom BCM47xx support' CONFIG_ET_47XX
6646 +      fi
6647 +      dep_tristate '  Broadcom BCM43xx 802.11 Wireless support' CONFIG_WL $CONFIG_HND
6648 +      if [ "$CONFIG_WL" != "n" ]; then
6649 +         bool '    Access Point Mode Supported' CONFIG_WL_AP
6650 +         bool '    STA Mode Supported' CONFIG_WL_STA
6651 +         bool '    OID Interface Supported' CONFIG_WL_OID
6652 +      fi
6653 +   fi
6654 +endmenu
6655 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
6656 +++ linux-2.4.20/drivers/net/hnd/Makefile       2005-01-07 05:39:02.000000000 -0500
6657 @@ -0,0 +1,67 @@
6658 +#
6659 +# Makefile for Broadcom Home Networking Division (HND) shared driver code
6660 +#
6661 +# Copyright 2004, Broadcom Corporation
6662 +# All Rights Reserved.
6663 +# 
6664 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
6665 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
6666 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
6667 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
6668 +#
6669 +# $Id: Makefile,v 1.1.1.7 2004/04/12 04:31:58 honor Exp $
6670 +#
6671 +
6672 +O_TARGET       := hnd.o
6673 +
6674 +HND_OBJS       := bcmutils.o hnddma.o linux_osl.o sbutils.o bcmsrom.o
6675 +
6676 +ifneq ($(CONFIG_BCM947XX),y)
6677 +HND_OBJS       += nvramstubs.o
6678 +endif
6679 +
6680 +export-objs    := shared_ksyms.o
6681 +obj-y          := shared_ksyms.o $(HND_OBJS)
6682 +obj-m          := $(O_TARGET)
6683 +
6684 +vpath %.c $(SRCBASE)/shared $(SRCBASE)/shared/nvram
6685 +
6686 +include $(TOPDIR)/Rules.make
6687 +
6688 +ifeq ($(wildcard $(SRCBASE)/shared/bcmutils.c),)
6689 +bcmutils.o: $(SRCBASE)/shared/linux/bcmutils.o
6690 +       cp $< $@
6691 +endif
6692 +
6693 +ifeq ($(wildcard $(SRCBASE)/shared/hnddma.c),)
6694 +hnddma.o: $(SRCBASE)/shared/linux/hnddma.o
6695 +       cp $< $@
6696 +endif
6697 +
6698 +ifeq ($(wildcard $(SRCBASE)/shared/linux_osl.c),)
6699 +linux_osl.o: $(SRCBASE)/shared/linux/linux_osl.o
6700 +       cp $< $@
6701 +endif
6702 +
6703 +ifeq ($(wildcard $(SRCBASE)/shared/sbutils.c),)
6704 +sbutils.o: $(SRCBASE)/shared/linux/sbutils.o
6705 +       cp $< $@
6706 +endif
6707 +
6708 +ifeq ($(wildcard $(SRCBASE)/shared/bcmsrom.c),)
6709 +bcmsrom.o: $(SRCBASE)/shared/linux/bcmsrom.o
6710 +       cp $< $@
6711 +endif
6712 +
6713 +ifeq ($(wildcard $(SRCBASE)/shared/nvramstubs.c),)
6714 +nvramstubs.o: $(SRCBASE)/shared/linux/nvramstubs.o
6715 +       cp $< $@
6716 +endif
6717 +
6718 +ifeq ($(wildcard $(SRCBASE)/shared/bcmwpa.c),)
6719 +bcmwpa.o: $(SRCBASE)/shared/linux/bcmwpa.o
6720 +       cp $< $@
6721 +endif
6722 +
6723 +shared_ksyms.c: shared_ksyms.sh $(HND_OBJS)
6724 +       sh -e $< $(HND_OBJS) > $@
6725 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
6726 +++ linux-2.4.20/drivers/net/hnd/shared_ksyms.sh        2005-01-07 05:39:02.000000000 -0500
6727 @@ -0,0 +1,21 @@
6728 +#!/bin/sh
6729 +#
6730 +# Copyright 2004, Broadcom Corporation      
6731 +# All Rights Reserved.      
6732 +#       
6733 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY      
6734 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM      
6735 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS      
6736 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.      
6737 +#
6738 +# $Id: shared_ksyms.sh,v 1.1.1.6 2004/04/12 04:31:58 honor Exp $
6739 +#
6740 +
6741 +cat <<EOF
6742 +#include <linux/config.h>
6743 +#include <linux/module.h>
6744 +EOF
6745 +
6746 +for file in $* ; do
6747 +    ${NM} $file | sed -ne 's/[0-9A-Fa-f]* [DT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p'
6748 +done
6749 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
6750 +++ linux-2.4.20/drivers/net/il/Makefile        2005-01-07 05:39:02.000000000 -0500
6751 @@ -0,0 +1,50 @@
6752 +#
6753 +# Makefile for the Broadcom il driver
6754 +#
6755 +# Copyright 2004, Broadcom Corporation
6756 +# All Rights Reserved.
6757 +# 
6758 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
6759 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
6760 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
6761 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
6762 +#
6763 +# $Id: Makefile,v 1.1.1.6 2004/04/12 04:31:58 honor Exp $
6764 +#
6765 +
6766 +O_TARGET       := il.o
6767 +
6768 +IL_OBJS                := il_linux.o ilc.o cert.o plarq.o pe_select_maxse.o
6769 +
6770 +ifeq ($(CONFIG_IL_47XX),y)
6771 +IL_OBJS                += ilc47xx.o
6772 +EXTRA_CFLAGS   += -DBCM47XX_CHOPS
6773 +endif
6774 +ifeq ($(CONFIG_IL_42XX),y)
6775 +IL_OBJS                += ilc42xx.o
6776 +EXTRA_CFLAGS   += -DBCM42XX_CHOPS
6777 +endif
6778 +
6779 +export-objs    :=
6780 +obj-y          := $(IL_OBJS)
6781 +obj-m          := $(O_TARGET)
6782 +
6783 +EXTRA_CFLAGS   += -DDMA -DIL_CERT -DIL_PROTOS
6784 +
6785 +ifneq ($(CONFIG_BRIDGE),n)
6786 +EXTRA_CFLAGS   += -DIL_BRIDGE
6787 +endif
6788 +
6789 +ifeq ($(CONFIG_LARQ_BUF),0)
6790 +EXTRA_CFLAGS   += -DLARQ_TINY
6791 +endif
6792 +
6793 +# Search for sources under src/il/sys or objects under src/il/linux
6794 +ifneq ($(wildcard $(SRCBASE)/il/sys),)
6795 +EXTRA_CFLAGS   += -I$(SRCBASE)/il/sys
6796 +vpath %.c $(SRCBASE)/il/sys $(SRCBASE)/shared
6797 +else
6798 +obj-y          := $(foreach obj,$(IL_OBJS),$(SRCBASE)/il/linux/$(obj))
6799 +endif
6800 +
6801 +include $(TOPDIR)/Rules.make
6802 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
6803 +++ linux-2.4.20/drivers/net/mac/Makefile       2005-01-07 05:39:02.000000000 -0500
6804 @@ -0,0 +1,27 @@
6805 +#  Copyright 2001, Cybertan Corporation
6806 +#  All Rights Reserved.
6807 +#  
6808 +#  This is UNPUBLISHED PROPRIETARY SOURCE CODE of Cybertan Corporation;
6809 +#  the contents of this file may not be disclosed to third parties, copied or
6810 +#  duplicated in any form, in whole or in part, without the prior written
6811 +#  permission of Cybertan Corporation.
6812 +#
6813 +#
6814 +# $Id: Makefile,v 1.1 2003/07/09 14:10:26 honor Exp $
6815 +#
6816 +
6817 +O_TARGET       := writemac.o
6818 +
6819 +MAC_OBJS       := mac.o
6820 +
6821 +export-objs    := 
6822 +obj-y          := $(MAC_OBJS)
6823 +obj-m          := $(O_TARGET)
6824 +
6825 +SRCBASE                := $(TOPDIR)/../..
6826 +EXTRA_CFLAGS   += -I$(SRCBASE)/include
6827 +
6828 +vpath %.c $(SRCBASE)/shared
6829 +
6830 +include $(TOPDIR)/Rules.make
6831 +
6832 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
6833 +++ linux-2.4.20/drivers/net/port_based_qos/Atan.c      2005-01-07 05:39:02.000000000 -0500
6834 @@ -0,0 +1,177 @@
6835 +#include "Atan.h"
6836 +#include "c47xx.h"
6837 +
6838 +extern void conf_gpio(int x);
6839 +
6840 +/*----------------------------------------------------------------------------
6841 +Write specified data to eeprom
6842 +entry: *src    = pointer to specified data to write
6843 +               len             = number of short(2 bytes) to be written
6844 +*/
6845 +void write_eeprom( short RegNumber, unsigned short *data, int len )
6846 +{
6847 +    int i2;
6848 +    unsigned short s_addr, s_data;
6849 +    unsigned short *src;
6850 +
6851 +    src = data;
6852 +    SetEEpromToSendState();
6853 +//  the write enable(WEN) instruction must be executed before any device
6854 +//  programming can be done
6855 +
6856 +    s_data = 0x04c0;
6857 +    SendAddrToEEprom(s_data); //00000001 0011000000B
6858 +    SetCSToLowForEEprom();
6859 +
6860 +    s_addr = 0x0500 | (RegNumber & 0x0ff); //00000001 01dddddddd
6861 +    s_data = *src;
6862 +
6863 +    for (i2 = len; i2 > 0 ; i2 --)
6864 +    {
6865 +      SendAddrToEEprom(s_addr); //00000001 01dddddd
6866 +      SendDataToEEprom(s_data); //dddddddd dddddddd
6867 +      SetCSToLowForEEprom();
6868 +      SetCSToLowForEEprom();
6869 +      //WriteWait();     
6870 +      s_addr ++;
6871 +      src ++;
6872 +      s_data = *src;
6873 +    }
6874 +//  after all data has been written to EEprom , the write disable(WDS) 
6875 +//  instruction must be executed
6876 +    SetCSToHighForEEprom();
6877 +    s_data = 0x0400;
6878 +    SendAddrToEEprom(s_data); //00000001 00000000B
6879 +    SetCSToLowForEEprom();
6880 +    SetCSToLowForEEprom();
6881 +}
6882 +
6883 +void SetEEpromToSendState()
6884 +{
6885 +  conf_gpio(0x0);
6886 +  conf_gpio(0x0);
6887 +  conf_gpio(B_ECS);
6888 +  conf_gpio(B_ECS);
6889 +  
6890 +//  ;cs     __--   ,bit 2
6891 +//  ;sck    ____   ,bit 3
6892 +//  ;di     ____   ,bit 5
6893 +//  ;do     ____   ,bit 4
6894 +//  ;
6895 +}
6896 +
6897 +void ResetEEpromToSendState()
6898 +{
6899 +  conf_gpio(0x0);
6900 +  conf_gpio(0x0);
6901 +  conf_gpio(0x0);
6902 +  conf_gpio(0x0);
6903 +  
6904 +//  ;cs     ____   ,bit 2  
6905 +//  ;sck    ____   ,bit 3
6906 +//  ;di     ____   ,bit 5
6907 +//  ;do     ____   ,bit 4 
6908 +//  ;
6909 +}
6910 +
6911 +void SetCSToLowForEEprom()
6912 +{
6913 +  conf_gpio(0x0);
6914 +  conf_gpio(B_ECK);
6915 +  conf_gpio(B_ECK);
6916 +  conf_gpio(0x0);
6917 +  
6918 +//  ;cs     ____   ,bit 2
6919 +//  ;sck    _--_   ,bit 3
6920 +//  ;di     ____   ,bit 5
6921 +//  ;do     ____   ,bit 4 
6922 +//  ;
6923 +}
6924 +
6925 +void SetCSToHighForEEprom()
6926 +{
6927 +  conf_gpio(B_ECS);
6928 +  conf_gpio(B_ECS|B_ECK);
6929 +  conf_gpio(B_ECS|B_ECK);
6930 +  conf_gpio(B_ECS);
6931 +  
6932 +//  ;cs     ----   ,bit 2
6933 +//  ;sck    _--_   ,bit 3
6934 +//  ;di     ____   ,bit 5
6935 +//  ;do     ____   ,bit 4  
6936 +//  ;
6937 +}
6938 +
6939 +void send_1ToEEprom()
6940 +{
6941 +  conf_gpio(B_ECS|B_EDI);
6942 +  conf_gpio(B_ECS|B_ECK|B_EDI);
6943 +  conf_gpio(B_ECS|B_ECK|B_EDI);
6944 +  conf_gpio(B_ECS|B_EDI);
6945 +  
6946 +//  ;cs     ----   ,bit 2
6947 +//  ;sck    _--_   ,bit 3
6948 +//  ;di     ----   ,bit 5
6949 +//  ;do     ____   ,bit 4
6950 +//  ;       
6951 +}
6952 +
6953 +void send_0ToEEprom()
6954 +{
6955 +  conf_gpio(B_ECS);
6956 +  conf_gpio(B_ECS|B_ECK);
6957 +  conf_gpio(B_ECS|B_ECK);
6958 +  conf_gpio(B_ECS);
6959 +  
6960 +//  ;cs     ----   ,bit 2
6961 +//  ;sck    _--_   ,bit 3
6962 +//  ;di     ____   ,bit 5
6963 +//  ;do     ____   ,bit 4
6964 +//  ;       
6965 +}
6966 +
6967 +#if 0
6968 +void WriteWait()
6969 +{
6970 +  unsigned int status;
6971 +  
6972 +  SetCSToLowForEEprom();
6973 +  SetCSToHighForEEprom();
6974 +  do {
6975 +       SetCSToHighForEEprom();
6976 +       //status = ReadGPIOData(EDO);
6977 +       status = gpio & B_EDO;  // read EDO bit
6978 +  }
6979 +  while (!status);   // wait for write - ready
6980 +  SetCSToLowForEEprom();
6981 +}
6982 +#endif
6983 +
6984 +void SendDataToEEprom(short s_data) 
6985 +{
6986 +  int data_mask;
6987 +  
6988 +  for (data_mask = 0x8000; data_mask != 0; )
6989 +  {
6990 +    if (s_data & data_mask) 
6991 +      send_1ToEEprom();
6992 +    else
6993 +      send_0ToEEprom();  
6994 +    data_mask = data_mask >> 1;
6995 +  }
6996 +}
6997 +
6998 +void SendAddrToEEprom(short s_data) 
6999 +{
7000 +  int data_mask;
7001 +  
7002 +  for (data_mask = 0x0400 ;data_mask != 0; )
7003 +  {
7004 +    if (s_data & data_mask) 
7005 +      send_1ToEEprom();
7006 +    else
7007 +      send_0ToEEprom();  
7008 +    data_mask = data_mask >> 1;
7009 +  }
7010 +}
7011 +
7012 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
7013 +++ linux-2.4.20/drivers/net/port_based_qos/Atan.h      2005-01-07 05:39:02.000000000 -0500
7014 @@ -0,0 +1,18 @@
7015 +#ifndef _ATAN_H_
7016 +#define _ATAN_H_
7017 +
7018 +#define SINGLECOLOUR                           0x1
7019 +#define DUALCOLOUR                                     0x2
7020 +
7021 +void write_eeprom(short,unsigned short *,int);
7022 +void SetEEpromToSendState(void);
7023 +void ResetEEpromToSendState(void); 
7024 +void SetCSToLowForEEprom(void);
7025 +void SetCSToHighForEEprom(void);  
7026 +void send_1ToEEprom(void);
7027 +void send_0ToEEprom(void);
7028 +//void WriteWait(void);
7029 +void SendAddrToEEprom(short);
7030 +void SendDataToEEprom(short);
7031 +
7032 +#endif
7033 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
7034 +++ linux-2.4.20/drivers/net/port_based_qos/Makefile    2005-01-07 05:39:02.000000000 -0500
7035 @@ -0,0 +1,27 @@
7036 +#  Copyright 2001, Cybertan Corporation
7037 +#  All Rights Reserved.
7038 +#  
7039 +#  This is UNPUBLISHED PROPRIETARY SOURCE CODE of Cybertan Corporation;
7040 +#  the contents of this file may not be disclosed to third parties, copied or
7041 +#  duplicated in any form, in whole or in part, without the prior written
7042 +#  permission of Cybertan Corporation.
7043 +#
7044 +#
7045 +# $Id: Makefile,v 1.2 2004/03/02 13:23:33 cnhsieh Exp $
7046 +#
7047 +
7048 +O_TARGET       := port_based_qos_mod.o 
7049 +
7050 +PORT_BASED_QOS_MOD_OBJS        := port_based_qos.o Atan.o c47xx.o eeprom.o 
7051 +
7052 +export-objs    := 
7053 +obj-y          := $(PORT_BASED_QOS_MOD_OBJS)
7054 +obj-m          := $(O_TARGET)
7055 +
7056 +SRCBASE                := $(TOPDIR)/../..
7057 +EXTRA_CFLAGS   += -I$(SRCBASE)/include -Wall -I$(SRCBASE)/
7058 +
7059 +vpath %.c $(SRCBASE)/shared
7060 +
7061 +include $(TOPDIR)/Rules.make
7062 +
7063 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
7064 +++ linux-2.4.20/drivers/net/port_based_qos/c47xx.c     2005-01-07 05:39:02.000000000 -0500
7065 @@ -0,0 +1,85 @@
7066 +#include <typedefs.h>
7067 +#include <sbutils.h>
7068 +#include <bcmdevs.h>
7069 +#include <osl.h>
7070 +#include <bcmnvram.h>
7071 +#include <bcmutils.h>
7072 +
7073 +#include <sbpci.h>
7074 +#include <sbchipc.h>
7075 +#include <sbconfig.h>
7076 +#include <sbextif.h>
7077 +#include <sbmips.h>
7078 +#include "c47xx.h"
7079 +extern uint32 sb_gpioouten(void *sbh, uint32 mask, uint32 val);
7080 +extern uint32 sb_gpioout(void *sbh, uint32 mask, uint32 val);
7081 +extern uint32 sb_gpioin(void *sbh);
7082 +extern uint32 sb_gpiointmask(void *sbh, uint32 mask, uint32 val);
7083 +
7084 +#define OUTENMASK      B_RESET|B_ECS|B_ECK|B_EDI
7085 +#define CFGMASK                B_ECS|B_ECK|B_EDI
7086 +#define BIT(x) (1 << (x))
7087 +#define        ASSERT(exp)             do {} while (0)
7088 +
7089 +void
7090 +conf_gpio(int x)
7091 +{
7092 +       ASSERT(sbh);
7093 +
7094 +       /* Enable all of output pins */
7095 +       sb_gpioouten(sbh, OUTENMASK, OUTENMASK);
7096 +
7097 +       /* We don't want the B_RESET pin changed, unless
7098 +        * it tries to set the B_RESET pin.
7099 +        */
7100 +       if (x & B_RESET)
7101 +               sb_gpioout(sbh, OUTENMASK, x);
7102 +       else
7103 +               sb_gpioout(sbh, CFGMASK, x);
7104 +       
7105 +}
7106 +       
7107 +void
7108 +gpio_line_set(int x, unsigned int value)
7109 +{
7110 +       ASSERT(sbh);
7111 +
7112 +       if (value == 1)
7113 +               sb_gpioout(sbh, BIT(x), BIT(x));
7114 +       else if (value == 0)
7115 +               sb_gpioout(sbh, BIT(x), 0);
7116 +}
7117 +
7118 +void
7119 +gpio_line_get(int x, int *value)
7120 +{
7121 +       ASSERT(sbh);
7122 +
7123 +       *value = (sb_gpioin(sbh) >> x) & 0x1;
7124 +}
7125 +
7126 +void
7127 +gpio_line_config_in(int x)
7128 +{
7129 +       ASSERT(sbh);
7130 +       
7131 +       sb_gpioouten(sbh, BIT(x), 0);
7132 +       sb_gpiointmask(sbh, BIT(x), BIT(x));
7133 +}
7134 +
7135 +void
7136 +gpio_line_config_out(int x)
7137 +{
7138 +       ASSERT(sbh);
7139 +
7140 +       sb_gpiointmask(sbh, BIT(x), 0);
7141 +       sb_gpioouten(sbh, BIT(x), BIT(x));
7142 +}
7143 +
7144 +void
7145 +gpio_line_config_out_all(int x)
7146 +{
7147 +       ASSERT(sbh);
7148 +
7149 +       sb_gpioouten(sbh, OUTENMASK, OUTENMASK);
7150 +}
7151 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
7152 +++ linux-2.4.20/drivers/net/port_based_qos/c47xx.h     2005-01-07 05:39:02.000000000 -0500
7153 @@ -0,0 +1,23 @@
7154 +#ifndef _C47XX_H_
7155 +#define _C47XX_H_
7156 +
7157 +extern void    *bcm947xx_sbh;
7158 +#define sbh bcm947xx_sbh
7159 +
7160 +#define GPIO0  0
7161 +#define GPIO1  1
7162 +#define GPIO2  2
7163 +#define GPIO3  3
7164 +#define GPIO4  4
7165 +#define GPIO5  5
7166 +#define GPIO6  6
7167 +#define GPIO7  7
7168 +#define GPIO8  8
7169 +
7170 +#define B_RESET                1<<GPIO0
7171 +#define B_ECS          1<<GPIO2
7172 +#define B_ECK          1<<GPIO3
7173 +#define B_EDO          1<<GPIO4
7174 +#define B_EDI          1<<GPIO5
7175 +
7176 +#endif
7177 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
7178 +++ linux-2.4.20/drivers/net/port_based_qos/eeprom.c    2005-01-07 05:39:02.000000000 -0500
7179 @@ -0,0 +1,355 @@
7180 +#include <linux/delay.h>
7181 +
7182 +#define EEDO_PIN       4
7183 +#define EECS_PIN       2
7184 +#define EECK_PIN       3
7185 +#define EEDI_PIN       5
7186 +#define RESET_PIN      0
7187 +
7188 +static void SetCSToLowForEEprom(void);
7189 +//static void SetCSToHighForEEprom(void);
7190 +static void send1ToEEprom(void);
7191 +static void send0ToEEprom(void);
7192 +static void InitSerialInterface(void);
7193 +static void SerialPulse(void);
7194 +static void WriteDataToRegister(unsigned short RegNumber, unsigned short data);
7195 +void ReadDataFromRegister(unsigned short addr, unsigned short *hidata, unsigned short *lodata,int select_count);
7196 +static void WriteDataToEEprom(unsigned short addr, unsigned short data);
7197 +static void WriteCmdToEEprom(unsigned short cmd);
7198 +extern void gpio_line_set(int x, unsigned int value);
7199 +extern void gpio_line_get(int x, int *value);
7200 +extern void gpio_line_config_out(int x);
7201 +extern void gpio_line_config_in(int x);
7202 +extern void gpio_line_config_out_all(void);
7203 +//  ;cs     __--   ,bit 3
7204 +//  ;sck    ____   ,bit 4
7205 +//  ;di     ____   ,bit 5
7206 +//  ;do     ____   ,bit 6
7207 +//  ;
7208 +
7209 +static void SetEEpromToSendState(void)
7210 +{        
7211 +       gpio_line_set(EECS_PIN, 0); 
7212 +        gpio_line_set(EECK_PIN, 0);       
7213 +       gpio_line_set(EEDI_PIN, 1);     
7214 +//     gpio_line_set(EEDO_PIN, 1);    /* high impedance */     
7215 +       
7216 +        mdelay(1);
7217 +        gpio_line_set(EECS_PIN, 1);
7218 +//     gpio_line_set(EEDO_PIN, 1);    /* high impedance */
7219 +}
7220 +
7221 +#if 0
7222 +static void EEpromInit(void)
7223 +{
7224 +       gpio_line_set(EECS_PIN, 0); 
7225 +        gpio_line_set(EECK_PIN, 0);       
7226 +       gpio_line_set(EEDI_PIN, 1);     
7227 +       gpio_line_set(EEDO_PIN, 1);    /* high impedance */     
7228 +       
7229 +        mdelay(1);
7230 +}
7231 +   
7232 +//  ;cs     ____   ,bit 3  
7233 +//  ;sck    ____   ,bit 4
7234 +//  ;di     ____   ,bit 5
7235 +//  ;do     ____   ,bit 6 
7236 +//  ;
7237 +static void ResetEEpromToSendState(void)
7238 +{
7239 +       gpio_line_set(EECS_PIN, 0);
7240 +       gpio_line_set(EEDI_PIN, 0);
7241 +       //gpio_line_set(EEDO_PIN, 0);
7242 +       gpio_line_set(EECK_PIN, 0);
7243 +}
7244 +#endif /* 0 */
7245 +   
7246 +//  ;cs     ____   ,bit 3  
7247 +//  ;sck    _--_   ,bit 4
7248 +//  ;di     ____   ,bit 5
7249 +//  ;do     ____   ,bit 6 
7250 +//  ;
7251 +static void SetCSToLowForEEprom(void)
7252 +{
7253 +        /* minimum tcs is 1us */      
7254 +       gpio_line_set(EECS_PIN, 0);        
7255 +        gpio_line_set(EECS_PIN, 0);      
7256 +
7257 +       gpio_line_set(EECK_PIN, 0);
7258 +       gpio_line_set(EECK_PIN, 1);
7259 +       gpio_line_set(EECK_PIN, 1);
7260 +       gpio_line_set(EECK_PIN, 1);
7261 +       gpio_line_set(EECK_PIN, 1);
7262 +       gpio_line_set(EECK_PIN, 0);
7263 +
7264 +       gpio_line_set(EECS_PIN, 1);     
7265 +
7266 +        udelay(10);
7267 +}
7268 +
7269 +#if 0  
7270 +//  ;cs     ----   ,bit 3
7271 +//  ;sck    _--_   ,bit 4
7272 +//  ;di     ____   ,bit 5
7273 +//  ;do     ____   ,bit 6  
7274 +//  ;
7275 +static void SetCSToHighForEEprom(void)
7276 +{
7277 +       gpio_line_set(EECS_PIN, 1);
7278 +       
7279 +        /* min tskh and tskl is 1us */
7280 +       gpio_line_set(EECK_PIN, 1);
7281 +       udelay(2);
7282 +       gpio_line_set(EECK_PIN, 0); 
7283 +}
7284 +#endif /* 0 */
7285 +  
7286 +//  ;cs     ----   ,bit 3
7287 +//  ;sck    _--_   ,bit 4
7288 +//  ;di     ----   ,bit 5
7289 +//  ;do     ____   ,bit 6
7290 +//  ;       
7291 +static void send1ToEEprom(void)
7292 +{         
7293 +//printf("send1ToEEprom(1)...");
7294 +       gpio_line_set(EEDI_PIN, 1);                  
7295 +           
7296 +       gpio_line_set(EECK_PIN, 0);
7297 +        udelay(1);         
7298 +       gpio_line_set(EECK_PIN, 1);             
7299 +       gpio_line_set(EECK_PIN, 1);      
7300 +       gpio_line_set(EECK_PIN, 1);     
7301 +        udelay(1);
7302 +       gpio_line_set(EECK_PIN, 0);
7303 +}
7304 +
7305 +//  ;cs     ----   ,bit 3
7306 +//  ;sck    _--_   ,bit 4
7307 +//  ;di     ____   ,bit 5
7308 +//  ;do     ____   ,bit 6
7309 +//  ;       
7310 +static void send0ToEEprom(void)
7311 +{
7312 +//printf("send0ToEEprom(0)...");
7313 +       gpio_line_set(EEDI_PIN, 0);                  
7314 +           
7315 +       gpio_line_set(EECK_PIN, 0);         
7316 +       udelay(1);
7317 +       gpio_line_set(EECK_PIN, 1);             
7318 +       gpio_line_set(EECK_PIN, 1);      
7319 +       gpio_line_set(EECK_PIN, 1);     
7320 +       udelay(1);
7321 +       gpio_line_set(EECK_PIN, 0);
7322 +}
7323 +
7324 +static void WriteDataToEEprom(unsigned short addr, unsigned short data) 
7325 +{
7326 +  unsigned short addr_mask, data_mask;
7327 +  
7328 +  SetEEpromToSendState();
7329 +  for (addr_mask = 0x400; addr_mask != 0; )
7330 +  {
7331 +    if (addr & addr_mask) 
7332 +      send1ToEEprom();
7333 +    else
7334 +      send0ToEEprom();  
7335 +    addr_mask = addr_mask >> 1;    
7336 +  }
7337 +  for (data_mask = 0x8000; data_mask != 0; )
7338 +  {
7339 +    if (data & data_mask) 
7340 +      send1ToEEprom();
7341 +    else
7342 +      send0ToEEprom();  
7343 +    data_mask = data_mask >> 1;    
7344 +  }
7345 +  SetCSToLowForEEprom();
7346 +}
7347 +
7348 +static void WriteCmdToEEprom(unsigned short cmd) 
7349 +{
7350 +  unsigned short cmd_mask;
7351 +  
7352 +  SetEEpromToSendState();
7353 +  for (cmd_mask = 0x0400 ;cmd_mask != 0; )
7354 +  {
7355 +    if (cmd & cmd_mask) 
7356 +      send1ToEEprom();
7357 +    else
7358 +      send0ToEEprom();  
7359 +    cmd_mask = cmd_mask >> 1;
7360 +  }
7361 +   SetCSToLowForEEprom();
7362 +}
7363 +
7364 +/*
7365 + * Write data to configure registers through EEPROM interface, even we do not have
7366 + * an external EEPROM connectted, ADM6996 got a virtual AT39C66 inside
7367 + */
7368 +static void WriteDataToRegister(unsigned short RegNumber, unsigned short data)
7369 +{
7370 +    unsigned short cmd, addr;   
7371 +
7372 +    printk("WriteDataToRegister(RegNumber=0x%x, data=0x%x)\n", RegNumber, data);
7373 +   
7374 +//  the write enable(WEN) instruction must be executed before any device
7375 +//  programming can be done
7376 +    cmd = 0x04c0;
7377 +    WriteCmdToEEprom(cmd); //00000001 0011000000B    
7378 +
7379 +    addr = 0x0500 | (RegNumber & 0x0ff); //00000001 01dddddddd   
7380 +    WriteDataToEEprom(addr, data); //00000001 01dddddd
7381 +    
7382 +     
7383 +//  after all data has been written to EEprom , the write disable(WDS) 
7384 +//  instruction must be executed   
7385 +    cmd = 0x0400;
7386 +    WriteCmdToEEprom(cmd); //00000001 00000000B   
7387 +}
7388 +
7389 +static void SerialDelay(int count)
7390 +{        
7391 +     udelay(count);
7392 +}
7393 +
7394 +static void InitSerialInterface(void)
7395 +{
7396 +        gpio_line_set(EECK_PIN, 0);  
7397 +        gpio_line_set(EEDI_PIN, 0);  
7398 +}
7399 +
7400 +static void SerialPulse(void)
7401 +{
7402 +        gpio_line_set(EECK_PIN, 0);  
7403 +        gpio_line_set(EECK_PIN, 1);    
7404 +         SerialDelay(10);
7405 +         gpio_line_set(EECK_PIN, 1);  
7406 +         gpio_line_set(EECK_PIN, 0);  
7407 +}
7408 +/* 
7409 + * Since there is no EEPROM is our board, read from EEPROM need to obey the timing alike
7410 + *  MII interface, EECK = MDC, EEDI = MDIO, please refer to section 4.3 of ADM6996 datasheet
7411 + */
7412 +void ReadDataFromRegister(unsigned short addr, unsigned short *hidata, unsigned short *lodata, int select_count) 
7413 +{
7414 +       unsigned short addr_mask, data_mask;
7415 +       int value, i;
7416 +        unsigned char StartBits, Opcode, TAbits;
7417 +       
7418 +       gpio_line_config_out_all();
7419 +       mdelay(1);      
7420 +       /* initialize serial interface */
7421 +        gpio_line_set(EECS_PIN, 0);  
7422 +       InitSerialInterface();        
7423 +
7424 +        /* Preamble, 35 bits */
7425 +        gpio_line_set(EECK_PIN, 0); 
7426 +        gpio_line_set(EEDI_PIN, 1);
7427 +        for (i = 0; i < 35; i++)        
7428 +        {    
7429 +            gpio_line_set(EECK_PIN, 1);                        
7430 +            SerialDelay(10);
7431 +            gpio_line_set(EECK_PIN, 0); 
7432 +           SerialDelay(10);
7433 +        }
7434
7435 +        /* Start bits, 2-bit(01b) */
7436 +        InitSerialInterface();
7437 +        StartBits = 0x01;
7438 +        for (i = 0; i < 2; i++)
7439 +        {
7440 +             value = (StartBits & 2) ? 1 : 0;
7441 +             gpio_line_set(EEDI_PIN, value);  
7442 +             SerialDelay(1);
7443 +             SerialPulse();
7444 +             StartBits <<= 1;
7445 +         }
7446 +          
7447 +         /* Opcode, read = 10b */
7448 +         InitSerialInterface();
7449 +         Opcode = 0x02;
7450 +         for (i = 0; i < 2; i++)
7451 +         {
7452 +             value = (Opcode & 0x02) ? 1 : 0;
7453 +             gpio_line_set(EEDI_PIN, value);  
7454 +            SerialDelay(1);
7455 +             SerialPulse();
7456 +             Opcode <<= 1;
7457 +         }         
7458 +
7459 +         /* 10 bits register address */
7460 +         /* 1-bit Table Select, 2-bit Device Address, 7-bit Register Address  */         
7461 +         InitSerialInterface();
7462 +        if (select_count)
7463 +               addr = (addr & 0x7f) | 0x200; 
7464 +        else
7465 +               addr = addr & 0x7f ; 
7466 +         for (addr_mask = 0x200; addr_mask != 0; addr_mask >>= 1)
7467 +         {
7468 +             value = (addr & addr_mask) ? 1 : 0;
7469 +             gpio_line_set(EEDI_PIN, value);  
7470 +            SerialDelay(1);
7471 +             SerialPulse();           
7472 +         }             
7473 +
7474 +         /* TA, turnaround 2-bit */
7475 +         InitSerialInterface();
7476 +         TAbits = 0x02;        
7477 +          gpio_line_config_in(EEDI_PIN);
7478 +         for (i = 0; i < 2; i++)
7479 +         {
7480 +             gpio_line_set(EECK_PIN, 1);            
7481 +            SerialDelay(4);         
7482 +            gpio_line_get(EEDI_PIN, &value); 
7483 +            SerialDelay(4);  
7484 +             TAbits <<= 1;            
7485 +            gpio_line_set(EECK_PIN, 1);
7486 +         }
7487
7488 +       
7489 +         /* Latch data from serial management EEDI pin */
7490 +         *hidata = 0;
7491 +         gpio_line_set(EECK_PIN, 0);  
7492 +        for (data_mask = 0x8000; data_mask != 0; data_mask >>= 1)       
7493 +         {
7494 +             SerialDelay(4);             
7495 +             gpio_line_set(EECK_PIN, 1);  
7496 +             gpio_line_get(EEDI_PIN, &value); 
7497 +             if (value)
7498 +             {
7499 +                 *hidata |= data_mask;                 
7500 +            }
7501 +             gpio_line_set(EECK_PIN, 0); 
7502 +            SerialDelay(4);
7503 +         }
7504 +        *lodata = 0;
7505 +         gpio_line_set(EECK_PIN, 0);  
7506 +        for (data_mask = 0x8000; data_mask != 0; data_mask >>= 1)       
7507 +         {
7508 +             SerialDelay(4);           
7509 +             gpio_line_set(EECK_PIN, 1);  
7510 +             gpio_line_get(EEDI_PIN, &value); 
7511 +             if (value)
7512 +             {
7513 +                 *lodata |= data_mask;                 
7514 +            }
7515 +             gpio_line_set(EECK_PIN, 0); 
7516 +            SerialDelay(4);
7517 +         }
7518 +       
7519 +         SerialDelay(2);
7520 +
7521 +         /* Idle, EECK must send at least one clock at idle time */
7522 +         SerialPulse();
7523 +         gpio_line_set(EECK_PIN, 0);  
7524 +         SerialDelay(10);
7525 +         gpio_line_set(EECK_PIN, 1);  
7526 +         SerialDelay(10);
7527 +         gpio_line_set(EECK_PIN, 0);  
7528 +         SerialPulse();
7529 +
7530 +         gpio_line_config_out(EEDI_PIN);
7531 +        gpio_line_set(EECS_PIN, 1);
7532 +
7533 +   printk("ReadDataFromRegister(addr=0x%x, hidata=0x%x, lodata=0x%x)\n", addr, *hidata, *lodata);
7534 +}
7535 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
7536 +++ linux-2.4.20/drivers/net/port_based_qos/port_based_qos.c    2005-01-07 05:39:02.000000000 -0500
7537 @@ -0,0 +1,460 @@
7538 + /*
7539 + * Remaining issues:
7540 + *   + stats support
7541 + *   + multicast support
7542 + *   + media sense
7543 + *   + half/full duplex
7544 + *   - random MAC addr.
7545 + */
7546 +
7547 +#include <linux/config.h>
7548 +#include <linux/module.h>
7549 +#include <linux/kernel.h>
7550 +#include <linux/pci.h>
7551 +#include <linux/init.h>
7552 +#include <linux/ioport.h>
7553 +#include <linux/netdevice.h>
7554 +#include <linux/etherdevice.h>
7555 +#include <linux/ethtool.h>
7556 +#include <linux/mii.h>
7557 +#include <asm/io.h>
7558 +
7559 +#include <linux/sysctl.h>
7560 +#include <cy_conf.h>
7561 +
7562 +#define MODULE_NAME "port_based_qos_mod"
7563 +#define DEVICE_NAME "qos"
7564 +#define MODULE_VERSION "0.0.1"
7565 +
7566 +extern void ReadDataFromRegister(unsigned short addr, unsigned short *hidata, unsigned short *lodata,int select_count);
7567 +
7568 +#ifdef PERFORMANCE_SUPPORT
7569 +static struct ctl_table_header *qos_sysctl_header;
7570 +static unsigned long qos[28];
7571 +
7572 +static ctl_table mytable[] = {
7573 +         { 2000, "qos", 
7574 +          qos, sizeof(qos), 
7575 +          0644, NULL, 
7576 +          proc_dointvec },
7577 +         { 0 }
7578 +};
7579 +
7580 +static unsigned short statis_addr_map[7][6] ={
7581 +       {0x04, 0x06, 0x08, 0x0a, 0x0b, 0x0c},
7582 +       {0x16, 0x18, 0x1a, 0x1c, 0x1d, 0x1e},
7583 +       {0x0d, 0x0f, 0x11, 0x13, 0x14, 0x15},
7584 +       {0x1f, 0x21, 0x23, 0x25, 0x26, 0x27},
7585 +       {0x31, 0x33, 0x35, 0x37, 0x38, 0x39},
7586 +       {0x28, 0x2a, 0x2c, 0x2e, 0x2f, 0x30},
7587 +       {0x01, 0x01, 0x01, 0x01, 0x01, 0x01}
7588 +};
7589 +
7590 +unsigned long get_statistic_from_serial(unsigned short port, unsigned short item)
7591 +{
7592 +    unsigned short hidata, lodata;
7593 +       
7594 +    ReadDataFromRegister(statis_addr_map[item][port], &hidata, &lodata, 1); 
7595 +       return ((hidata << 16) | lodata);
7596 +}
7597 +#endif
7598 +
7599 +#ifdef HW_QOS_SUPPORT
7600 +struct port_qos_t{
7601 +       int addr;
7602 +       int content_mask;
7603 +       int *content_set; 
7604 +};
7605 +
7606 +void WriteDataToRegister_(unsigned short reg_idx, unsigned short content_idx);
7607 +extern void write_eeprom(short,short *,int);
7608 +
7609 +#define BANDWIDTH_1_BIT        2
7610 +#define BANDWIDTH_2_BIT        4
7611 +#define BANDWIDTH_3_BIT        6
7612 +#define BANDWIDTH_4_BIT        7
7613 +
7614 +#define PORT_CONFIG_1  0x3
7615 +#define PORT_CONFIG_2  0x5
7616 +#define PORT_CONFIG_3  0x7
7617 +#define PORT_CONFIG_4  0x8
7618 +#define BANDWIDTH_CTL_123      0x31
7619 +#define BANDWIDTH_CTL_4        0x32
7620 +#define BANDWIDTH_CTL_ENABLE   0x33
7621 +#define DISCARD_MODE   0x10
7622 +#define TOS_PRIO_MAP   0xf
7623 +
7624 +#define PRIORITY_MASK  0xfc7f
7625 +#define PRIORITY_DISABLE_MASK  0xfc7e
7626 +#define FLOW_CTL_MASK  0xfffe
7627 +#define RATE_LIMIT_MASK_1      0xff8f
7628 +#define RATE_LIMIT_MASK_2      0xf8ff
7629 +#define RATE_LIMIT_MASK_3      0x8fff
7630 +#define RATE_LIMIT_MASK_4      0xfff8
7631 +#define BANDWIDTH_CTL_MASK     0xff2b
7632 +#define DISCARD_MASK   0x0fff
7633 +
7634 +#define BANDWIDTH_ENABLE_1     1 << BANDWIDTH_1_BIT//04 
7635 +#define BANDWIDTH_ENABLE_2     1 << BANDWIDTH_2_BIT//10 
7636 +#define BANDWIDTH_ENABLE_3     1 << BANDWIDTH_3_BIT//40 
7637 +#define BANDWIDTH_ENABLE_4     1 << BANDWIDTH_4_BIT//80 
7638 +#define BANDWIDTH_CTL_MASK_1   0xffff^BANDWIDTH_ENABLE_1//0xfffb 
7639 +#define BANDWIDTH_CTL_MASK_2   0xffff^BANDWIDTH_ENABLE_2//0xffef 
7640 +#define BANDWIDTH_CTL_MASK_3   0xffff^BANDWIDTH_ENABLE_3//0xffbf 
7641 +#define BANDWIDTH_CTL_MASK_4   0xffff^BANDWIDTH_ENABLE_4//0xff7f 
7642 +
7643 +/*static int disable_content[] = {0x0};
7644 +//static int enable_content[] = {0xd4, 0x0cff};//bit 7,6,4,2; Q1=11(50%),Q0=00(0%)*/
7645 +//static int sw_content[] = {0x0,0x0c00};//bit 7,6,4,2; Q1=11(50%),Q0=00(0%)
7646 +static int sw_content[] = {0x0,0xc000};//bit 7,6,4,2; Q1=11(50%),Q0=00(0%)
7647 +static int port_priority_content[] = {0x080,0x380};//Q0,Q3
7648 +//static int port_priority_content[] = {0x300,0x0};//Q1,Q0
7649 +static int port_flow_ctl_content[] = {0x0,0x1};
7650 +static int port_rate_limit_content_1[] = {0x0,0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70};
7651 +static int port_rate_limit_content_2[] = {0x0,0x000,0x100,0x200,0x300,0x400,0x500,0x600,0x700};
7652 +static int port_rate_limit_content_3[] = {0x0,0x0000,0x1000,0x2000,0x3000,0x4000,0x5000,0x6000,0x7000};
7653 +static int port_rate_limit_content_4[] = {0x0,0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7};
7654 +static int port_rate_limit_enable_1[] = {0x0, BANDWIDTH_ENABLE_1};
7655 +static int port_rate_limit_enable_2[] = {0x0, BANDWIDTH_ENABLE_2};
7656 +static int port_rate_limit_enable_3[] = {0x0, BANDWIDTH_ENABLE_3};
7657 +static int port_rate_limit_enable_4[] = {0x0, BANDWIDTH_ENABLE_4};
7658 +
7659 +static struct port_qos_t port_mii_disable[] = {
7660 +       { BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK, sw_content},
7661 +       //{ DISCARD_MODE, DISCARD_MASK, sw_content},
7662 +       { PORT_CONFIG_1, PRIORITY_MASK, sw_content},//port_priority_1
7663 +       { PORT_CONFIG_2, PRIORITY_MASK, sw_content},//port_priority_2
7664 +       { PORT_CONFIG_3, PRIORITY_MASK, sw_content},//port_priority_3
7665 +       { PORT_CONFIG_4, PRIORITY_MASK, sw_content},//port_priority_4
7666 +       { PORT_CONFIG_1, FLOW_CTL_MASK, &port_flow_ctl_content[1]},//port_flow_control_1
7667 +       { PORT_CONFIG_2, FLOW_CTL_MASK, &port_flow_ctl_content[1]},//port_flow_control_2
7668 +       { PORT_CONFIG_3, FLOW_CTL_MASK, &port_flow_ctl_content[1]},//port_flow_control_3
7669 +       { PORT_CONFIG_4, FLOW_CTL_MASK, &port_flow_ctl_content[1]},//port_flow_control_4
7670 +       { -1}
7671 +};
7672 +
7673 +static struct port_qos_t port_mii_enable[] = {
7674 +       //{ BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK, enable_content},
7675 +       //{ DISCARD_MODE, DISCARD_MASK, sw_content},
7676 +       { -1}
7677 +};
7678 +
7679 +struct port_qos_t *port_mii_sw_array[] = {port_mii_disable, port_mii_enable};
7680 +
7681 +/*static struct port_qos_t port_mii_addr[] = {
7682 +       { PORT_CONFIG_1, PRIORITY_MASK, port_priority_content},//port_priority_1
7683 +       { PORT_CONFIG_1, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_1
7684 +       //{ "port_frame_type_1", 0x3},
7685 +       { BANDWIDTH_CTL_123, RATE_LIMIT_MASK_14, port_rate_limit_content_14},//port_rate_limit_1
7686 +       { PORT_CONFIG_2, PRIORITY_MASK, port_priority_content},//port_priority_2
7687 +       { PORT_CONFIG_2, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_2
7688 +       //{ "port_frame_type_2", 0x5},
7689 +       { BANDWIDTH_CTL_123, RATE_LIMIT_MASK_2, port_rate_limit_content_2},//port_rate_limit_2
7690 +       { PORT_CONFIG_3, PRIORITY_MASK, port_priority_content},//port_priority_3
7691 +       { PORT_CONFIG_3, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_3
7692 +       //{ "port_frame_type_3", 0x7},
7693 +       { BANDWIDTH_CTL_123, RATE_LIMIT_MASK_3, port_rate_limit_content_3},//port_rate_limit_3
7694 +       //{ "port_priority_4", 0x8, 0x380},
7695 +       { PORT_CONFIG_4, PRIORITY_MASK, port_priority_content},//port_priority_4
7696 +       { PORT_CONFIG_4, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_4
7697 +       //{ "port_frame_type_4", 0x8},
7698 +       { BANDWIDTH_CTL_4, RATE_LIMIT_MASK_14, port_rate_limit_content_14},//port_rate_limit_4
7699 +       { -1}
7700 +};*/
7701 +
7702 +static struct port_qos_t priority_1[] = {
7703 +       { PORT_CONFIG_1, PRIORITY_MASK, port_priority_content},//port_priority_1
7704 +       { -1}
7705 +};
7706 +static struct port_qos_t flow_control_1[] = {
7707 +       { PORT_CONFIG_1, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_1
7708 +       { -1}
7709 +};
7710 +static struct port_qos_t rate_limit_1[] = {
7711 +       { BANDWIDTH_CTL_123, RATE_LIMIT_MASK_1, port_rate_limit_content_1},//port_rate_limit_1
7712 +       { BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK_1, port_rate_limit_enable_1},//port_rate_limit_4
7713 +       { -1}
7714 +};
7715 +static struct port_qos_t priority_2[] = {
7716 +       { PORT_CONFIG_2, PRIORITY_MASK, port_priority_content},//port_priority_2
7717 +       { -1}
7718 +};
7719 +static struct port_qos_t flow_control_2[] = {
7720 +       { PORT_CONFIG_2, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_2
7721 +       { -1}
7722 +};
7723 +static struct port_qos_t rate_limit_2[] = {
7724 +       { BANDWIDTH_CTL_123, RATE_LIMIT_MASK_2, port_rate_limit_content_2},//port_rate_limit_2
7725 +       { BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK_2, port_rate_limit_enable_2},//port_rate_limit_4
7726 +       { -1}
7727 +};
7728 +static struct port_qos_t priority_3[] = {
7729 +       { PORT_CONFIG_3, PRIORITY_MASK, port_priority_content},//port_priority_3
7730 +       { -1}
7731 +};
7732 +static struct port_qos_t flow_control_3[] = {
7733 +       { PORT_CONFIG_3, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_3
7734 +       { -1}
7735 +};
7736 +static struct port_qos_t rate_limit_3[] = {
7737 +       { BANDWIDTH_CTL_123, RATE_LIMIT_MASK_3, port_rate_limit_content_3},//port_rate_limit_3
7738 +       { BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK_3, port_rate_limit_enable_3},//port_rate_limit_4
7739 +       { -1}
7740 +};
7741 +static struct port_qos_t priority_4[] = {
7742 +       { PORT_CONFIG_4, PRIORITY_MASK, port_priority_content},//port_priority_4
7743 +       { -1}
7744 +};
7745 +static struct port_qos_t flow_control_4[] = {
7746 +       { PORT_CONFIG_4, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_4
7747 +       { -1}
7748 +};
7749 +static struct port_qos_t rate_limit_4[] = {
7750 +       { BANDWIDTH_CTL_4, RATE_LIMIT_MASK_4, port_rate_limit_content_4},//port_rate_limit_4
7751 +       { BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK_4, port_rate_limit_enable_4},//port_rate_limit_4
7752 +       { -1}
7753 +};
7754 +
7755 +static struct port_qos_t *port_mii_addr[] = {
7756 +       priority_1,
7757 +       flow_control_1,
7758 +       rate_limit_1,
7759 +       priority_2,
7760 +       flow_control_2,
7761 +       rate_limit_2,
7762 +       priority_3,
7763 +       flow_control_3,
7764 +       rate_limit_3,
7765 +       priority_4,
7766 +       flow_control_4,
7767 +       rate_limit_4,
7768 +       NULL
7769 +};
7770 +
7771 +void WriteDataToRegister_(unsigned short reg_idx, unsigned short content_idx)
7772 +{
7773 +    short RegNumber;
7774 +    unsigned short data, hidata=0x0, lodata=0x0;
7775 +    int i;
7776 +    struct port_qos_t *port_qos = port_mii_addr[reg_idx];
7777 +    
7778 +    //printk("\nWriteDataToRegister_:reg_idx=%d content_idx=%d\n", reg_idx, content_idx);
7779 +    if (!port_qos)
7780 +        port_qos = port_mii_sw_array[content_idx];
7781 +       
7782 +    for (i=0; port_qos[i].addr != -1; i++)
7783 +    {
7784 +       RegNumber = port_qos[i].addr;
7785 +       ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
7786 +
7787 +        if (!(RegNumber % 2)) /* even port number use lower word */
7788 +               hidata = lodata;
7789 +
7790 +        data = (hidata & port_qos[i].content_mask) | (((i > 0) && (content_idx > 1))? port_qos[i].content_set[1] : port_qos[i].content_set[content_idx]);
7791 +       
7792 +       write_eeprom(RegNumber, &data, 1);
7793 +       ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
7794 +    }
7795 +       ReadDataFromRegister(0xf, &hidata, &lodata, 0);
7796 +       
7797 +       /*RegNumber = port_mii_addr[reg_idx].addr;
7798 +       if (RegNumber == -1)//Disable or Enable
7799 +       {
7800 +               struct port_qos_t *port_mii_sw = port_mii_sw_array[content_idx];
7801 +       
7802 +               printk("\nWriteDataToRegister_:reg_idx=%d content_idx=%d\n", reg_idx, content_idx);
7803 +               for (i=0; port_mii_sw[i].addr != -1; i++)
7804 +               {
7805 +                       RegNumber = port_mii_sw[i].addr;
7806 +                               
7807 +                       ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
7808 +                       
7809 +                       if (!(RegNumber % 2)) 
7810 +                               hidata = lodata;
7811 +                        
7812 +                       data = (hidata & port_mii_sw[i].content_mask) | port_mii_sw[i].content_set[i];
7813 +       
7814 +                       write_eeprom(RegNumber, &data, 1);
7815 +                       
7816 +                       ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
7817 +                       printk("\n============== %s===============\n", (content_idx==0)?"disable":"enable");
7818 +               }
7819 +       }
7820 +       else
7821 +       {
7822 +               ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
7823 +
7824 +               if (!(RegNumber % 2)) 
7825 +                       hidata = lodata;
7826 +
7827 +               data = (hidata & port_mii_addr[reg_idx].content_mask) | port_mii_addr[reg_idx].content_set[content_idx];
7828 +       
7829 +               write_eeprom(RegNumber, &data, 1);
7830 +               ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
7831 +       }*/
7832 +}
7833 +#endif
7834 +
7835 +static int dev_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
7836 +{
7837 +    struct mii_ioctl_data *data = (struct mii_ioctl_data *)req->ifr_data;
7838 +#ifdef PERFORMANCE_SUPPORT
7839 +    int item, port; 
7840 +    
7841 +    unsigned long status_item;
7842 +#endif
7843 +    
7844 +    switch (cmd)
7845 +    {
7846 +    case SIOCGMIIPHY:          /* Get address of MII PHY in use. */
7847 +    case SIOCDEVPRIVATE:       /* for binary compat, remove in 2.5 */
7848 +
7849 +       /* Fall through to the SIOCGMIIREG, taken from eepro100 and rtl
7850 +        * drivers */
7851 +#ifdef PERFORMANCE_SUPPORT
7852 +    case SIOCGMIIREG:          /* Read MII PHY register. */
7853 +       for (item=0; item<6; item++)
7854 +               for (port=1; port<5; port++){
7855 +                       qos[(item * 4) + (port-1)] = get_statistic_from_serial(port, item);     
7856 +               }
7857 +       
7858 +       status_item = get_statistic_from_serial(0, 6);
7859 +       
7860 +       qos[24] = (0x1 & (status_item >> 8));
7861 +       qos[25] = (0x1 & (status_item >> 16));
7862 +       qos[26] = (0x1 & (status_item >> 24));
7863 +       qos[27] = (0x1 & (status_item >> 28));
7864 +       
7865 +       return 0;
7866 +#endif
7867 +
7868 +    case SIOCDEVPRIVATE+1:     /* for binary compat, remove in 2.5 */
7869 +#ifdef HW_QOS_SUPPORT
7870 +    case SIOCSMIIREG:          /* Write MII PHY register. */
7871 +       {
7872 +       printk("\n x phy_id=%x\n", data->phy_id);
7873 +       printk("\n x reg_num=%x\n", data->reg_num);
7874 +       printk("\n x val_in=%x\n", data->val_in);
7875 +       printk("\n x val_out=%x\n", data->val_out);
7876 +               
7877 +       WriteDataToRegister_(data->phy_id, data->val_in); 
7878 +       return 0;
7879 +       }
7880 +#endif
7881 +    case SIOCDEVPRIVATE+2:     /* for binary compat, remove in 2.5 */
7882 +    default:
7883 +       return -EOPNOTSUPP;
7884 +    }
7885 +}
7886 +
7887 +static int __devinit qos_eth_probe(struct net_device *dev)
7888 +{
7889 +    
7890 +    SET_MODULE_OWNER(dev);
7891 +
7892 +    ether_setup(dev);
7893 +
7894 +    strcpy(dev->name, DEVICE_NAME "0");
7895 +
7896 +    dev->do_ioctl = dev_do_ioctl;
7897 +
7898 +    return 0;
7899 +}
7900 +
7901 +#ifdef HW_QOS_SUPPORT
7902 +static char *port_option_name[] = {
7903 +       "port_priority_1",
7904 +       "port_flow_control_1",
7905 +       //{ "port_frame_type_1",
7906 +       "port_rate_limit_1",
7907 +       "port_priority_2",
7908 +       "port_flow_control_2",
7909 +       //{ "port_frame_type_2",
7910 +       "port_rate_limit_2",
7911 +       "port_priority_3",
7912 +       "port_flow_control_3",
7913 +       //{ "port_frame_type_3",
7914 +       "port_rate_limit_3",
7915 +       "port_priority_4",
7916 +       //{ "port_priority_4", PORT_CONFIG_4, PRIORITY_MASK, port_priority_content},
7917 +       "port_flow_control_4",
7918 +       //{ "port_frame_type_4",
7919 +       "port_rate_limit_4",
7920 +       "QoS",
7921 +       NULL
7922 +};
7923 +
7924 +extern char *nvram_get(const char *name);
7925 +extern uint bcm_atoi(char *s);
7926 +
7927 +static int set_port_option(struct net_device *dev, unsigned short port_addr, char *option_content)
7928 +{
7929 +    struct ifreq ifr;
7930 +    struct mii_ioctl_data stats;
7931 +       
7932 +    stats.phy_id=port_addr;
7933 +    stats.val_in=bcm_atoi(option_content);
7934 +
7935 +    ifr.ifr_data = (void *)&stats;
7936 +    
7937 +    return dev_do_ioctl(dev, &ifr, SIOCSMIIREG);
7938 +}
7939 +
7940 +
7941 +void
7942 +restore_default_from_NV(struct net_device *dev)
7943 +{
7944 +       unsigned short i;
7945 +       char *value = NULL;
7946 +       
7947 +       for (i = 0; port_option_name[i]; i++)
7948 +       {
7949 +               if((value = nvram_get(port_option_name[i])))
7950 +                       set_port_option(dev, i, value);
7951 +       }
7952 +       return;
7953 +}
7954 +#endif
7955 +
7956 +static struct net_device qos_devices;
7957 +
7958 +/* Module initialization and cleanup */
7959 +int init_module(void)
7960 +{
7961 +    int res;
7962 +    struct net_device *dev;
7963 +
7964 +    printk("Initializing " MODULE_NAME " driver " MODULE_VERSION "\n");
7965 +
7966 +       dev = &qos_devices;
7967 +
7968 +       dev->init = qos_eth_probe;
7969 +
7970 +       if ((res = register_netdev(dev)))
7971 +           printk("Failed to register netdev. res = %d\n", res);
7972 +
7973 +#ifdef PERFORMANCE_SUPPORT
7974 +       qos_sysctl_header = register_sysctl_table(mytable, 0);
7975 +#endif
7976 +#ifdef HW_QOS_SUPPORT
7977 +       restore_default_from_NV(dev);
7978 +       write_eeprom(TOS_PRIO_MAP, &sw_content[0], 1);/* disable TOS priority map*/
7979 +#endif
7980 +    return 0;
7981 +}
7982 +
7983 +void cleanup_module(void)
7984 +{
7985 +       struct net_device *dev = &qos_devices;
7986 +       if (dev->priv != NULL)
7987 +       {
7988 +           unregister_netdev(dev);
7989 +           kfree(dev->priv);
7990 +           dev->priv = NULL;
7991 +       }
7992 +       
7993 +#ifdef PERFORMANCE_SUPPORT
7994 +       unregister_sysctl_table(qos_sysctl_header);
7995 +#endif
7996 +}
7997 +
7998 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
7999 +++ linux-2.4.20/drivers/net/wl/Makefile        2005-01-07 05:39:02.000000000 -0500
8000 @@ -0,0 +1,68 @@
8001 +#
8002 +# Makefile for the Broadcom wl driver
8003 +#
8004 +# Copyright 2004, Broadcom Corporation
8005 +# All Rights Reserved.
8006 +# 
8007 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8008 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
8009 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
8010 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
8011 +#
8012 +# $Id: Makefile,v 1.1.1.7 2004/04/12 04:32:06 honor Exp $
8013 +#
8014 +
8015 +O_TARGET       := wl.o
8016 +
8017 +WL_OBJS                := wl_linux.o wlc.o d11ucode.o wlc_phy.o wlc_rate.o wlc_led.o wlc_security.o rc4.o tkhash.o bcmwpa.o
8018 +
8019 +INSUP_OBJS     := aes.o aeskeywrap.o hmac.o md5.o passhash.o prf.o rijndael-alg-fst.o sha1.o 
8020 +
8021 +# Alternate ioctl interfaces
8022 +ifeq ($(CONFIG_NET_WIRELESS),y)
8023 +WL_OBJS                += wlc_cmn_ioctl.o
8024 +endif
8025 +ifeq ($(CONFIG_WL_OID),y)
8026 +WL_OBJS                += wl_oid.o
8027 +endif
8028 +
8029 +ifeq ($(CONFIG_WL_STA),y)
8030 +WL_OBJS        += $(INSUP_OBJS)
8031 +endif
8032 +
8033 +# Prefix driver variants
8034 +WL_APOBJS      := $(foreach obj,$(WL_OBJS),ap_$(obj))
8035 +WL_STAOBJS     := $(foreach obj,$(WL_OBJS) wlc_sup.o,sta_$(obj))
8036 +WL_APSTAOBJS   := $(foreach obj,$(WL_OBJS) wlc_sup.o,apsta_$(obj))
8037 +ifneq ($(CONFIG_WL_STA),y)
8038 +WL_APSTAOBJS   += $(foreach obj,$(INSUP_OBJS), apsta_$(obj))
8039 +endif
8040 +
8041 +# Either or both
8042 +ifeq ($(CONFIG_WL_AP),y)
8043 +AP             := AP
8044 +endif
8045 +ifeq ($(CONFIG_WL_STA),y)
8046 +STA            := STA
8047 +endif
8048 +
8049 +# Build all variants as modules but link only one of them
8050 +export-objs    :=
8051 +obj-y          := $(WL_$(AP)$(STA)OBJS)
8052 +obj-m          := $(O_TARGET)
8053 +variant-objs   := $(WL_APOBJS) $(WL_STAOBJS) $(WL_APSTAOBJS)
8054 +
8055 +EXTRA_CFLAGS   += -DDMA
8056 +
8057 +# Search for sources under src/wl/sys or objects under src/wl/linux
8058 +ifneq ($(wildcard $(SRCBASE)/wl/sys),)
8059 +EXTRA_CFLAGS   += -I$(SRCBASE)/wl/sys
8060 +vpath %.c $(SRCBASE)/wl/sys $(SRCBASE)/shared $(SRCBASE)/crypto
8061 +else
8062 +obj-y          := $(foreach obj,$(obj-y),$(SRCBASE)/wl/linux/$(obj))
8063 +variant-objs   := $(foreach obj,$(variant-objs),$(SRCBASE)/wl/linux/$(obj))
8064 +endif
8065 +
8066 +include $(TOPDIR)/Rules.make
8067 +
8068 +
8069 --- linux-2.4.20/drivers/pcmcia/Makefile~2.4.20_broadcom_3_37_2_1109_US.patch   2005-01-07 05:39:01.000000000 -0500
8070 +++ linux-2.4.20/drivers/pcmcia/Makefile        2005-01-07 05:39:02.000000000 -0500
8071 @@ -64,6 +64,10 @@
8072  au1000_ss-objs-$(CONFIG_PCMCIA_PB1X00)         += au1000_pb1x00.o
8073  au1000_ss-objs-$(CONFIG_PCMCIA_DB1X00)         += au1000_db1x00.o
8074  
8075 +obj-$(CONFIG_PCMCIA_BCM4710)                   += bcm4710_ss.o
8076 +bcm4710_ss-objs                                        := bcm4710_generic.o
8077 +bcm4710_ss-objs                                        += bcm4710_pcmcia.o
8078 +
8079  obj-$(CONFIG_PCMCIA_SA1100)    += sa1100_cs.o
8080  obj-$(CONFIG_PCMCIA_M8XX)      += m8xx_pcmcia.o
8081  
8082 @@ -98,5 +102,8 @@
8083  au1x00_ss.o: $(au1000_ss-objs-y)
8084         $(LD) -r -o $@ $(au1000_ss-objs-y)
8085  
8086 +bcm4710_ss.o: $(bcm4710_ss-objs)
8087 +       $(LD) -r -o $@ $(bcm4710_ss-objs)
8088 +
8089  yenta_socket.o: $(yenta_socket-objs)
8090         $(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs)
8091 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
8092 +++ linux-2.4.20/drivers/pcmcia/bcm4710_generic.c       2005-01-07 05:39:02.000000000 -0500
8093 @@ -0,0 +1,912 @@
8094 +/*
8095 + *
8096 + * bcm47xx pcmcia driver
8097 + *
8098 + * Copyright 2004, Broadcom Corporation
8099 + * All Rights Reserved.
8100 + * 
8101 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8102 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
8103 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
8104 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
8105 + *
8106 + * Based on sa1100_generic.c from www.handhelds.org,
8107 + *     and au1000_generic.c from oss.sgi.com.
8108 + *
8109 + * $Id: bcm4710_generic.c,v 1.1.1.7 2004/04/12 04:32:07 honor Exp $
8110 + */
8111 +#include <linux/module.h>
8112 +#include <linux/init.h>
8113 +#include <linux/config.h>
8114 +#include <linux/delay.h>
8115 +#include <linux/ioport.h>
8116 +#include <linux/kernel.h>
8117 +#include <linux/tqueue.h>
8118 +#include <linux/timer.h>
8119 +#include <linux/mm.h>
8120 +#include <linux/proc_fs.h>
8121 +#include <linux/version.h>
8122 +#include <linux/types.h>
8123 +#include <linux/vmalloc.h>
8124 +
8125 +#include <pcmcia/version.h>
8126 +#include <pcmcia/cs_types.h>
8127 +#include <pcmcia/cs.h>
8128 +#include <pcmcia/ss.h>
8129 +#include <pcmcia/bulkmem.h>
8130 +#include <pcmcia/cistpl.h>
8131 +#include <pcmcia/bus_ops.h>
8132 +#include "cs_internal.h"
8133 +
8134 +#include <asm/io.h>
8135 +#include <asm/irq.h>
8136 +#include <asm/system.h>
8137 +
8138 +#include <typedefs.h>
8139 +#include <bcm4710.h>
8140 +#include <sbextif.h>
8141 +
8142 +#include "bcm4710pcmcia.h"
8143 +
8144 +#ifdef PCMCIA_DEBUG
8145 +static int pc_debug = PCMCIA_DEBUG;
8146 +#endif
8147 +
8148 +MODULE_DESCRIPTION("Linux PCMCIA Card Services: bcm47xx Socket Controller");
8149 +
8150 +/* This structure maintains housekeeping state for each socket, such
8151 + * as the last known values of the card detect pins, or the Card Services
8152 + * callback value associated with the socket:
8153 + */
8154 +static struct bcm47xx_pcmcia_socket *pcmcia_socket;
8155 +static int socket_count;
8156 +
8157 +
8158 +/* Returned by the low-level PCMCIA interface: */
8159 +static struct pcmcia_low_level *pcmcia_low_level;
8160 +
8161 +/* Event poll timer structure */
8162 +static struct timer_list poll_timer;
8163 +
8164 +
8165 +/* Prototypes for routines which are used internally: */
8166 +
8167 +static int  bcm47xx_pcmcia_driver_init(void);
8168 +static void bcm47xx_pcmcia_driver_shutdown(void);
8169 +static void bcm47xx_pcmcia_task_handler(void *data);
8170 +static void bcm47xx_pcmcia_poll_event(unsigned long data);
8171 +static void bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs);
8172 +static struct tq_struct bcm47xx_pcmcia_task;
8173 +
8174 +#ifdef CONFIG_PROC_FS
8175 +static int bcm47xx_pcmcia_proc_status(char *buf, char **start, 
8176 +               off_t pos, int count, int *eof, void *data);
8177 +#endif
8178 +
8179 +
8180 +/* Prototypes for operations which are exported to the
8181 + * in-kernel PCMCIA core:
8182 + */
8183 +
8184 +static int bcm47xx_pcmcia_init(unsigned int sock);
8185 +static int bcm47xx_pcmcia_suspend(unsigned int sock);
8186 +static int bcm47xx_pcmcia_register_callback(unsigned int sock, 
8187 +               void (*handler)(void *, unsigned int), void *info);
8188 +static int bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap);
8189 +static int bcm47xx_pcmcia_get_status(unsigned int sock, u_int *value);
8190 +static int bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state);
8191 +static int bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state);
8192 +static int bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *io);
8193 +static int bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *io);
8194 +static int bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *mem);
8195 +static int bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *mem);
8196 +#ifdef CONFIG_PROC_FS
8197 +static void bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base);
8198 +#endif
8199 +
8200 +static struct pccard_operations bcm47xx_pcmcia_operations = {
8201 +       bcm47xx_pcmcia_init,
8202 +       bcm47xx_pcmcia_suspend,
8203 +       bcm47xx_pcmcia_register_callback,
8204 +       bcm47xx_pcmcia_inquire_socket,
8205 +       bcm47xx_pcmcia_get_status,
8206 +       bcm47xx_pcmcia_get_socket,
8207 +       bcm47xx_pcmcia_set_socket,
8208 +       bcm47xx_pcmcia_get_io_map,
8209 +       bcm47xx_pcmcia_set_io_map,
8210 +       bcm47xx_pcmcia_get_mem_map,
8211 +       bcm47xx_pcmcia_set_mem_map,
8212 +#ifdef CONFIG_PROC_FS
8213 +       bcm47xx_pcmcia_proc_setup
8214 +#endif
8215 +};
8216 +
8217 +
8218 +/*
8219 + * bcm47xx_pcmcia_driver_init()
8220 + *
8221 + * This routine performs a basic sanity check to ensure that this
8222 + * kernel has been built with the appropriate board-specific low-level
8223 + * PCMCIA support, performs low-level PCMCIA initialization, registers
8224 + * this socket driver with Card Services, and then spawns the daemon
8225 + * thread which is the real workhorse of the socket driver.
8226 + *
8227 + * Please see linux/Documentation/arm/SA1100/PCMCIA for more information
8228 + * on the low-level kernel interface.
8229 + *
8230 + * Returns: 0 on success, -1 on error
8231 + */
8232 +static int __init bcm47xx_pcmcia_driver_init(void)
8233 +{
8234 +       servinfo_t info;
8235 +       struct pcmcia_init pcmcia_init;
8236 +       struct pcmcia_state state;
8237 +       unsigned int i;
8238 +       unsigned long tmp;
8239 +
8240 +
8241 +       printk("\nBCM47XX PCMCIA (CS release %s)\n", CS_RELEASE);
8242 +
8243 +       CardServices(GetCardServicesInfo, &info);
8244 +
8245 +       if (info.Revision != CS_RELEASE_CODE) {
8246 +               printk(KERN_ERR "Card Services release codes do not match\n");
8247 +               return -1;
8248 +       }
8249 +
8250 +#ifdef CONFIG_BCM4710
8251 +       pcmcia_low_level=&bcm4710_pcmcia_ops;
8252 +#else
8253 +#error Unsupported Broadcom BCM47XX board.
8254 +#endif
8255 +
8256 +       pcmcia_init.handler=bcm47xx_pcmcia_interrupt;
8257 +
8258 +       if ((socket_count = pcmcia_low_level->init(&pcmcia_init)) < 0) {
8259 +               printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
8260 +               return -EIO;
8261 +       } else {
8262 +               printk("\t%d PCMCIA sockets initialized.\n", socket_count);
8263 +       }
8264 +
8265 +       pcmcia_socket = 
8266 +               kmalloc(sizeof(struct bcm47xx_pcmcia_socket) * socket_count, 
8267 +                               GFP_KERNEL);
8268 +       memset(pcmcia_socket, 0, 
8269 +                       sizeof(struct bcm47xx_pcmcia_socket) * socket_count);
8270 +       if (!pcmcia_socket) {
8271 +               printk(KERN_ERR "Card Services can't get memory \n");
8272 +               return -1;
8273 +       }
8274 +                       
8275 +       for (i = 0; i < socket_count; i++) {
8276 +               if (pcmcia_low_level->socket_state(i, &state) < 0) {
8277 +                       printk(KERN_ERR "Unable to get PCMCIA status\n");
8278 +                       return -EIO;
8279 +               }
8280 +               pcmcia_socket[i].k_state = state;
8281 +               pcmcia_socket[i].cs_state.csc_mask = SS_DETECT;
8282 +               
8283 +               if (i == 0) {
8284 +                       pcmcia_socket[i].virt_io =
8285 +                               (unsigned long)ioremap_nocache(EXTIF_PCMCIA_IOBASE(BCM4710_EXTIF), 0x1000);
8286 +                       /* Substract ioport base which gets added by in/out */
8287 +                       pcmcia_socket[i].virt_io -= mips_io_port_base;
8288 +                       pcmcia_socket[i].phys_attr =
8289 +                               (unsigned long)EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF);
8290 +                       pcmcia_socket[i].phys_mem =
8291 +                               (unsigned long)EXTIF_PCMCIA_MEMBASE(BCM4710_EXTIF);
8292 +               } else  {
8293 +                       printk(KERN_ERR "bcm4710: socket 1 not supported\n");
8294 +                       return 1;
8295 +               }
8296 +       }
8297 +
8298 +       /* Only advertise as many sockets as we can detect: */
8299 +       if (register_ss_entry(socket_count, &bcm47xx_pcmcia_operations) < 0) {
8300 +               printk(KERN_ERR "Unable to register socket service routine\n");
8301 +               return -ENXIO;
8302 +       }
8303 +
8304 +       /* Start the event poll timer.  
8305 +        * It will reschedule by itself afterwards. 
8306 +        */
8307 +       bcm47xx_pcmcia_poll_event(0);
8308 +
8309 +       DEBUG(1, "bcm4710: initialization complete\n");
8310 +       return 0;
8311 +
8312 +}
8313 +
8314 +module_init(bcm47xx_pcmcia_driver_init);
8315 +
8316 +
8317 +/*
8318 + * bcm47xx_pcmcia_driver_shutdown()
8319 + *
8320 + * Invokes the low-level kernel service to free IRQs associated with this
8321 + * socket controller and reset GPIO edge detection.
8322 + */
8323 +static void __exit bcm47xx_pcmcia_driver_shutdown(void)
8324 +{
8325 +       int i;
8326 +
8327 +       del_timer_sync(&poll_timer);
8328 +       unregister_ss_entry(&bcm47xx_pcmcia_operations);
8329 +       pcmcia_low_level->shutdown();
8330 +       flush_scheduled_tasks();
8331 +       for (i = 0; i < socket_count; i++) {
8332 +               if (pcmcia_socket[i].virt_io) 
8333 +                       iounmap((void *)pcmcia_socket[i].virt_io);
8334 +               if (pcmcia_socket[i].phys_attr) 
8335 +                       iounmap((void *)pcmcia_socket[i].phys_attr);
8336 +               if (pcmcia_socket[i].phys_mem) 
8337 +                       iounmap((void *)pcmcia_socket[i].phys_mem);
8338 +       }
8339 +       DEBUG(1, "bcm4710: shutdown complete\n");
8340 +}
8341 +
8342 +module_exit(bcm47xx_pcmcia_driver_shutdown);
8343 +
8344 +/*
8345 + * bcm47xx_pcmcia_init()
8346 + * We perform all of the interesting initialization tasks in 
8347 + * bcm47xx_pcmcia_driver_init().
8348 + *
8349 + * Returns: 0
8350 + */
8351 +static int bcm47xx_pcmcia_init(unsigned int sock)
8352 +{
8353 +       DEBUG(1, "%s(): initializing socket %u\n", __FUNCTION__, sock);
8354 +
8355 +       return 0;
8356 +}
8357 +
8358 +/*
8359 + * bcm47xx_pcmcia_suspend()
8360 + *
8361 + * We don't currently perform any actions on a suspend.
8362 + *
8363 + * Returns: 0
8364 + */
8365 +static int bcm47xx_pcmcia_suspend(unsigned int sock)
8366 +{
8367 +       DEBUG(1, "%s(): suspending socket %u\n", __FUNCTION__, sock);
8368 +
8369 +       return 0;
8370 +}
8371 +
8372 +
8373 +/*
8374 + * bcm47xx_pcmcia_events()
8375 + *
8376 + * Helper routine to generate a Card Services event mask based on
8377 + * state information obtained from the kernel low-level PCMCIA layer
8378 + * in a recent (and previous) sampling. Updates `prev_state'.
8379 + *
8380 + * Returns: an event mask for the given socket state.
8381 + */
8382 +static inline unsigned 
8383 +bcm47xx_pcmcia_events(struct pcmcia_state *state, 
8384 +               struct pcmcia_state *prev_state, 
8385 +               unsigned int mask, unsigned int flags)
8386 +{
8387 +       unsigned int events=0;
8388 +
8389 +       if (state->bvd1 != prev_state->bvd1) {
8390 +
8391 +               DEBUG(3, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1);
8392 +
8393 +               events |= mask & (flags & SS_IOCARD) ? SS_STSCHG : SS_BATDEAD;
8394 +       }
8395 +
8396 +       if (state->bvd2 != prev_state->bvd2) {
8397 +
8398 +               DEBUG(3, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2);
8399 +
8400 +               events |= mask & (flags & SS_IOCARD) ? 0 : SS_BATWARN;
8401 +       }
8402 +
8403 +       if (state->detect != prev_state->detect) {
8404 +
8405 +               DEBUG(3, "%s(): card detect value %u\n", __FUNCTION__, state->detect);
8406 +
8407 +               events |= mask & SS_DETECT;
8408 +       }
8409 +
8410 +
8411 +       if (state->ready != prev_state->ready) {
8412 +
8413 +               DEBUG(3, "%s(): card ready value %u\n", __FUNCTION__, state->ready);
8414 +
8415 +               events |= mask & ((flags & SS_IOCARD) ? 0 : SS_READY);
8416 +       }
8417 +
8418 +       if (events != 0) {
8419 +               DEBUG(2, "events: %s%s%s%s%s\n",
8420 +                     (events & SS_DETECT) ? "DETECT " : "",
8421 +                     (events & SS_READY) ? "READY " : "",
8422 +                     (events & SS_BATDEAD) ? "BATDEAD " : "",
8423 +                     (events & SS_BATWARN) ? "BATWARN " : "",
8424 +                     (events & SS_STSCHG) ? "STSCHG " : "");
8425 +       }
8426 +
8427 +       *prev_state=*state;
8428 +       return events;
8429 +}
8430 +
8431 +
8432 +/* 
8433 + * bcm47xx_pcmcia_task_handler()
8434 + *
8435 + * Processes serviceable socket events using the "eventd" thread context.
8436 + *
8437 + * Event processing (specifically, the invocation of the Card Services event
8438 + * callback) occurs in this thread rather than in the actual interrupt
8439 + * handler due to the use of scheduling operations in the PCMCIA core.
8440 + */
8441 +static void bcm47xx_pcmcia_task_handler(void *data) 
8442 +{
8443 +       struct pcmcia_state state;
8444 +       int i, events, irq_status;
8445 +
8446 +       DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
8447 +
8448 +       for (i = 0; i < socket_count; i++)  {
8449 +               if ((irq_status = pcmcia_low_level->socket_state(i, &state)) < 0)
8450 +                       printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n");
8451 +
8452 +               events = bcm47xx_pcmcia_events(&state, 
8453 +                                              &pcmcia_socket[i].k_state, 
8454 +                                              pcmcia_socket[i].cs_state.csc_mask, 
8455 +                                              pcmcia_socket[i].cs_state.flags);
8456 +
8457 +               if (pcmcia_socket[i].handler != NULL) {
8458 +                       pcmcia_socket[i].handler(pcmcia_socket[i].handler_info,
8459 +                                                events);
8460 +               }
8461 +       }
8462 +}
8463 +
8464 +static struct tq_struct bcm47xx_pcmcia_task = {
8465 +       routine: bcm47xx_pcmcia_task_handler
8466 +};
8467 +
8468 +
8469 +/*
8470 + * bcm47xx_pcmcia_poll_event()
8471 + *
8472 + * Let's poll for events in addition to IRQs since IRQ only is unreliable...
8473 + */
8474 +static void bcm47xx_pcmcia_poll_event(unsigned long dummy)
8475 +{
8476 +       DEBUG(4, "%s(): polling for events\n", __FUNCTION__);
8477 +
8478 +       poll_timer.function = bcm47xx_pcmcia_poll_event;
8479 +       poll_timer.expires = jiffies + BCM47XX_PCMCIA_POLL_PERIOD;
8480 +       add_timer(&poll_timer);
8481 +       schedule_task(&bcm47xx_pcmcia_task);
8482 +}
8483 +
8484 +
8485 +/* 
8486 + * bcm47xx_pcmcia_interrupt()
8487 + *
8488 + * Service routine for socket driver interrupts (requested by the
8489 + * low-level PCMCIA init() operation via bcm47xx_pcmcia_thread()).
8490 + *
8491 + * The actual interrupt-servicing work is performed by
8492 + * bcm47xx_pcmcia_task(), largely because the Card Services event-
8493 + * handling code performs scheduling operations which cannot be
8494 + * executed from within an interrupt context.
8495 + */
8496 +static void 
8497 +bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
8498 +{
8499 +       DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
8500 +       schedule_task(&bcm47xx_pcmcia_task);
8501 +}
8502 +
8503 +
8504 +/*
8505 + * bcm47xx_pcmcia_register_callback()
8506 + *
8507 + * Implements the register_callback() operation for the in-kernel
8508 + * PCMCIA service (formerly SS_RegisterCallback in Card Services). If 
8509 + * the function pointer `handler' is not NULL, remember the callback 
8510 + * location in the state for `sock', and increment the usage counter 
8511 + * for the driver module. (The callback is invoked from the interrupt
8512 + * service routine, bcm47xx_pcmcia_interrupt(), to notify Card Services
8513 + * of interesting events.) Otherwise, clear the callback pointer in the
8514 + * socket state and decrement the module usage count.
8515 + *
8516 + * Returns: 0
8517 + */
8518 +static int 
8519 +bcm47xx_pcmcia_register_callback(unsigned int sock, 
8520 +               void (*handler)(void *, unsigned int), void *info)
8521 +{
8522 +       if (handler == NULL) {
8523 +               pcmcia_socket[sock].handler = NULL;
8524 +               MOD_DEC_USE_COUNT;
8525 +       } else {
8526 +               MOD_INC_USE_COUNT;
8527 +               pcmcia_socket[sock].handler = handler;
8528 +               pcmcia_socket[sock].handler_info = info;
8529 +       }
8530 +       return 0;
8531 +}
8532 +
8533 +
8534 +/*
8535 + * bcm47xx_pcmcia_inquire_socket()
8536 + *
8537 + * Implements the inquire_socket() operation for the in-kernel PCMCIA
8538 + * service (formerly SS_InquireSocket in Card Services). Of note is
8539 + * the setting of the SS_CAP_PAGE_REGS bit in the `features' field of
8540 + * `cap' to "trick" Card Services into tolerating large "I/O memory" 
8541 + * addresses. Also set is SS_CAP_STATIC_MAP, which disables the memory
8542 + * resource database check. (Mapped memory is set up within the socket
8543 + * driver itself.)
8544 + *
8545 + * In conjunction with the STATIC_MAP capability is a new field,
8546 + * `io_offset', recommended by David Hinds. Rather than go through
8547 + * the SetIOMap interface (which is not quite suited for communicating
8548 + * window locations up from the socket driver), we just pass up
8549 + * an offset which is applied to client-requested base I/O addresses
8550 + * in alloc_io_space().
8551 + *
8552 + * Returns: 0 on success, -1 if no pin has been configured for `sock'
8553 + */
8554 +static int
8555 +bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
8556 +{
8557 +       struct pcmcia_irq_info irq_info;
8558 +
8559 +       if (sock >= socket_count) {
8560 +               printk(KERN_ERR "bcm47xx: socket %u not configured\n", sock);
8561 +               return -1;
8562 +       }
8563 +
8564 +       /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
8565 +        *   force_low argument to validate_mem() in rsrc_mgr.c -- since in
8566 +        *   general, the mapped * addresses of the PCMCIA memory regions
8567 +        *   will not be within 0xffff, setting force_low would be
8568 +        *   undesirable.
8569 +        *
8570 +        * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
8571 +        *   resource database; we instead pass up physical address ranges
8572 +        *   and allow other parts of Card Services to deal with remapping.
8573 +        *
8574 +        * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
8575 +        *   not 32-bit CardBus devices.
8576 +        */
8577 +       cap->features = (SS_CAP_PAGE_REGS  | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
8578 +
8579 +       irq_info.sock = sock;
8580 +       irq_info.irq = -1;
8581 +
8582 +       if (pcmcia_low_level->get_irq_info(&irq_info) < 0) {
8583 +               printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock);
8584 +               return -1;
8585 +       }
8586 +
8587 +       cap->irq_mask = 0;
8588 +       cap->map_size = PAGE_SIZE;
8589 +       cap->pci_irq = irq_info.irq;
8590 +       cap->io_offset = pcmcia_socket[sock].virt_io;
8591 +
8592 +       return 0;
8593 +}
8594 +
8595 +
8596 +/*
8597 + * bcm47xx_pcmcia_get_status()
8598 + *
8599 + * Implements the get_status() operation for the in-kernel PCMCIA
8600 + * service (formerly SS_GetStatus in Card Services). Essentially just
8601 + * fills in bits in `status' according to internal driver state or
8602 + * the value of the voltage detect chipselect register.
8603 + *
8604 + * As a debugging note, during card startup, the PCMCIA core issues
8605 + * three set_socket() commands in a row the first with RESET deasserted,
8606 + * the second with RESET asserted, and the last with RESET deasserted
8607 + * again. Following the third set_socket(), a get_status() command will
8608 + * be issued. The kernel is looking for the SS_READY flag (see
8609 + * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
8610 + *
8611 + * Returns: 0
8612 + */
8613 +static int 
8614 +bcm47xx_pcmcia_get_status(unsigned int sock, unsigned int *status)
8615 +{
8616 +       struct pcmcia_state state;
8617 +
8618 +
8619 +       if ((pcmcia_low_level->socket_state(sock, &state)) < 0) {
8620 +               printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
8621 +               return -1;
8622 +       }
8623 +
8624 +       pcmcia_socket[sock].k_state = state;
8625 +
8626 +       *status = state.detect ? SS_DETECT : 0;
8627 +
8628 +       *status |= state.ready ? SS_READY : 0;
8629 +
8630 +       /* The power status of individual sockets is not available
8631 +        * explicitly from the hardware, so we just remember the state
8632 +        * and regurgitate it upon request:
8633 +        */
8634 +       *status |= pcmcia_socket[sock].cs_state.Vcc ? SS_POWERON : 0;
8635 +
8636 +       if (pcmcia_socket[sock].cs_state.flags & SS_IOCARD)
8637 +               *status |= state.bvd1 ? SS_STSCHG : 0;
8638 +       else {
8639 +               if (state.bvd1 == 0)
8640 +                       *status |= SS_BATDEAD;
8641 +               else if (state.bvd2 == 0)
8642 +                       *status |= SS_BATWARN;
8643 +       }
8644 +
8645 +       *status |= state.vs_3v ? SS_3VCARD : 0;
8646 +
8647 +       *status |= state.vs_Xv ? SS_XVCARD : 0;
8648 +
8649 +       DEBUG(2, "\tstatus: %s%s%s%s%s%s%s%s\n",
8650 +             (*status&SS_DETECT)?"DETECT ":"",
8651 +             (*status&SS_READY)?"READY ":"", 
8652 +             (*status&SS_BATDEAD)?"BATDEAD ":"",
8653 +             (*status&SS_BATWARN)?"BATWARN ":"",
8654 +             (*status&SS_POWERON)?"POWERON ":"",
8655 +             (*status&SS_STSCHG)?"STSCHG ":"",
8656 +             (*status&SS_3VCARD)?"3VCARD ":"",
8657 +             (*status&SS_XVCARD)?"XVCARD ":"");
8658 +
8659 +       return 0;
8660 +}
8661 +
8662 +
8663 +/*
8664 + * bcm47xx_pcmcia_get_socket()
8665 + *
8666 + * Implements the get_socket() operation for the in-kernel PCMCIA
8667 + * service (formerly SS_GetSocket in Card Services). Not a very 
8668 + * exciting routine.
8669 + *
8670 + * Returns: 0
8671 + */
8672 +static int 
8673 +bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
8674 +{
8675 +       DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
8676 +
8677 +       /* This information was given to us in an earlier call to set_socket(),
8678 +        * so we're just regurgitating it here:
8679 +        */
8680 +       *state = pcmcia_socket[sock].cs_state;
8681 +       return 0;
8682 +}
8683 +
8684 +
8685 +/*
8686 + * bcm47xx_pcmcia_set_socket()
8687 + *
8688 + * Implements the set_socket() operation for the in-kernel PCMCIA
8689 + * service (formerly SS_SetSocket in Card Services). We more or
8690 + * less punt all of this work and let the kernel handle the details
8691 + * of power configuration, reset, &c. We also record the value of
8692 + * `state' in order to regurgitate it to the PCMCIA core later.
8693 + *
8694 + * Returns: 0
8695 + */
8696 +static int 
8697 +bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
8698 +{
8699 +       struct pcmcia_configure configure;
8700 +
8701 +       DEBUG(2, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
8702 +             "\tVcc %d  Vpp %d  irq %d\n",
8703 +             (state->csc_mask == 0) ? "<NONE>" : "",
8704 +             (state->csc_mask & SS_DETECT) ? "DETECT " : "",
8705 +             (state->csc_mask & SS_READY) ? "READY " : "",
8706 +             (state->csc_mask & SS_BATDEAD) ? "BATDEAD " : "",
8707 +             (state->csc_mask & SS_BATWARN) ? "BATWARN " : "",
8708 +             (state->csc_mask & SS_STSCHG) ? "STSCHG " : "",
8709 +             (state->flags == 0) ? "<NONE>" : "",
8710 +             (state->flags & SS_PWR_AUTO) ? "PWR_AUTO " : "",
8711 +             (state->flags & SS_IOCARD) ? "IOCARD " : "",
8712 +             (state->flags & SS_RESET) ? "RESET " : "",
8713 +             (state->flags & SS_SPKR_ENA) ? "SPKR_ENA " : "",
8714 +             (state->flags & SS_OUTPUT_ENA) ? "OUTPUT_ENA " : "",
8715 +             state->Vcc, state->Vpp, state->io_irq);
8716 +
8717 +       configure.sock = sock;
8718 +       configure.vcc = state->Vcc;
8719 +       configure.vpp = state->Vpp;
8720 +       configure.output = (state->flags & SS_OUTPUT_ENA) ? 1 : 0;
8721 +       configure.speaker = (state->flags & SS_SPKR_ENA) ? 1 : 0;
8722 +       configure.reset = (state->flags & SS_RESET) ? 1 : 0;
8723 +
8724 +       if (pcmcia_low_level->configure_socket(&configure) < 0) {
8725 +               printk(KERN_ERR "Unable to configure socket %u\n", sock);
8726 +               return -1;
8727 +       }
8728 +
8729 +       pcmcia_socket[sock].cs_state = *state;
8730 +       return 0;
8731 +}
8732 +
8733 +
8734 +/*
8735 + * bcm47xx_pcmcia_get_io_map()
8736 + *
8737 + * Implements the get_io_map() operation for the in-kernel PCMCIA
8738 + * service (formerly SS_GetIOMap in Card Services). Just returns an
8739 + * I/O map descriptor which was assigned earlier by a set_io_map().
8740 + *
8741 + * Returns: 0 on success, -1 if the map index was out of range
8742 + */
8743 +static int 
8744 +bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
8745 +{
8746 +       DEBUG(2, "bcm47xx_pcmcia_get_io_map: sock %d\n", sock);
8747 +
8748 +       if (map->map >= MAX_IO_WIN) {
8749 +               printk(KERN_ERR "%s(): map (%d) out of range\n", 
8750 +                      __FUNCTION__, map->map);
8751 +               return -1;
8752 +       }
8753 +
8754 +       *map = pcmcia_socket[sock].io_map[map->map];
8755 +       return 0;
8756 +}
8757 +
8758 +
8759 +/*
8760 + * bcm47xx_pcmcia_set_io_map()
8761 + *
8762 + * Implements the set_io_map() operation for the in-kernel PCMCIA
8763 + * service (formerly SS_SetIOMap in Card Services). We configure
8764 + * the map speed as requested, but override the address ranges
8765 + * supplied by Card Services.
8766 + *
8767 + * Returns: 0 on success, -1 on error
8768 + */
8769 +int 
8770 +bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
8771 +{
8772 +       unsigned int speed;
8773 +       unsigned long start;
8774 +
8775 +       DEBUG(2, "\tmap %u  speed %u\n\tstart 0x%08lx  stop 0x%08lx\n"
8776 +             "\tflags: %s%s%s%s%s%s%s%s\n",
8777 +             map->map, map->speed, map->start, map->stop,
8778 +             (map->flags == 0) ? "<NONE>" : "",
8779 +             (map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
8780 +             (map->flags & MAP_16BIT) ? "16BIT " : "",
8781 +             (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
8782 +             (map->flags & MAP_0WS) ? "0WS " : "",
8783 +             (map->flags & MAP_WRPROT) ? "WRPROT " : "",
8784 +             (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "",
8785 +             (map->flags & MAP_PREFETCH) ? "PREFETCH " : "");
8786 +
8787 +       if (map->map >= MAX_IO_WIN) {
8788 +               printk(KERN_ERR "%s(): map (%d) out of range\n", 
8789 +                               __FUNCTION__, map->map);
8790 +               return -1;
8791 +       }
8792 +
8793 +       if (map->flags & MAP_ACTIVE) {
8794 +               speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_IO_SPEED;
8795 +               pcmcia_socket[sock].speed_io = speed;
8796 +       }
8797 +
8798 +       start = map->start;
8799 +
8800 +       if (map->stop == 1) {
8801 +               map->stop = PAGE_SIZE - 1;
8802 +       }
8803 +
8804 +       map->start = pcmcia_socket[sock].virt_io;
8805 +       map->stop = map->start + (map->stop - start);
8806 +       pcmcia_socket[sock].io_map[map->map] = *map;
8807 +       DEBUG(2, "set_io_map %d start %x stop %x\n", 
8808 +             map->map, map->start, map->stop);
8809 +       return 0;
8810 +}
8811 +
8812 +
8813 +/*
8814 + * bcm47xx_pcmcia_get_mem_map()
8815 + *
8816 + * Implements the get_mem_map() operation for the in-kernel PCMCIA
8817 + * service (formerly SS_GetMemMap in Card Services). Just returns a
8818 + *  memory map descriptor which was assigned earlier by a
8819 + *  set_mem_map() request.
8820 + *
8821 + * Returns: 0 on success, -1 if the map index was out of range
8822 + */
8823 +static int 
8824 +bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
8825 +{
8826 +       DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
8827 +
8828 +       if (map->map >= MAX_WIN) {
8829 +               printk(KERN_ERR "%s(): map (%d) out of range\n", 
8830 +                      __FUNCTION__, map->map);
8831 +               return -1;
8832 +       }
8833 +
8834 +       *map = pcmcia_socket[sock].mem_map[map->map];
8835 +       return 0;
8836 +}
8837 +
8838 +
8839 +/*
8840 + * bcm47xx_pcmcia_set_mem_map()
8841 + *
8842 + * Implements the set_mem_map() operation for the in-kernel PCMCIA
8843 + * service (formerly SS_SetMemMap in Card Services). We configure
8844 + * the map speed as requested, but override the address ranges
8845 + * supplied by Card Services.
8846 + *
8847 + * Returns: 0 on success, -1 on error
8848 + */
8849 +static int 
8850 +bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
8851 +{
8852 +       unsigned int speed;
8853 +       unsigned long start;
8854 +       u_long flags;
8855 +
8856 +       if (map->map >= MAX_WIN) {
8857 +               printk(KERN_ERR "%s(): map (%d) out of range\n", 
8858 +                      __FUNCTION__, map->map);
8859 +               return -1;
8860 +       }
8861 +
8862 +       DEBUG(2, "\tmap %u  speed %u\n\tsys_start  %#lx\n"
8863 +             "\tsys_stop   %#lx\n\tcard_start %#x\n"
8864 +             "\tflags: %s%s%s%s%s%s%s%s\n",
8865 +             map->map, map->speed, map->sys_start, map->sys_stop,
8866 +             map->card_start, (map->flags == 0) ? "<NONE>" : "",
8867 +             (map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
8868 +             (map->flags & MAP_16BIT) ? "16BIT " : "",
8869 +             (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
8870 +             (map->flags & MAP_0WS) ? "0WS " : "",
8871 +             (map->flags & MAP_WRPROT) ? "WRPROT " : "",
8872 +             (map->flags & MAP_ATTRIB) ? "ATTRIB " : "",
8873 +             (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "");
8874 +
8875 +       if (map->flags & MAP_ACTIVE) {
8876 +               /* When clients issue RequestMap, the access speed is not always
8877 +                * properly configured:
8878 +                */
8879 +               speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_MEM_SPEED;
8880 +
8881 +               /* TBD */
8882 +               if (map->flags & MAP_ATTRIB) {
8883 +                       pcmcia_socket[sock].speed_attr = speed;
8884 +               } else {
8885 +                       pcmcia_socket[sock].speed_mem = speed;
8886 +               }
8887 +       }
8888 +
8889 +       save_flags(flags);
8890 +       cli();
8891 +       start = map->sys_start;
8892 +
8893 +       if (map->sys_stop == 0)
8894 +               map->sys_stop = PAGE_SIZE - 1;
8895 +
8896 +       if (map->flags & MAP_ATTRIB) {
8897 +               map->sys_start = pcmcia_socket[sock].phys_attr + 
8898 +                       map->card_start;
8899 +       } else {
8900 +               map->sys_start = pcmcia_socket[sock].phys_mem + 
8901 +                       map->card_start;
8902 +       }
8903 +
8904 +       map->sys_stop = map->sys_start + (map->sys_stop - start);
8905 +       pcmcia_socket[sock].mem_map[map->map] = *map;
8906 +       restore_flags(flags);
8907 +       DEBUG(2, "set_mem_map %d start %x stop %x card_start %x\n", 
8908 +                       map->map, map->sys_start, map->sys_stop, 
8909 +                       map->card_start);
8910 +       return 0;
8911 +}
8912 +
8913 +
8914 +#if defined(CONFIG_PROC_FS)
8915 +
8916 +/*
8917 + * bcm47xx_pcmcia_proc_setup()
8918 + *
8919 + * Implements the proc_setup() operation for the in-kernel PCMCIA
8920 + * service (formerly SS_ProcSetup in Card Services).
8921 + *
8922 + * Returns: 0 on success, -1 on error
8923 + */
8924 +static void 
8925 +bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
8926 +{
8927 +       struct proc_dir_entry *entry;
8928 +
8929 +       if ((entry = create_proc_entry("status", 0, base)) == NULL) {
8930 +               printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
8931 +               return;
8932 +       }
8933 +
8934 +       entry->read_proc = bcm47xx_pcmcia_proc_status;
8935 +       entry->data = (void *)sock;
8936 +}
8937 +
8938 +
8939 +/*
8940 + * bcm47xx_pcmcia_proc_status()
8941 + *
8942 + * Implements the /proc/bus/pccard/??/status file.
8943 + *
8944 + * Returns: the number of characters added to the buffer
8945 + */
8946 +static int 
8947 +bcm47xx_pcmcia_proc_status(char *buf, char **start, off_t pos, 
8948 +                          int count, int *eof, void *data)
8949 +{
8950 +       char *p = buf;
8951 +       unsigned int sock = (unsigned int)data;
8952 +
8953 +       p += sprintf(p, "k_flags  : %s%s%s%s%s%s%s\n", 
8954 +                    pcmcia_socket[sock].k_state.detect ? "detect " : "",
8955 +                    pcmcia_socket[sock].k_state.ready ? "ready " : "",
8956 +                    pcmcia_socket[sock].k_state.bvd1 ? "bvd1 " : "",
8957 +                    pcmcia_socket[sock].k_state.bvd2 ? "bvd2 " : "",
8958 +                    pcmcia_socket[sock].k_state.wrprot ? "wrprot " : "",
8959 +                    pcmcia_socket[sock].k_state.vs_3v ? "vs_3v " : "",
8960 +                    pcmcia_socket[sock].k_state.vs_Xv ? "vs_Xv " : "");
8961 +
8962 +       p += sprintf(p, "status   : %s%s%s%s%s%s%s%s%s\n",
8963 +                    pcmcia_socket[sock].k_state.detect ? "SS_DETECT " : "",
8964 +                    pcmcia_socket[sock].k_state.ready ? "SS_READY " : "",
8965 +                    pcmcia_socket[sock].cs_state.Vcc ? "SS_POWERON " : "",
8966 +                    pcmcia_socket[sock].cs_state.flags & SS_IOCARD ? "SS_IOCARD " : "",
8967 +                    (pcmcia_socket[sock].cs_state.flags & SS_IOCARD &&
8968 +                     pcmcia_socket[sock].k_state.bvd1) ? "SS_STSCHG " : "",
8969 +                    ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 &&
8970 +                     (pcmcia_socket[sock].k_state.bvd1 == 0)) ? "SS_BATDEAD " : "",
8971 +                    ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 &&
8972 +                     (pcmcia_socket[sock].k_state.bvd2 == 0)) ? "SS_BATWARN " : "",
8973 +                    pcmcia_socket[sock].k_state.vs_3v ? "SS_3VCARD " : "",
8974 +                    pcmcia_socket[sock].k_state.vs_Xv ? "SS_XVCARD " : "");
8975 +
8976 +       p += sprintf(p, "mask     : %s%s%s%s%s\n",
8977 +                    pcmcia_socket[sock].cs_state.csc_mask & SS_DETECT ? "SS_DETECT " : "",
8978 +                    pcmcia_socket[sock].cs_state.csc_mask & SS_READY ? "SS_READY " : "",
8979 +                    pcmcia_socket[sock].cs_state.csc_mask & SS_BATDEAD ? "SS_BATDEAD " : "",
8980 +                    pcmcia_socket[sock].cs_state.csc_mask & SS_BATWARN ? "SS_BATWARN " : "",
8981 +                    pcmcia_socket[sock].cs_state.csc_mask & SS_STSCHG ? "SS_STSCHG " : "");
8982 +
8983 +       p += sprintf(p, "cs_flags : %s%s%s%s%s\n",
8984 +                    pcmcia_socket[sock].cs_state.flags & SS_PWR_AUTO ?
8985 +                       "SS_PWR_AUTO " : "",
8986 +                    pcmcia_socket[sock].cs_state.flags & SS_IOCARD ?
8987 +                       "SS_IOCARD " : "",
8988 +                    pcmcia_socket[sock].cs_state.flags & SS_RESET ?
8989 +                       "SS_RESET " : "",
8990 +                    pcmcia_socket[sock].cs_state.flags & SS_SPKR_ENA ?
8991 +                       "SS_SPKR_ENA " : "",
8992 +                    pcmcia_socket[sock].cs_state.flags & SS_OUTPUT_ENA ?
8993 +                       "SS_OUTPUT_ENA " : "");
8994 +
8995 +       p += sprintf(p, "Vcc      : %d\n", pcmcia_socket[sock].cs_state.Vcc);
8996 +       p += sprintf(p, "Vpp      : %d\n", pcmcia_socket[sock].cs_state.Vpp);
8997 +       p += sprintf(p, "irq      : %d\n", pcmcia_socket[sock].cs_state.io_irq);
8998 +       p += sprintf(p, "I/O      : %u\n", pcmcia_socket[sock].speed_io);
8999 +       p += sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr);
9000 +       p += sprintf(p, "common   : %u\n", pcmcia_socket[sock].speed_mem);
9001 +       return p-buf;
9002 +}
9003 +
9004 +
9005 +#endif  /* defined(CONFIG_PROC_FS) */
9006 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
9007 +++ linux-2.4.20/drivers/pcmcia/bcm4710_pcmcia.c        2005-01-07 05:39:02.000000000 -0500
9008 @@ -0,0 +1,266 @@
9009 +/*
9010 + * BCM4710 specific pcmcia routines.
9011 + *
9012 + * Copyright 2004, Broadcom Corporation
9013 + * All Rights Reserved.
9014 + * 
9015 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
9016 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9017 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
9018 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
9019 + *
9020 + * $Id: bcm4710_pcmcia.c,v 1.1.1.7 2004/04/12 04:32:07 honor Exp $
9021 + */
9022 +#include <linux/module.h>
9023 +#include <linux/init.h>
9024 +#include <linux/config.h>
9025 +#include <linux/delay.h>
9026 +#include <linux/ioport.h>
9027 +#include <linux/kernel.h>
9028 +#include <linux/tqueue.h>
9029 +#include <linux/timer.h>
9030 +#include <linux/mm.h>
9031 +#include <linux/proc_fs.h>
9032 +#include <linux/version.h>
9033 +#include <linux/types.h>
9034 +#include <linux/pci.h>
9035 +
9036 +#include <pcmcia/version.h>
9037 +#include <pcmcia/cs_types.h>
9038 +#include <pcmcia/cs.h>
9039 +#include <pcmcia/ss.h>
9040 +#include <pcmcia/bulkmem.h>
9041 +#include <pcmcia/cistpl.h>
9042 +#include <pcmcia/bus_ops.h>
9043 +#include "cs_internal.h"
9044 +
9045 +#include <asm/io.h>
9046 +#include <asm/irq.h>
9047 +#include <asm/system.h>
9048 +
9049 +
9050 +#include <typedefs.h>
9051 +#include <bcmdevs.h>
9052 +#include <bcm4710.h>
9053 +#include <sbconfig.h>
9054 +#include <sbextif.h>
9055 +
9056 +#include "bcm4710pcmcia.h"
9057 +
9058 +/* Use a static var for irq dev_id */
9059 +static int bcm47xx_pcmcia_dev_id;
9060 +
9061 +/* Do we think we have a card or not? */
9062 +static int bcm47xx_pcmcia_present = 0;
9063 +
9064 +
9065 +static void bcm4710_pcmcia_reset(void)
9066 +{
9067 +       extifregs_t *eir;
9068 +       unsigned long s;
9069 +       uint32 out0, out1, outen;
9070 +
9071 +
9072 +       eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t));
9073 +
9074 +       save_and_cli(s);
9075 +
9076 +       /* Use gpio7 to reset the pcmcia slot */
9077 +       outen = readl(&eir->gpio[0].outen);
9078 +       outen |= BCM47XX_PCMCIA_RESET;
9079 +       out0 = readl(&eir->gpio[0].out);
9080 +       out0 &= ~(BCM47XX_PCMCIA_RESET);
9081 +       out1 = out0 | BCM47XX_PCMCIA_RESET;
9082 +
9083 +       writel(out0, &eir->gpio[0].out);
9084 +       writel(outen, &eir->gpio[0].outen);
9085 +       mdelay(1);
9086 +       writel(out1, &eir->gpio[0].out);
9087 +       mdelay(1);
9088 +       writel(out0, &eir->gpio[0].out);
9089 +
9090 +       restore_flags(s);
9091 +}
9092 +
9093 +
9094 +static int bcm4710_pcmcia_init(struct pcmcia_init *init)
9095 +{
9096 +       struct pci_dev *pdev;
9097 +       extifregs_t *eir;
9098 +       uint32 outen, intp, intm, tmp;
9099 +       uint16 *attrsp;
9100 +       int rc = 0, i;
9101 +       extern unsigned long bcm4710_cpu_cycle;
9102 +
9103 +
9104 +       if (!(pdev = pci_find_device(VENDOR_BROADCOM, SB_EXTIF, NULL))) {
9105 +               printk(KERN_ERR "bcm4710_pcmcia: extif not found\n");
9106 +               return -ENODEV;
9107 +       }
9108 +       eir = (extifregs_t *) ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
9109 +
9110 +       /* Initialize the pcmcia i/f: 16bit no swap */
9111 +       writel(CF_EM_PCMCIA | CF_DS | CF_EN, &eir->pcmcia_config);
9112 +
9113 +#ifdef notYet
9114 +
9115 +       /* Set the timing for memory accesses */
9116 +       tmp = (19 / bcm4710_cpu_cycle) << 24;           /* W3 = 10nS */
9117 +       tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16);   /* W2 = 20nS */
9118 +       tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8);   /* W1 = 100nS */
9119 +       tmp = tmp | (129 / bcm4710_cpu_cycle);          /* W0 = 120nS */
9120 +       writel(tmp, &eir->pcmcia_memwait);              /* 0x01020a0c for a 100Mhz clock */
9121 +
9122 +       /* Set the timing for I/O accesses */
9123 +       tmp = (19 / bcm4710_cpu_cycle) << 24;           /* W3 = 10nS */
9124 +       tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16);   /* W2 = 20nS */
9125 +       tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8);   /* W1 = 100nS */
9126 +       tmp = tmp | (129 / bcm4710_cpu_cycle);          /* W0 = 120nS */
9127 +       writel(tmp, &eir->pcmcia_iowait);               /* 0x01020a0c for a 100Mhz clock */
9128 +
9129 +       /* Set the timing for attribute accesses */
9130 +       tmp = (19 / bcm4710_cpu_cycle) << 24;           /* W3 = 10nS */
9131 +       tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16);   /* W2 = 20nS */
9132 +       tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8);   /* W1 = 100nS */
9133 +       tmp = tmp | (129 / bcm4710_cpu_cycle);          /* W0 = 120nS */
9134 +       writel(tmp, &eir->pcmcia_attrwait);             /* 0x01020a0c for a 100Mhz clock */
9135 +
9136 +#endif
9137 +       /* Make sure gpio0 and gpio5 are inputs */
9138 +       outen = readl(&eir->gpio[0].outen);
9139 +       outen &= ~(BCM47XX_PCMCIA_WP | BCM47XX_PCMCIA_STSCHG | BCM47XX_PCMCIA_RESET);
9140 +       writel(outen, &eir->gpio[0].outen);
9141 +
9142 +       /* Issue a reset to the pcmcia socket */
9143 +       bcm4710_pcmcia_reset();
9144 +
9145 +#ifdef DO_BCM47XX_PCMCIA_INTERRUPTS
9146 +       /* Setup gpio5 to be the STSCHG interrupt */
9147 +       intp = readl(&eir->gpiointpolarity);
9148 +       writel(intp | BCM47XX_PCMCIA_STSCHG, &eir->gpiointpolarity);    /* Active low */
9149 +       intm = readl(&eir->gpiointmask);
9150 +       writel(intm | BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask);        /* Enable it */
9151 +#endif
9152 +
9153 +       DEBUG(2, "bcm4710_pcmcia after reset:\n");
9154 +       DEBUG(2, "\textstatus\t= 0x%08x:\n", readl(&eir->extstatus));
9155 +       DEBUG(2, "\tpcmcia_config\t= 0x%08x:\n", readl(&eir->pcmcia_config));
9156 +       DEBUG(2, "\tpcmcia_memwait\t= 0x%08x:\n", readl(&eir->pcmcia_memwait));
9157 +       DEBUG(2, "\tpcmcia_attrwait\t= 0x%08x:\n", readl(&eir->pcmcia_attrwait));
9158 +       DEBUG(2, "\tpcmcia_iowait\t= 0x%08x:\n", readl(&eir->pcmcia_iowait));
9159 +       DEBUG(2, "\tgpioin\t\t= 0x%08x:\n", readl(&eir->gpioin));
9160 +       DEBUG(2, "\tgpio_outen0\t= 0x%08x:\n", readl(&eir->gpio[0].outen));
9161 +       DEBUG(2, "\tgpio_out0\t= 0x%08x:\n", readl(&eir->gpio[0].out));
9162 +       DEBUG(2, "\tgpiointpolarity\t= 0x%08x:\n", readl(&eir->gpiointpolarity));
9163 +       DEBUG(2, "\tgpiointmask\t= 0x%08x:\n", readl(&eir->gpiointmask));
9164 +
9165 +#ifdef DO_BCM47XX_PCMCIA_INTERRUPTS
9166 +       /* Request pcmcia interrupt */
9167 +       rc =  request_irq(BCM47XX_PCMCIA_IRQ, init->handler, SA_INTERRUPT,
9168 +                         "PCMCIA Interrupt", &bcm47xx_pcmcia_dev_id);
9169 +#endif
9170 +
9171 +       attrsp = (uint16 *)ioremap_nocache(EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF), 0x1000);
9172 +       tmp = readw(&attrsp[0]);
9173 +       DEBUG(2, "\tattr[0] = 0x%04x\n", tmp);
9174 +       if ((tmp == 0x7fff) || (tmp == 0x7f00)) {
9175 +               bcm47xx_pcmcia_present = 0;
9176 +       } else {
9177 +               bcm47xx_pcmcia_present = 1;
9178 +       }
9179 +
9180 +       /* There's only one socket */
9181 +       return 1;
9182 +}
9183 +
9184 +static int bcm4710_pcmcia_shutdown(void)
9185 +{
9186 +       extifregs_t *eir;
9187 +       uint32 intm;
9188 +
9189 +       eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t));
9190 +
9191 +       /* Disable the pcmcia i/f */
9192 +       writel(0, &eir->pcmcia_config);
9193 +
9194 +       /* Reset gpio's */
9195 +       intm = readl(&eir->gpiointmask);
9196 +       writel(intm & ~BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask);       /* Disable it */
9197 +
9198 +       free_irq(BCM47XX_PCMCIA_IRQ, &bcm47xx_pcmcia_dev_id);
9199 +
9200 +       return 0;
9201 +}
9202 +
9203 +static int 
9204 +bcm4710_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
9205 +{
9206 +       extifregs_t *eir;
9207 +
9208 +       eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t));
9209 +
9210 +
9211 +       if (sock != 0) {
9212 +               printk(KERN_ERR "bcm4710 socket_state bad sock %d\n", sock);
9213 +               return -1;
9214 +       }
9215 +
9216 +       if (bcm47xx_pcmcia_present) {
9217 +               state->detect = 1;
9218 +               state->ready = 1;
9219 +               state->bvd1 = 1;
9220 +               state->bvd2 = 1;
9221 +               state->wrprot = (readl(&eir->gpioin) & BCM47XX_PCMCIA_WP) == BCM47XX_PCMCIA_WP; 
9222 +               state->vs_3v = 0;
9223 +               state->vs_Xv = 0;
9224 +       } else {
9225 +               state->detect = 0;
9226 +               state->ready = 0;
9227 +       }
9228 +
9229 +       return 1;
9230 +}
9231 +
9232 +
9233 +static int bcm4710_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
9234 +{
9235 +       if (info->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1;
9236 +
9237 +       info->irq = BCM47XX_PCMCIA_IRQ;         
9238 +
9239 +       return 0;
9240 +}
9241 +
9242 +
9243 +static int 
9244 +bcm4710_pcmcia_configure_socket(const struct pcmcia_configure *configure)
9245 +{
9246 +       if (configure->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1;
9247 +
9248 +
9249 +       DEBUG(2, "Vcc %dV Vpp %dV output %d speaker %d reset %d\n", configure->vcc,
9250 +             configure->vpp, configure->output, configure->speaker, configure->reset);
9251 +
9252 +       if ((configure->vcc != 50) || (configure->vpp != 50)) {
9253 +               printk("%s: bad Vcc/Vpp (%d:%d)\n", __FUNCTION__, configure->vcc, 
9254 +                      configure->vpp);
9255 +       }
9256 +
9257 +       if (configure->reset) {
9258 +               /* Issue a reset to the pcmcia socket */
9259 +               DEBUG(1, "%s: Reseting socket\n", __FUNCTION__);
9260 +               bcm4710_pcmcia_reset();
9261 +       }
9262 +
9263 +
9264 +       return 0;
9265 +}
9266 +
9267 +struct pcmcia_low_level bcm4710_pcmcia_ops = { 
9268 +       bcm4710_pcmcia_init,
9269 +       bcm4710_pcmcia_shutdown,
9270 +       bcm4710_pcmcia_socket_state,
9271 +       bcm4710_pcmcia_get_irq_info,
9272 +       bcm4710_pcmcia_configure_socket
9273 +};
9274 +
9275 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
9276 +++ linux-2.4.20/drivers/pcmcia/bcm4710pcmcia.h 2005-01-07 05:39:02.000000000 -0500
9277 @@ -0,0 +1,118 @@
9278 +/*
9279 + *
9280 + * bcm47xx pcmcia driver
9281 + *
9282 + * Copyright 2004, Broadcom Corporation
9283 + * All Rights Reserved.
9284 + * 
9285 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
9286 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9287 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
9288 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
9289 + *
9290 + * Based on sa1100.h and include/asm-arm/arch-sa1100/pcmica.h
9291 + *     from www.handhelds.org,
9292 + * and au1000_generic.c from oss.sgi.com.
9293 + *
9294 + * $Id: bcm4710pcmcia.h,v 1.1.1.7 2004/04/12 04:32:07 honor Exp $
9295 + */
9296 +
9297 +#if !defined(_BCM4710PCMCIA_H)
9298 +#define _BCM4710PCMCIA_H
9299 +
9300 +#include <pcmcia/cs_types.h>
9301 +#include <pcmcia/ss.h>
9302 +#include <pcmcia/bulkmem.h>
9303 +#include <pcmcia/cistpl.h>
9304 +#include "cs_internal.h"
9305 +
9306 +
9307 +/* The 47xx can only support one socket */
9308 +#define BCM47XX_PCMCIA_MAX_SOCK                1
9309 +
9310 +/* In the bcm947xx gpio's are used for some pcmcia functions */
9311 +#define        BCM47XX_PCMCIA_WP               0x01            /* Bit 0 is WP input */
9312 +#define        BCM47XX_PCMCIA_STSCHG           0x20            /* Bit 5 is STSCHG input/interrupt */
9313 +#define        BCM47XX_PCMCIA_RESET            0x80            /* Bit 7 is RESET */
9314 +
9315 +#define        BCM47XX_PCMCIA_IRQ              2
9316 +
9317 +/* The socket driver actually works nicely in interrupt-driven form,
9318 + * so the (relatively infrequent) polling is "just to be sure."
9319 + */
9320 +#define BCM47XX_PCMCIA_POLL_PERIOD    (2 * HZ)
9321 +
9322 +#define BCM47XX_PCMCIA_IO_SPEED       (255)
9323 +#define BCM47XX_PCMCIA_MEM_SPEED      (300)
9324 +
9325 +
9326 +struct pcmcia_state {
9327 +       unsigned detect: 1,
9328 +               ready: 1,
9329 +               bvd1: 1,
9330 +               bvd2: 1,
9331 +               wrprot: 1,
9332 +               vs_3v: 1,
9333 +               vs_Xv: 1;
9334 +};
9335 +
9336 +
9337 +struct pcmcia_configure {
9338 +       unsigned sock: 8,
9339 +               vcc: 8,
9340 +               vpp: 8,
9341 +               output: 1,
9342 +               speaker: 1,
9343 +               reset: 1;
9344 +};
9345 +
9346 +struct pcmcia_irq_info {
9347 +       unsigned int sock;
9348 +       unsigned int irq;
9349 +};
9350 +
9351 +/* This structure encapsulates per-socket state which we might need to
9352 + * use when responding to a Card Services query of some kind.
9353 + */
9354 +struct bcm47xx_pcmcia_socket {
9355 +  socket_state_t        cs_state;
9356 +  struct pcmcia_state   k_state;
9357 +  unsigned int          irq;
9358 +  void                  (*handler)(void *, unsigned int);
9359 +  void                  *handler_info;
9360 +  pccard_io_map         io_map[MAX_IO_WIN];
9361 +  pccard_mem_map        mem_map[MAX_WIN];
9362 +  ioaddr_t              virt_io, phys_attr, phys_mem;
9363 +  unsigned short        speed_io, speed_attr, speed_mem;
9364 +};
9365 +
9366 +struct pcmcia_init {
9367 +       void (*handler)(int irq, void *dev, struct pt_regs *regs);
9368 +};
9369 +
9370 +struct pcmcia_low_level {
9371 +       int (*init)(struct pcmcia_init *);
9372 +       int (*shutdown)(void);
9373 +       int (*socket_state)(unsigned sock, struct pcmcia_state *);
9374 +       int (*get_irq_info)(struct pcmcia_irq_info *);
9375 +       int (*configure_socket)(const struct pcmcia_configure *);
9376 +};
9377 +
9378 +extern struct pcmcia_low_level bcm47xx_pcmcia_ops;
9379 +
9380 +/* I/O pins replacing memory pins
9381 + * (PCMCIA System Architecture, 2nd ed., by Don Anderson, p.75)
9382 + *
9383 + * These signals change meaning when going from memory-only to 
9384 + * memory-or-I/O interface:
9385 + */
9386 +#define iostschg bvd1
9387 +#define iospkr   bvd2
9388 +
9389 +
9390 +/*
9391 + * Declaration for implementation specific low_level operations.
9392 + */
9393 +extern struct pcmcia_low_level bcm4710_pcmcia_ops;
9394 +
9395 +#endif  /* !defined(_BCM4710PCMCIA_H) */
9396 --- linux-2.4.20/include/asm-mips/asm.h~2.4.20_broadcom_3_37_2_1109_US.patch    2005-01-07 05:39:02.000000000 -0500
9397 +++ linux-2.4.20/include/asm-mips/asm.h 2005-01-08 12:10:12.593676448 -0500
9398 @@ -387,4 +387,16 @@
9399  
9400  #define SSNOP          sll zero,zero,1
9401  
9402 +/*
9403 + * mips32/64 has some extra CP0 register selected by the low bits of
9404 + * the mfc0/mtc0 instruction. Note that dst and src CANNOT have '$'
9405 + * signs in them.
9406 + */
9407 +#define MFC0_SEL(dst, src, sel)\
9408 +               .word (0x40000000 | ((dst)<<16) | ((src)<<11) | (sel))
9409 +
9410 +
9411 +#define MTC0_SEL(dst, src, sel)\
9412 +               .word (0x40800000 | ((dst)<<16) | ((src)<<11) | (sel))
9413 +
9414  #endif /* __ASM_ASM_H */
9415 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
9416 +++ linux-2.4.20/include/asm-mips/bcm4710_cache.h       2005-01-07 05:39:02.000000000 -0500
9417 @@ -0,0 +1,229 @@
9418 +
9419 +#ifndef _MIPS_R4KCACHE_H
9420 +#define _MIPS_R4KCACHE_H
9421 +
9422 +#include <asm/asm.h>
9423 +#include <asm/cacheops.h>
9424 +
9425 +#include <typedefs.h>
9426 +#include <sbconfig.h>
9427 +#include <bcm4710.h>
9428 +#include <asm/paccess.h>
9429 +#define BCM4710_DUMMY_RREG() (((sbconfig_t *)(KSEG1ADDR(BCM4710_REG_SDRAM + SBCONFIGOFF)))->sbimstate)
9430 +#define BCM4710_FILL_TLB(addr) (*(volatile unsigned long *)(addr))
9431 +#define BCM4710_PROTECTED_FILL_TLB(addr) ({ unsigned long x; get_dbe(x, (volatile unsigned long *)(addr)); })
9432 +
9433 +static inline void flush_icache_line_indexed(unsigned long addr)
9434 +{
9435 +       unsigned long waystep = icache_size/mips_cpu.icache.ways;
9436 +       unsigned int way;
9437 +
9438 +       for (way = 0; way < mips_cpu.icache.ways; way++)
9439 +       {
9440 +               __asm__ __volatile__(
9441 +                       ".set noreorder\n\t"
9442 +                       ".set mips3\n\t"
9443 +                       "cache %1, (%0)\n\t"
9444 +                       ".set mips0\n\t"
9445 +                       ".set reorder"
9446 +                       :
9447 +                       : "r" (addr),
9448 +                       "i" (Index_Invalidate_I));
9449 +               
9450 +               addr += waystep;
9451 +       }
9452 +}
9453 +
9454 +static inline void flush_dcache_line_indexed(unsigned long addr)
9455 +{
9456 +       unsigned long waystep = dcache_size/mips_cpu.dcache.ways;
9457 +       unsigned int way;
9458 +
9459 +       for (way = 0; way < mips_cpu.dcache.ways; way++)
9460 +       {
9461 +               BCM4710_DUMMY_RREG();
9462 +               __asm__ __volatile__(
9463 +                       ".set noreorder\n\t"
9464 +                       ".set mips3\n\t"
9465 +                       "cache %1, (%0)\n\t"
9466 +                       ".set mips0\n\t"
9467 +                       ".set reorder"
9468 +                       :
9469 +                       : "r" (addr),
9470 +                       "i" (Index_Writeback_Inv_D));
9471 +
9472 +               addr += waystep;
9473 +       }
9474 +}
9475 +
9476 +static inline void flush_icache_line(unsigned long addr)
9477 +{
9478 +
9479 +       __asm__ __volatile__(
9480 +               ".set noreorder\n\t"
9481 +               ".set mips3\n\t"
9482 +               "cache %1, (%0)\n\t"
9483 +               ".set mips0\n\t"
9484 +               ".set reorder"
9485 +               :
9486 +               : "r" (addr),
9487 +                 "i" (Hit_Invalidate_I));
9488 +}
9489 +
9490 +static inline void flush_dcache_line(unsigned long addr)
9491 +{
9492 +       BCM4710_DUMMY_RREG();
9493 +       __asm__ __volatile__(
9494 +               ".set noreorder\n\t"
9495 +               ".set mips3\n\t"
9496 +               "cache %1, (%0)\n\t"
9497 +               ".set mips0\n\t"
9498 +               ".set reorder"
9499 +               :
9500 +               : "r" (addr),
9501 +                 "i" (Hit_Writeback_Inv_D));
9502 +}
9503 +
9504 +static inline void invalidate_dcache_line(unsigned long addr)
9505 +{
9506 +       __asm__ __volatile__(
9507 +               ".set noreorder\n\t"
9508 +               ".set mips3\n\t"
9509 +               "cache %1, (%0)\n\t"
9510 +               ".set mips0\n\t"
9511 +               ".set reorder"
9512 +               :
9513 +               : "r" (addr),
9514 +                 "i" (Hit_Invalidate_D));
9515 +}
9516 +
9517 +/*
9518 + * The next two are for badland addresses like signal trampolines.
9519 + */
9520 +static inline void protected_flush_icache_line(unsigned long addr)
9521 +{
9522 +       __asm__ __volatile__(
9523 +               ".set noreorder\n\t"
9524 +               ".set mips3\n"
9525 +               "1:\tcache %1,(%0)\n"
9526 +               "2:\t.set mips0\n\t"
9527 +               ".set reorder\n\t"
9528 +               ".section\t__ex_table,\"a\"\n\t"
9529 +               STR(PTR)"\t1b,2b\n\t"
9530 +               ".previous"
9531 +               :
9532 +               : "r" (addr),
9533 +                 "i" (Hit_Invalidate_I));
9534 +}
9535 +
9536 +static inline void protected_writeback_dcache_line(unsigned long addr)
9537 +{
9538 +       BCM4710_DUMMY_RREG();
9539 +       __asm__ __volatile__(
9540 +               ".set noreorder\n\t"
9541 +               ".set mips3\n"
9542 +               "1:\tcache %1,(%0)\n"
9543 +               "2:\t.set mips0\n\t"
9544 +               ".set reorder\n\t"
9545 +               ".section\t__ex_table,\"a\"\n\t"
9546 +               STR(PTR)"\t1b,2b\n\t"
9547 +               ".previous"
9548 +               :
9549 +               : "r" (addr),
9550 +                 "i" (Hit_Writeback_D));
9551 +}
9552 +
9553 +#define cache_unroll(base,op)                  \
9554 +       __asm__ __volatile__("                  \
9555 +               .set noreorder;                 \
9556 +               .set mips3;                     \
9557 +                cache %1, (%0);                        \
9558 +               .set mips0;                     \
9559 +               .set reorder"                   \
9560 +               :                               \
9561 +               : "r" (base),                   \
9562 +                 "i" (op));
9563 +
9564 +
9565 +static inline void blast_dcache(void)
9566 +{
9567 +       unsigned long start = KSEG0;
9568 +       unsigned long end = (start + dcache_size);
9569 +
9570 +       while(start < end) {
9571 +               BCM4710_DUMMY_RREG();
9572 +               cache_unroll(start,Index_Writeback_Inv_D);
9573 +               start += dc_lsize;
9574 +       }
9575 +}
9576 +
9577 +static inline void blast_dcache_page(unsigned long page)
9578 +{
9579 +       unsigned long start = page;
9580 +       unsigned long end = (start + PAGE_SIZE);
9581 +
9582 +       BCM4710_FILL_TLB(start);
9583 +       while(start < end) {
9584 +               BCM4710_DUMMY_RREG();
9585 +               cache_unroll(start,Hit_Writeback_Inv_D);
9586 +               start += dc_lsize;
9587 +       }
9588 +}
9589 +
9590 +static inline void blast_dcache_page_indexed(unsigned long page)
9591 +{
9592 +       unsigned long start;
9593 +       unsigned long end = (page + PAGE_SIZE);
9594 +       unsigned long waystep = dcache_size/mips_cpu.dcache.ways;
9595 +       unsigned int way;
9596 +
9597 +       for (way = 0; way < mips_cpu.dcache.ways; way++) {
9598 +               start = page + way*waystep;
9599 +               while(start < end) {
9600 +                       BCM4710_DUMMY_RREG();
9601 +                       cache_unroll(start,Index_Writeback_Inv_D);
9602 +                       start += dc_lsize;
9603 +               }
9604 +       }
9605 +}
9606 +
9607 +static inline void blast_icache(void)
9608 +{
9609 +       unsigned long start = KSEG0;
9610 +       unsigned long end = (start + icache_size);
9611 +
9612 +       while(start < end) {
9613 +               cache_unroll(start,Index_Invalidate_I);
9614 +               start += ic_lsize;
9615 +       }
9616 +}
9617 +
9618 +static inline void blast_icache_page(unsigned long page)
9619 +{
9620 +       unsigned long start = page;
9621 +       unsigned long end = (start + PAGE_SIZE);
9622 +
9623 +       BCM4710_FILL_TLB(start);
9624 +       while(start < end) {
9625 +               cache_unroll(start,Hit_Invalidate_I);
9626 +               start += ic_lsize;
9627 +       }
9628 +}
9629 +
9630 +static inline void blast_icache_page_indexed(unsigned long page)
9631 +{
9632 +       unsigned long start;
9633 +       unsigned long end = (page + PAGE_SIZE);
9634 +       unsigned long waystep = icache_size/mips_cpu.icache.ways;
9635 +       unsigned int way;
9636 +
9637 +       for (way = 0; way < mips_cpu.icache.ways; way++) {
9638 +               start = page + way*waystep;
9639 +               while(start < end) {
9640 +                       cache_unroll(start,Index_Invalidate_I);
9641 +                       start += ic_lsize;
9642 +               }
9643 +       }
9644 +}
9645 +
9646 +#endif /* !(_MIPS_R4KCACHE_H) */
9647 --- linux-2.4.20/include/asm-mips/bootinfo.h~2.4.20_broadcom_3_37_2_1109_US.patch       2005-01-07 05:39:02.000000000 -0500
9648 +++ linux-2.4.20/include/asm-mips/bootinfo.h    2005-01-08 12:17:06.878695552 -0500
9649 @@ -36,6 +36,7 @@
9650  #define MACH_GROUP_NEC_VR41XX  19 /* NEC Vr41xx based boards/gadgets        */
9651  #define MACH_GROUP_HP_LJ       20 /* Hewlett Packard LaserJet               */
9652  #define MACH_GROUP_LASAT       21
9653 +#define MACH_GROUP_BRCM        22 /* Broadcom Boards */
9654  
9655  /*
9656   * Valid machtype values for group unknown (low order halfword of mips_machtype)
9657 @@ -179,7 +180,15 @@
9658  #define MACH_VICTOR_MPC30X     3       /* Victor MP-C303/304 */
9659  #define MACH_IBM_WORKPAD       4       /* IBM WorkPad z50 */
9660  #define MACH_CASIO_E55         5       /* CASIO CASSIOPEIA E-10/15/55/65 */
9661 -#define MACH_TANBAC_TB0226     6       /* TANBAC TB0226 (MBASE) */
9662 +
9663 +/*
9664 + * Valid machtypes for group Broadcom
9665 + */
9666 +#define MACH_BCM93725          0
9667 +#define MACH_BCM93725_VJ       1
9668 +#define MACH_BCM93730          2
9669 +#define MACH_BCM947XX          3
9670 +#define MACH_BCM933XX          4
9671  
9672  #define CL_SIZE                        (256)
9673  
9674 --- linux-2.4.20/include/asm-mips/cpu.h~2.4.20_broadcom_3_37_2_1109_US.patch    2005-01-07 05:38:15.000000000 -0500
9675 +++ linux-2.4.20/include/asm-mips/cpu.h 2005-01-08 12:10:11.203887728 -0500
9676 @@ -24,6 +24,11 @@
9677     spec.
9678  */
9679  
9680 +#define PRID_COPT_MASK         0xff000000
9681 +#define PRID_COMP_MASK         0x00ff0000
9682 +#define PRID_IMP_MASK          0x0000ff00
9683 +#define PRID_REV_MASK          0x000000ff
9684 +
9685  #define PRID_COMP_LEGACY       0x000000
9686  #define PRID_COMP_MIPS         0x010000
9687  #define PRID_COMP_BROADCOM     0x020000
9688 @@ -65,10 +70,17 @@
9689  #define PRID_IMP_20KC          0x8200
9690  #define PRID_IMP_4KEC          0x8400
9691  #define PRID_IMP_4KSC          0x8600
9692 -
9693 +#define PRID_IMP_BCM4710       0x4000
9694 +#define PRID_IMP_BCM3302       0x9000
9695 +#define PRID_IMP_BCM3303       0x9100
9696 +#define        PRID_IMP_BCM3303        0x9100
9697  
9698  #define PRID_IMP_UNKNOWN       0xff00
9699  
9700 +#define       BCM330X(id) \
9701 +       (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \
9702 +       || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303)))
9703 +
9704  /*
9705   * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
9706   */
9707 @@ -139,7 +151,7 @@
9708         CPU_TX3912, CPU_TX3922, CPU_TX3927, CPU_AU1000, CPU_4KEC, CPU_4KSC,
9709         CPU_VR41XX, CPU_R5500, CPU_TX49XX, CPU_TX39XX, CPU_AU1500, CPU_20KC,
9710         CPU_VR4111, CPU_VR4121, CPU_VR4122, CPU_VR4131, CPU_VR4181, CPU_VR4181A,
9711 -       CPU_AU1100, CPU_LAST
9712 +       CPU_AU1100, CPU_BCM4710, CPU_BCM3302, CPU_LAST
9713  };
9714  
9715  #endif /* !__ASSEMBLY__ */
9716 --- linux-2.4.20/include/asm-mips/mips32_cache.h~2.4.20_broadcom_3_37_2_1109_US.patch   2005-01-07 05:39:02.000000000 -0500
9717 +++ linux-2.4.20/include/asm-mips/mips32_cache.h        2005-01-07 05:39:02.000000000 -0500
9718 @@ -325,4 +325,17 @@
9719         }
9720  }
9721  
9722 +extern inline void fill_icache_line(unsigned long addr)
9723 +{
9724 +       __asm__ __volatile__(
9725 +               ".set noreorder\n\t"
9726 +               ".set mips3\n\t"
9727 +               "cache %1, (%0)\n\t"
9728 +               ".set mips0\n\t"
9729 +               ".set reorder"
9730 +               :
9731 +               : "r" (addr),
9732 +               "i" (Fill));
9733 +}
9734 +
9735  #endif /* !(_MIPS_R4KCACHE_H) */
9736 --- linux-2.4.20/include/asm-mips/mipsregs.h~2.4.20_broadcom_3_37_2_1109_US.patch       2005-01-07 05:39:02.000000000 -0500
9737 +++ linux-2.4.20/include/asm-mips/mipsregs.h    2005-01-07 05:39:44.000000000 -0500
9738 @@ -400,13 +400,75 @@
9739  #define TX49_CONF_HALT         (_ULCAST_(1) << 18)
9740  #define TX49_CONF_CWFON                (_ULCAST_(1) << 27)
9741  
9742 -/*
9743 - * R10000 performance counter definitions.
9744 - *
9745 - * FIXME: The R10000 performance counter opens a nice way to implement CPU
9746 - *        time accounting with a precission of one cycle.  I don't have
9747 - *        R10000 silicon but just a manual, so ...
9748 - */
9749 +/* mips32/64 definitions for CP0 config register */
9750 +#define        CONF_MT_MASK                    0x00000380              /* MMU Type */
9751 +#define        CONF_MT_NONE                    0x00000000              /* No mmu */
9752 +#define        CONF_MT_TLB                     0x00000080              /* TLB present */
9753 +#define        CONF_MT_BAT                     0x00000100              /* Block address translation */
9754 +#define        CONF_MT_FM                      0x00000180              /* Fixed map (Like 4Kp/4Km) */
9755 +#define        CONF_AR_MASK                    0x00001c00              /* Architecture revision */
9756 +#define        CONF_AT_MASK                    0x00006000              /* Architecture type */
9757 +#define        CONF_AT_M32                     0x00000000              /* mips32 */
9758 +#define        CONF_AT_M6432                   0x00002000              /* mips64/mips32?? */
9759 +#define        CONF_AT_M64                     0x00004000              /* mips64 */
9760 +#define        CONF_BE                         0x00008000              /* BigEndian */
9761 +#define        CONF_BM                         0x00010000              /* Burst Mode */
9762 +#define        CONF_BM_SEQ                     0x00000000              /* Sequential */
9763 +#define        CONF_BM_SB                      0x00010000              /* SubBlock */
9764 +#define        CONF_MM_MASK                    0x00060000              /* Merge Mode */
9765 +#define        CONF_MM_NONE                    0x00000000              /* No merging */
9766 +#define        CONF_MM_SYSAD                   0x00020000              /* SysAD merging */
9767 +#define        CONF_MM_FULL                    0x00040000              /* Full merging */
9768 +#define        CONF_MDU                        0x00100000              /* Slow MDU */
9769 +#define        CONF_KU_MASK                    0x0e000000              /* Kuseg and useg cacheability (for MT=FM) */
9770 +#define        CONF_K23_MASK                   0x70000000              /* Kseg2 and Kseg3 cacheability (for MT=FM) */
9771 +#define        CONF_M                          0x80000000              /* config1 register present */
9772 +
9773 +/* mips32/64 definitions for CP0 config1 register */
9774 +#define CONF1_FP                       0x00000001              /* FPU present */
9775 +#define CONF1_EP                       0x00000002              /* EJTAG present */
9776 +#define CONF1_CA                       0x00000004              /* Code compression (mips16) implemented */
9777 +#define CONF1_WR                       0x00000008              /* Watch registers present */
9778 +#define CONF1_PC                       0x00000010              /* Performance counters present */
9779 +#define        CONF1_DA_SHIFT                  7                       /* Data cache associativity */
9780 +#define CONF1_DA_MASK                  0x00000380
9781 +#define CONF1_DA_BASE                  1
9782 +#define CONF1_DA_DM                    0x00000000              /*      Direct mapped */
9783 +#define CONF1_DA_2W                    0x00000080              /*      2-way */
9784 +#define CONF1_DA_3W                    0x00000100              /*      3-way */
9785 +#define CONF1_DA_4W                    0x00000180              /*      4-way */
9786 +#define CONF1_DL_SHIFT                 10                      /* Data cache line size */
9787 +#define CONF1_DL_MASK                  0x00001c00
9788 +#define CONF1_DL_BASE                  2
9789 +#define CONF1_DL_NONE                  0x00000000              /*      No data cache present */
9790 +#define CONF1_DL_16                    0x00000c00              /*      16 bytes */
9791 +#define CONF1_DS_SHIFT                 13                      /* Data cache sets/way */
9792 +#define CONF1_DS_MASK                  0x0000e000
9793 +#define CONF1_DS_BASE                  64
9794 +#define CONF1_DS_64                    0x00000000              /*      64 sets */
9795 +#define CONF1_DS_128                   0x00002000              /*      128 sets */
9796 +#define CONF1_DS_256                   0x00004000              /*      256 sets */
9797 +#define CONF1_IA_SHIFT                 16                      /* Instruction cache associativity */
9798 +#define CONF1_IA_MASK                  0x00070000
9799 +#define CONF1_IA_BASE                  1
9800 +#define CONF1_IA_DM                    0x00000000              /*      Direct mapped */
9801 +#define CONF1_IA_2W                    0x00010000              /*      2-way */
9802 +#define CONF1_IA_3W                    0x00020000              /*      3-way */
9803 +#define CONF1_IA_4W                    0x00030000              /*      4-way */
9804 +#define CONF1_IL_SHIFT                 19                      /* Instruction cache line size */
9805 +#define CONF1_IL_MASK                  0x00380000
9806 +#define CONF1_IL_BASE                  2
9807 +#define CONF1_IL_NONE                  0x00000000              /*      No data cache present */
9808 +#define CONF1_IL_16                    0x00180000              /*      16 bytes */
9809 +#define CONF1_IS_SHIFT                 22                      /* Instruction cache sets/way */
9810 +#define CONF1_IS_MASK                  0x01c00000
9811 +#define CONF1_IS_BASE                  64
9812 +#define CONF1_IS_64                    0x00000000              /*      64 sets */
9813 +#define CONF1_IS_128                   0x00400000              /*      128 sets */
9814 +#define CONF1_IS_256                   0x00800000              /*      256 sets */
9815 +#define CONF1_MS_MASK                  0x7e000000              /* Number of tlb entries */
9816 +#define CONF1_MS_SHIFT                 25
9817 +
9818  
9819  /*
9820   * Events counted by counter #0
9821 @@ -727,6 +789,20 @@
9822  #define read_c0_framemask()    __read_32bit_c0_register($21, 0)
9823  #define write_c0_framemask(val)        __write_32bit_c0_register($21, 0, val)
9824  
9825 +#define read_c0_diag()         __read_32bit_c0_register($22, 0)
9826 +#define read_c0_diag1()                __read_32bit_c0_register($22, 1)
9827 +#define read_c0_diag2()                __read_32bit_c0_register($22, 2)
9828 +#define read_c0_diag3()                __read_32bit_c0_register($22, 3)
9829 +#define read_c0_diag4()                __read_32bit_c0_register($22, 4)
9830 +#define read_c0_diag5()                __read_32bit_c0_register($22, 5)
9831 +
9832 +#define write_c0_diag(val)     __write_32bit_c0_register($22, 0, val)
9833 +#define write_c0_diag1(val)    __write_32bit_c0_register($22, 1, val)
9834 +#define write_c0_diag2(val)    __write_32bit_c0_register($22, 2, val)
9835 +#define write_c0_diag3(val)    __write_32bit_c0_register($22, 3, val)
9836 +#define write_c0_diag4(val)    __write_32bit_c0_register($22, 4, val)
9837 +#define write_c0_diag5(val)    __write_32bit_c0_register($22, 5, val)
9838 +
9839  #define read_c0_debug()                __read_32bit_c0_register($23, 0)
9840  #define write_c0_debug(val)    __write_32bit_c0_register($23, 0, val)
9841  
9842 @@ -844,6 +920,14 @@
9843  __BUILD_SET_C0(cause,CP0_CAUSE)
9844  __BUILD_SET_C0(config,CP0_CONFIG)
9845  
9846 +/*
9847 + * Functions to access the performance counter and control registers
9848 + */
9849 +extern asmlinkage unsigned int read_perf_cntr(unsigned int counter);
9850 +extern asmlinkage void write_perf_cntr(unsigned int counter, unsigned int val);
9851 +extern asmlinkage unsigned int read_perf_cntl(unsigned int counter);
9852 +extern asmlinkage void write_perf_cntl(unsigned int counter, unsigned int val);
9853 +
9854  #endif /* !__ASSEMBLY__ */
9855  
9856  #endif /* _ASM_MIPSREGS_H */
9857 --- linux-2.4.20/include/asm-mips/pci.h~2.4.20_broadcom_3_37_2_1109_US.patch    2005-01-07 05:39:02.000000000 -0500
9858 +++ linux-2.4.20/include/asm-mips/pci.h 2005-01-08 12:15:03.133507680 -0500
9859 @@ -117,12 +117,7 @@
9860         if (direction == PCI_DMA_NONE)
9861                 out_of_line_bug();
9862  
9863 -       if (direction != PCI_DMA_TODEVICE) {
9864 -               unsigned long addr;
9865 -
9866 -               addr = baddr_to_bus(hwdev->bus, dma_addr) + PAGE_OFFSET;
9867 -               dma_cache_wback_inv(addr, size);
9868 -       }
9869 +       /* Nothing to do */
9870  }
9871  
9872  /*
9873 @@ -203,8 +198,7 @@
9874                 } else {
9875                         sg->dma_address = page_to_bus(sg->page) +
9876                                           sg->offset;
9877 -                       dma_cache_wback_inv((unsigned long)
9878 -                               (page_address(sg->page) + sg->offset),
9879 +                       dma_cache_wback_inv((unsigned long)page_address(sg->page) + sg->offset,
9880                                 sg->length);
9881                 }
9882         }
9883 --- linux-2.4.20/include/asm-mips/serial.h~2.4.20_broadcom_3_37_2_1109_US.patch 2005-01-07 05:39:02.000000000 -0500
9884 +++ linux-2.4.20/include/asm-mips/serial.h      2005-01-08 12:15:06.999919896 -0500
9885 @@ -181,6 +181,13 @@
9886  #define TXX927_SERIAL_PORT_DEFNS
9887  #endif
9888  
9889 +#ifdef CONFIG_BCM947XX
9890 +/* reserve 4 ports to be configured at runtime */
9891 +#define BCM947XX_SERIAL_PORT_DEFNS { 0, }, { 0, }, { 0, }, { 0, },
9892 +#else
9893 +#define BCM947XX_SERIAL_PORT_DEFNS
9894 +#endif
9895 +
9896  #ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT
9897  #define STD_SERIAL_PORT_DEFNS                  \
9898         /* UART CLK   PORT IRQ     FLAGS        */                      \
9899 @@ -313,6 +320,7 @@
9900  #endif
9901  
9902  #define SERIAL_PORT_DFNS                       \
9903 +       BCM947XX_SERIAL_PORT_DEFNS              \
9904         IVR_SERIAL_PORT_DEFNS                   \
9905         ITE_SERIAL_PORT_DEFNS                   \
9906         ATLAS_SERIAL_PORT_DEFNS                 \
9907 --- linux-2.4.20/include/asm-mips/stackframe.h~2.4.20_broadcom_3_37_2_1109_US.patch     2005-01-07 05:38:15.000000000 -0500
9908 +++ linux-2.4.20/include/asm-mips/stackframe.h  2005-01-08 12:15:32.798997840 -0500
9909 @@ -201,12 +201,25 @@
9910                 lw      $3,  PT_R3(sp);                  \
9911                 lw      $2,  PT_R2(sp)
9912  
9913 +#ifdef CONFIG_BCM4710
9914 +
9915  #define RESTORE_SP_AND_RET                               \
9916                 lw      sp,  PT_R29(sp);                 \
9917                 .set    mips3;                           \
9918 +               nop;                                     \
9919 +               nop;                                     \
9920                 eret;                                    \
9921                 .set    mips0
9922  
9923 +#else
9924 +
9925 +#define RESTORE_SP_AND_RET                               \
9926 +               lw      sp,  PT_R29(sp);                 \
9927 +               .set    mips3;                           \
9928 +               eret;                                    \
9929 +               .set    mips0
9930 +#endif
9931 +
9932  #endif
9933  
9934  #define RESTORE_SP                                       \
9935 --- linux-2.4.20/include/asm-mips/system.h~2.4.20_broadcom_3_37_2_1109_US.patch 2005-01-07 05:39:02.000000000 -0500
9936 +++ linux-2.4.20/include/asm-mips/system.h      2005-01-08 12:15:03.002527592 -0500
9937 @@ -16,6 +16,8 @@
9938  #ifndef _ASM_SYSTEM_H
9939  #define _ASM_SYSTEM_H
9940  
9941 +#ifdef __KERNEL__
9942 +
9943  #include <linux/config.h>
9944  #include <asm/sgidefs.h>
9945  
9946 @@ -316,4 +318,6 @@
9947  #define die_if_kernel(msg, regs)                                       \
9948         __die_if_kernel(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__)
9949  
9950 +#endif /* __KERNEL__ */
9951 +
9952  #endif /* _ASM_SYSTEM_H */
9953 --- linux-2.4.20/init/do_mounts.c~2.4.20_broadcom_3_37_2_1109_US.patch  2005-01-07 05:38:15.000000000 -0500
9954 +++ linux-2.4.20/init/do_mounts.c       2005-01-08 12:16:21.913531296 -0500
9955 @@ -238,7 +238,16 @@
9956         { "ftlb", 0x2c08 },
9957         { "ftlc", 0x2c10 },
9958         { "ftld", 0x2c18 },
9959 +#if defined(CONFIG_MTD_BLOCK) || defined(CONFIG_MTD_BLOCK_RO)
9960         { "mtdblock", 0x1f00 },
9961 +        { "mtdblock0",0x1f00 },
9962 +        { "mtdblock1",0x1f01 },
9963 +        { "mtdblock2",0x1f02 },
9964 +        { "mtdblock3",0x1f03 },
9965 +#endif
9966 +#ifdef CONFIG_BLK_DEV_DUMMY
9967 +       { "dummy",0x2000 },
9968 +#endif
9969         { NULL, 0 }
9970  };
9971  
9972 @@ -468,6 +477,7 @@
9973         struct minix_super_block *minixsb;
9974         struct ext2_super_block *ext2sb;
9975         struct romfs_super_block *romfsb;
9976 +       struct cramfs_super *cramfsb;
9977         int nblocks = -1;
9978         unsigned char *buf;
9979  
9980 @@ -478,6 +488,7 @@
9981         minixsb = (struct minix_super_block *) buf;
9982         ext2sb = (struct ext2_super_block *) buf;
9983         romfsb = (struct romfs_super_block *) buf;
9984 +       cramfsb = (struct cramfs_super *) buf;
9985         memset(buf, 0xe5, size);
9986  
9987         /*
9988 @@ -497,6 +508,13 @@
9989                 goto done;
9990         }
9991  
9992 +#ifdef CONFIG_BLK_DEV_INITRD
9993 +       /*
9994 +        * Fallback if size cannot be determined by superblock
9995 +        */
9996 +       nblocks = (initrd_end-initrd_start+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
9997 +#endif
9998 +
9999         /* romfs is at block zero too */
10000         if (romfsb->word0 == ROMSB_WORD0 &&
10001             romfsb->word1 == ROMSB_WORD1) {
10002 @@ -507,6 +525,16 @@
10003                 goto done;
10004         }
10005  
10006 +       /* so is cramfs */
10007 +       if (cramfsb->magic == CRAMFS_MAGIC) {
10008 +               printk(KERN_NOTICE
10009 +                       "RAMDISK: cramfs filesystem found at block %d\n",
10010 +                       start_block);
10011 +               if (cramfsb->flags & CRAMFS_FLAG_FSID_VERSION_2)
10012 +                       nblocks = (cramfsb->size+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
10013 +               goto done;
10014 +       }
10015 +
10016         /*
10017          * Read block 1 to test for minix and ext2 superblock
10018          */
10019 @@ -535,6 +563,7 @@
10020         printk(KERN_NOTICE
10021                "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
10022                start_block);
10023 +       nblocks = -1;
10024         
10025  done:
10026         lseek(fd, start_block * BLOCK_SIZE, 0);
10027 @@ -757,6 +786,17 @@
10028                         change_floppy("root floppy");
10029         }
10030  #endif
10031 +#if defined(CONFIG_MTD_BLOCK) || defined(CONFIG_MTD_BLOCK_RO)
10032 +       if (MAJOR(ROOT_DEV) == 31) {
10033 +               /* rd_doload is for a ramload setup */
10034 +               if (rd_doload) {
10035 +                       if (rd_load_disk(0)) {
10036 +                               ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
10037 +                               create_dev("/dev/root", ROOT_DEV, NULL);
10038 +                       }
10039 +               }
10040 +       }
10041 +#endif
10042         mount_block_root("/dev/root", root_mountflags);
10043  }
10044  
10045 --- linux-2.4.20/init/main.c~2.4.20_broadcom_3_37_2_1109_US.patch       2005-01-07 05:39:02.000000000 -0500
10046 +++ linux-2.4.20/init/main.c    2005-01-07 05:39:02.000000000 -0500
10047 @@ -554,6 +554,13 @@
10048         free_initmem();
10049         unlock_kernel();
10050  
10051 +#ifdef CONFIG_NOROOT
10052 +       for (;;) {
10053 +               DECLARE_WAIT_QUEUE_HEAD(wait);
10054 +               sleep_on(&wait);
10055 +       }
10056 +#endif
10057 +
10058         if (open("/dev/console", O_RDWR, 0) < 0)
10059                 printk("Warning: unable to open an initial console.\n");
10060  
10061 --- linux-2.4.20/net/bridge/br_device.c~2.4.20_broadcom_3_37_2_1109_US.patch    2005-01-07 05:38:15.000000000 -0500
10062 +++ linux-2.4.20/net/bridge/br_device.c 2005-01-07 05:39:02.000000000 -0500
10063 @@ -121,6 +121,25 @@
10064         return -1;
10065  }
10066  
10067 +extern void br_stp_change_bridge_id(struct net_bridge *br, unsigned char *addr);
10068 +
10069 +static int
10070 +br_set_mac_address(struct net_device *dev, void *addr)
10071 +{
10072 +       struct net_bridge *br = dev->priv;
10073 +       struct sockaddr *sa = (struct sockaddr *) addr;
10074 +       
10075 +       write_lock_bh(&br->lock);
10076 +
10077 +       memcpy(br->preferred_id.addr, sa->sa_data, ETH_ALEN);
10078 +
10079 +       br_stp_recalculate_bridge_id(br);
10080 +
10081 +       write_unlock_bh(&br->lock);
10082 +
10083 +       return 0;
10084 +}
10085 +
10086  void br_dev_setup(struct net_device *dev)
10087  {
10088         memset(dev->dev_addr, 0, ETH_ALEN);
10089 @@ -133,5 +152,5 @@
10090         dev->stop = br_dev_stop;
10091         dev->accept_fastpath = br_dev_accept_fastpath;
10092         dev->tx_queue_len = 0;
10093 -       dev->set_mac_address = NULL;
10094 +       dev->set_mac_address = br_set_mac_address;
10095  }
10096 --- linux-2.4.20/net/bridge/br_fdb.c~2.4.20_broadcom_3_37_2_1109_US.patch       2005-01-07 05:38:15.000000000 -0500
10097 +++ linux-2.4.20/net/bridge/br_fdb.c    2005-01-07 05:39:02.000000000 -0500
10098 @@ -290,10 +290,10 @@
10099         hash = br_mac_hash(addr);
10100  
10101         write_lock_bh(&br->hash_lock);
10102 +       if (!is_local) {
10103         fdb = br->hash[hash];
10104         while (fdb != NULL) {
10105 -               if (!fdb->is_local &&
10106 -                   !memcmp(fdb->addr.addr, addr, ETH_ALEN)) {
10107 +                       if (!memcmp(fdb->addr.addr, addr, ETH_ALEN)) {
10108                         __fdb_possibly_replace(fdb, source, is_local);
10109                         write_unlock_bh(&br->hash_lock);
10110                         return;
10111 @@ -301,6 +301,7 @@
10112  
10113                 fdb = fdb->next_hash;
10114         }
10115 +       }
10116  
10117         fdb = kmalloc(sizeof(*fdb), GFP_ATOMIC);
10118         if (fdb == NULL) {
10119 --- linux-2.4.20/net/bridge/br_private.h~2.4.20_broadcom_3_37_2_1109_US.patch   2005-01-07 05:38:15.000000000 -0500
10120 +++ linux-2.4.20/net/bridge/br_private.h        2005-01-08 12:16:21.367614288 -0500
10121 @@ -96,6 +96,7 @@
10122         int                             hello_time;
10123         int                             forward_delay;
10124         bridge_id                       bridge_id;
10125 +       bridge_id                       preferred_id;
10126         int                             bridge_max_age;
10127         int                             bridge_hello_time;
10128         int                             bridge_forward_delay;
10129 --- linux-2.4.20/net/bridge/br_stp_if.c~2.4.20_broadcom_3_37_2_1109_US.patch    2005-01-07 05:38:15.000000000 -0500
10130 +++ linux-2.4.20/net/bridge/br_stp_if.c 2005-01-07 05:39:02.000000000 -0500
10131 @@ -162,6 +162,12 @@
10132  
10133         p = br->port_list;
10134         while (p != NULL) {
10135 +               /* match against preferred address first */
10136 +               if (memcmp(p->dev->dev_addr, br->preferred_id.addr, ETH_ALEN) == 0) {
10137 +                       addr = p->dev->dev_addr;
10138 +                       break;
10139 +               }
10140 +
10141                 if (addr == br_mac_zero ||
10142                     memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0)
10143                         addr = p->dev->dev_addr;
10144 --- linux-2.4.20/net/core/Makefile~2.4.20_broadcom_3_37_2_1109_US.patch 2005-01-07 05:38:15.000000000 -0500
10145 +++ linux-2.4.20/net/core/Makefile      2005-01-08 12:16:20.333771456 -0500
10146 @@ -7,6 +7,8 @@
10147  #
10148  # Note 2! The CFLAGS definition is now in the main makefile...
10149  
10150 +SRCBASE        := $(TOPDIR)/../..
10151 +EXTRA_CFLAGS   += -Wall -I$(SRCBASE)/
10152  O_TARGET := core.o
10153  
10154  export-objs := netfilter.o profile.o
10155 --- linux-2.4.20/net/core/dev.c~2.4.20_broadcom_3_37_2_1109_US.patch    2005-01-07 05:38:15.000000000 -0500
10156 +++ linux-2.4.20/net/core/dev.c 2005-01-08 12:16:21.372613528 -0500
10157 @@ -1245,6 +1245,19 @@
10158         local_irq_save(flags);
10159  
10160         netdev_rx_stat[this_cpu].total++;
10161 +
10162 +#if defined(CONFIG_BCM4710) && defined(CONFIG_BRIDGE) 
10163 +       /* Optimisation for framebursting (allow interleaving of pkts by
10164 +               immediately processing the rx pkt instead of Qing the pkt and deferring
10165 +               the processing). Only optimise for bridging and guard against non
10166 +               TASKLET based netif_rx calls.
10167 +               */
10168 +       if (!in_irq() && skb->dev->br_port != NULL && br_handle_frame_hook != NULL){
10169 +               local_irq_restore(flags);
10170 +               return(netif_receive_skb(skb));
10171 +       }
10172 +#endif   
10173 +
10174         if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
10175                 if (queue->input_pkt_queue.qlen) {
10176                         if (queue->throttle)
10177 @@ -2005,6 +2018,7 @@
10178  {
10179         struct net_device *dev;
10180         int err;
10181 +       struct net_device_stats *stats;
10182  
10183         if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL)
10184                 return -ENODEV;
10185 @@ -2119,6 +2133,16 @@
10186                         ifr->ifr_ifindex = dev->ifindex;
10187                         return 0;
10188  
10189 +#ifdef PERFORMANCE_SUPPORT                     
10190 +               case SIOCGIFSTATS:
10191 +                       if (!dev->get_stats || !(stats = dev->get_stats(dev)))
10192 +                               return -ENODEV;
10193 +                       if (copy_to_user(ifr->ifr_data, stats, 
10194 +                           sizeof(struct net_device_stats)))
10195 +                               return -EFAULT;
10196 +                       return 0;
10197 +#endif
10198 +                       
10199                 case SIOCGIFTXQLEN:
10200                         ifr->ifr_qlen = dev->tx_queue_len;
10201                         return 0;
10202 --- linux-2.4.20/net/netsyms.c~2.4.20_broadcom_3_37_2_1109_US.patch     2005-01-07 05:38:15.000000000 -0500
10203 +++ linux-2.4.20/net/netsyms.c  2005-01-08 12:16:21.745556832 -0500
10204 @@ -435,20 +435,12 @@
10205  EXPORT_SYMBOL(neigh_add);
10206  EXPORT_SYMBOL(neigh_dump_info);
10207  
10208 -EXPORT_SYMBOL(dev_set_allmulti);
10209 -EXPORT_SYMBOL(dev_set_promiscuity);
10210 -EXPORT_SYMBOL(sklist_remove_socket);
10211 -EXPORT_SYMBOL(rtnl_sem);
10212 -EXPORT_SYMBOL(rtnl_lock);
10213 -EXPORT_SYMBOL(rtnl_unlock);
10214 -
10215  /* ABI emulation layers need this */
10216  EXPORT_SYMBOL(move_addr_to_kernel);
10217  EXPORT_SYMBOL(move_addr_to_user);
10218                    
10219  /* Used by at least ipip.c.  */
10220  EXPORT_SYMBOL(ipv4_config);
10221 -EXPORT_SYMBOL(dev_open);
10222  
10223  /* Used by other modules */
10224  EXPORT_SYMBOL(xrlim_allow);
10225 @@ -460,6 +452,14 @@
10226  
10227  #endif  /* CONFIG_INET */
10228  
10229 +EXPORT_SYMBOL(dev_open);
10230 +EXPORT_SYMBOL(dev_set_allmulti);
10231 +EXPORT_SYMBOL(dev_set_promiscuity);
10232 +EXPORT_SYMBOL(sklist_remove_socket);
10233 +EXPORT_SYMBOL(rtnl_sem);
10234 +EXPORT_SYMBOL(rtnl_lock);
10235 +EXPORT_SYMBOL(rtnl_unlock);
10236 +
10237  #ifdef CONFIG_TR
10238  EXPORT_SYMBOL(tr_type_trans);
10239  #endif